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:免密登录 + 远程关机
- 生成密钥(在 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
复制输出的整行公钥内容- Windows 创建用户 hauser
创建一个本地账户 hauser,yourpassword 换成你想设置的密码
net user hauser yourpassword /add
加入管理员组(必要,否则无法执行关机命令)
net localgroup administrators hauser /add- Windows 登录界面退出当前管理员账户,切换登录到你刚刚创建的 hauser 用户(密码就是你之前设置的)
- 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- Home Assistant 容器里测试免密
docker exec -it homeassistant bash
ssh -o StrictHostKeyChecking=accept-new hauser@<你的Windows_IP> "whoami"三、Home Assistant 设置
- 编辑你的
/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"- 设备与集成里安装Ping (ICMP),增加一个 ping 主机(判断是否已关机)
重启 HA 后,会得到实体:binary_sensor.10_10_10_26(设备里查询),on = 在线 off = 离线(关机或断网)。
- 脚本(含重试逻辑)
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/网络连接。"- 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 并自动重试吗?"








