You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell空闲计时自动重启脚本运行即重启问题排查

故障根因

脚本运行即重启是3个代码错误共同导致的:

  • 阈值变量未定义:判断重启条件的$logout(你设定的30分钟阈值)在全脚本中没有赋值,PowerShell对未初始化的变量默认返回$null,数值比较时$null会被转换为0,因此$test -ge $logout等价于判断「空闲时长≥0分钟」,条件永远成立,运行即触发重启。
  • WMI查询参数写法错误:获取当前用户的Get-WmiObject命令把参数名-ComputerName误写为参数值,本地运行时虽偶尔能返回结果,但属于无效语法,跨环境运行大概率取空值。
  • 事件日志源未预创建:写应用日志时调用的Script事件源默认不存在,直接调用会抛出非终止错误,影响日志记录。
修复后可直接运行的代码
Function Get-IdleTime 
{
Add-Type @'
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PInvoke.Win32 
    {

    public static class UserInput 
        {

        [DllImport("user32.dll", SetLastError=false)]
        private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

        [StructLayout(LayoutKind.Sequential)]
        private struct LASTINPUTINFO {
            public uint cbSize;
            public int dwTime;
        }

        public static DateTime LastInput {
            get {
                DateTime bootTime = DateTime.Now.AddMilliseconds(-Environment.TickCount);
                DateTime lastInput = bootTime.AddMilliseconds(LastInputTicks);
                return lastInput;
            }
        }

        public static TimeSpan IdleTime {
            get {
                return DateTime.Now.Subtract(LastInput);
            }
        }

        public static int LastInputTicks {
            get {
                LASTINPUTINFO lii = new LASTINPUTINFO();
                lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
                GetLastInputInfo(ref lii);
                return lii.dwTime;
            }
        }
    }
}
'@
    $Output = @{
        'LastInput' = [PInvoke.Win32.UserInput]::LastInput;
        'IdleTime'  = [PInvoke.Win32.UserInput]::IdleTime
    }
    New-Object -TypeName PSObject -Property $Output
}

Function AutomaticReboot {
    # 定义30分钟空闲阈值
    $logout = 30

    # 初始化事件日志源
    if (-not [System.Diagnostics.EventLog]::SourceExists("Script")) {
        New-EventLog -LogName Application -Source "Script"
    }

    $idle = Get-IdleTime
    $test = [Math]::Round($idle.IdleTime.TotalMinutes,3)

    # 替换废弃的Get-WmiObject命令,修正参数写法
    $CurrentUser = Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -ExpandProperty UserName

    If($test -ge $logout){
        $msg = "Autologout scheduled task triggered for $CurrentUser with an idle time of $test minutes."
        Write-EventLog -LogName Application -Source Script -EventID 1 -EntryType Information -Message $msg
        # 测试阶段可注释下面这行,避免误重启
        Restart-Computer
    }
    Else{
        $msg = "Autologout script ran for $CurrentUser but idle time of $logout was not met. Idle time at run was $test minutes."
        Write-EventLog -LogName Application -Source Script -EventID 2 -EntryType Information -Message $msg
    }
}

# 调用函数执行检测
AutomaticReboot
部署注意事项
  • 不要用SYSTEM等系统账户通过计划任务运行该脚本,必须配置为「仅当用户登录时运行」,在当前登录用户的上下文下执行,否则GetLastInputInfo无法正确读取用户输入,空闲时间计算会出错。
  • 首次运行建议先注释Restart-Computer行,执行后查看应用日志里的空闲时间记录,确认数值符合实际情况后再放开重启逻辑,避免误重启。
  • 创建事件日志源需要管理员权限,首次执行请用管理员身份打开PowerShell运行一次,后续普通权限即可正常写日志。

内容的提问来源于stack exchange,提问作者Damen Priddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:46:04