求助:修改PowerShell脚本以实现Windows 11按需休眠控制
求助:修改PowerShell脚本以实现Windows 11按需休眠控制
兄弟我太懂你这需求的痛点了——既要在外连接自己托管的服务时让电脑保持清醒,平时又能乖乖按30分钟的设定休眠,结果脚本写出来反而搞砸了,连正常休眠都不行,这闹心程度拉满对吧?
你排查到是加载客户端IP的文件处理部分在阻止休眠,这个判断大概率是对的。Windows的休眠判定机制很“敏感”,如果脚本一直占用文件句柄、或者持续有后台操作被系统误判为“用户活动”,它就会觉得你还在干活,不肯进入休眠。咱们一步步来改:
第一步:彻底解决文件读取的资源占用问题
问题大概率出在你的脚本一直保持文件打开状态,或者读取方式不对导致文件句柄没释放。咱们改成一次性读取+立即释放的方式:
# 一次性读入IP文件,自动释放文件句柄,同时过滤有效IP $clientIPs = Get-Content -Path "C:\Your\Path\To\IPs.txt" -Raw | Split-String -Pattern "`r`n|`n" | Where-Object { $_ -match '\d+\.\d+\.\d+\.\d+' }
用Get-Content -Raw一次性把整个文件读进内存,然后分割成单独的IP,再用正则过滤掉无效行,这样文件只会被打开一瞬间,读完就自动关闭句柄,不会一直占着资源。
第二步:调整脚本的循环逻辑,别让系统误以为有持续活动
如果你的脚本是一直在后台高频循环运行,系统会把这种循环当成持续操作。咱们改得“佛系”一点:
- 给检查逻辑加合理的间隔,比如每5分钟检查一次,而且两次检查之间让脚本进入系统级休眠——用
Start-Sleep -Seconds 300,这个休眠不会被系统判定为用户活动,完全不影响电脑的休眠计划。 - ping操作也要“点到为止”,不要持续ping,每次检查只ping每个IP1次,超时设短一点:
# 初始化连接标记 $connected = $false foreach ($ip in $clientIPs) { # 只ping1次,超时1秒,避免持续占用资源 $pingResult = Test-Connection -ComputerName $ip -Count 1 -TimeoutSeconds 1 -Quiet if ($pingResult) { $connected = $true break # 只要检测到一个在线IP就停止检查,提高效率 } } # 根据连接状态调整休眠时间 if ($connected) { # 连接状态:禁用自动休眠 powercfg -change -standby-timeout-ac 0 powercfg -change -standby-timeout-dc 0 } else { # 无连接:恢复30分钟休眠(1800秒) powercfg -change -standby-timeout-ac 1800 powercfg -change -standby-timeout-dc 1800 } # 等待5分钟再进行下一次检查 Start-Sleep -Seconds 300
第三步:让脚本在后台“安静”运行,别暴露在前台
不要一直开着PowerShell窗口运行脚本,用任务计划程序来托管:
- 创建新任务,触发器设为“用户登录时”或者“系统启动时”,勾选“不管用户是否登录都运行”。
- 操作选项里选择启动PowerShell脚本,参数填
-NoProfile -WindowStyle Hidden -File "C:\Your\Path\To\Script.ps1",这样脚本会在后台静默运行,不会有窗口,也不会被系统当成前台用户活动。 - 任务的“条件”选项卡,取消勾选“唤醒计算机运行此任务”,避免脚本乱唤醒电脑。
最后:验证基础休眠功能
改完先别急着启动脚本,先手动设置30分钟休眠,等电脑正常进入休眠一次,确认基础的休眠机制没问题,再启动脚本测试:连接服务时电脑保持清醒,断开后等30分钟看是否正常休眠。
备注:内容来源于stack exchange,提问作者user26895192




