Windows 系统中实现 Home Assistant(HA)远程关机 PC

0
54

SSH 方式 = “安全、直接、一次性命令执行”(最适合远程关机)

局域网环境 下,只要你的 Windows 主机 开机 + sshd 服务在运行 + IP 没变
SSH 基本不会断,也不会连不上。

通过 SSH 实现 Home Assistant 远程关机 Windows 系统 的完整步骤(适合 Docker 搭建的 HA,不安装额外 HASS.Agent 软件),Home Assistant 容器通过 SSH 登录你的 Windows 电脑,然后执行关机命令。

一、Windows 上安装 OpenSSH Server,启用 SSH 服务.

  • Windows 11系统

管理员身份打开 PowerShell

Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

  • 安装完成后,再启动并设置自启
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
  • 确认是否安装成功
Get-Service sshd
显示状态为 Running 即表示成功
  • 防火墙放行端口
New-NetFirewallRule -Name sshd -DisplayName "OpenSSH Server (Port 22)" -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
  • 确认端口 22 在监听
netstat -ano | findstr ":22"
# 或
Test-NetConnection -ComputerName localhost -Port 22

看到 TcpTestSucceeded : True 或 LISTENING 即正常

二、对接 Home Assistant:免密登录 + 远程关机

  1. 生成密钥(在 HA 容器内)
docker exec -it homeassistant bash
ssh-keygen -t rsa -b 4096 -C "homeassistant" -N "" -f /root/.ssh/id_rsa
cat /root/.ssh/id_rsa.pub
复制输出的整行公钥内容
  1. Windows 创建用户 hauser
创建一个本地账户 hauser,yourpassword 换成你想设置的密码
net user hauser yourpassword /add
加入管理员组(必要,否则无法执行关机命令)
net localgroup administrators hauser /add

  1. Windows 登录界面退出当前管理员账户,切换登录到你刚刚创建的 hauser 用户(密码就是你之前设置的)
  2. Windows 在 hauser 身份下,HA 公钥放到系统级文件,PowerShell管理身份运行
# 1) 新建文件administrators_authorized_keys
C:\ProgramData\ssh\administrators_authorized_keys

# 2) 打开 administrators_authorized_keys 以记事本方式,粘贴公钥确保整行
notepad "C:\ProgramData\ssh\administrators_authorized_keys"
注意:必须 一整行,ASCII/UTF-8(无 BOM)、没有多余换行

# 3) 设置权限(即便之前已有)
icacls "C:\ProgramData\ssh" /inheritance:r
icacls "C:\ProgramData\ssh" /grant:r "Administrators:(OI)(CI)(F)" "SYSTEM:(OI)(CI)(F)"
icacls "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r
icacls "C:\ProgramData\ssh\administrators_authorized_keys" /grant:r "Administrators:(F)" "SYSTEM:(F)"

# 4) 检查 sshd_config 确保启用公钥认证
Select-String -Path "C:\ProgramData\ssh\sshd_config" -Pattern "PubkeyAuthentication","PasswordAuthentication","Match Group administrators" | Format-Table LineNumber,Line

# 若发现 PasswordAuthentication no → OK;若是 yes 也 OK,先不用改。

# 5) 重启服务
Restart-Service sshd

完成后,本机测试一次(仍在 hauser 会话)

ssh localhost "whoami"
第一次会问 yes;能返回 desktop-... \ hauser 即 OK
  1. Home Assistant 容器里测试免密
docker exec -it homeassistant bash
ssh -o StrictHostKeyChecking=accept-new hauser@<你的Windows_IP> "whoami"

三、Home Assistant 设置

  1. 编辑你的 /config/configuration.yaml
    在底部添加以下配置(确保缩进对齐):
shell_command:
  shutdown_pc: >-
    ssh -o StrictHostKeyChecking=no hauser@10.10.10.26 "shutdown /s /t 0"
  restart_pc: >-
    ssh -o StrictHostKeyChecking=no hauser@10.10.10.26 "shutdown /r /t 0"
  1. 设备与集成里安装Ping (ICMP),增加一个 ping 主机(判断是否已关机)

重启 HA 后,会得到实体:binary_sensor.10_10_10_26(设备里查询),on = 在线 off = 离线(关机或断网)。

  1. 脚本(含重试逻辑)
  shutdown_windows_with_retry:
    alias: 关机 Windows(带重试)
    mode: single
    fields:
      max_attempts:
        description: 最大尝试次数
        example: 3
        default: 3
      wait_seconds:
        description: 每次尝试后等待离线的秒数
        example: 30
        default: 30
      between_retry_delay:
        description: 两次尝试之间的间隔秒数
        example: 5
        default: 5
    sequence:
      - variables:
          attempts: 0
          max: "{{ max_attempts | int }}"
          wait_s: "{{ wait_seconds | int }}"
          gap_s: "{{ between_retry_delay | int }}"
      - repeat:
          while:
            - condition: template
              value_template: "{{ repeat.index0 < max }}"
            - condition: state
              entity_id: binary_sensor.10_10_10_26
              state: "on"
          sequence:
            - variables:
                attempts: "{{ repeat.index }}"
            - service: shell_command.shutdown_pc
            - wait_for_trigger:
                - platform: state
                  entity_id: binary_sensor.10_10_10_26
                  to: "off"
              timeout:
                seconds: "{{ wait_s }}"
              continue_on_timeout: true
            - choose:
                # ✅ 成功:检测到离线
                - conditions:
                    - condition: state
                      entity_id: binary_sensor.10_10_10_26
                      state: "off"
                  sequence:
                    - service: persistent_notification.create
                      data:
                        title: "Windows 远程关机"
                        message: "✅ 已成功关机(第 {{ attempts }} 次尝试)。"
                    - stop: "Done"
                # ⚠️ 未离线:等待并重试
                - conditions: []
                  sequence:
                    - delay:
                        seconds: "{{ gap_s }}"
      # 🚫 循环结束仍在线:判定失败
      - choose:
          - conditions:
              - condition: state
                entity_id: binary_sensor.10_10_10_26
                state: "on"
            sequence:
              - service: persistent_notification.create
                data:
                  title: "Windows 远程关机"
                  message: "❌ 已重试 {{ max }} 次仍未关机,请检查 SSH/网络连接。"
  1. Lovelace 按钮(调用脚本)
    添加一个按钮(在你的仪表盘里):
type: button
name: 关机 Windows(带重试)
icon: mdi:power
tap_action:
  action: call-service
  service: script.shutdown_windows_with_retry
  data:
    max_attempts: 3
    wait_seconds: 30
    between_retry_delay: 5
  confirmation:
    text: "确定要关闭 Windows 并自动重试吗?"

发布回复

请输入评论!
请输入你的名字