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

使用System.Management.Automation远程重启计算机的正确方法咨询

System.Management.Automation 远程重启设备实现规范

包引用规范

最新版本的System.Management.Automation属于PowerShell 7+ SDK的一部分,不要单独安装零散的System.Management.Automation NuGet包,正确的依赖安装方式是直接引用Microsoft.PowerShell.SDK包,避免依赖冲突导致的Runspace异常。

前置环境要求

目标设备需要提前完成WinRM配置:

  • 开启WinRM服务
  • 放通防火墙5985(HTTP)/5986(HTTPS)端口
  • 配置对应账号的远程PowerShell访问权限

Runspace生命周期管理规范

Runspace损坏属于预期正常行为:远程重启命令会直接销毁目标设备上的PowerShell会话,关联的本地Runspace会因为连接断开进入损坏状态,遵循以下规则即可避免问题:

  • 重启操作和后续存活检测完全分离Runspace实例,不要复用同一个Runspace
  • 所有Runspace、PowerShell实例都放入using代码块,操作完成后自动释放资源,不要手动管理生命周期
  • 不要尝试重新打开已经触发过重启命令的Runspace,直接销毁重建即可

完整实现示例

using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Security;

// 替换为实际的目标配置
string targetHost = "192.168.1.100";
string userName = "administrator";
string password = "你的密码";

// 构造凭据(不需要凭据可跳过此步)
SecureString securePwd = new SecureString();
foreach (char c in password) securePwd.AppendChar(c);
PSCredential credential = new PSCredential(userName, securePwd);

// 构造远程连接信息
WSManConnectionInfo connInfo = new WSManConnectionInfo(new Uri($"http://{targetHost}:5985/wsman"));
connInfo.Credential = credential;
connInfo.OperationTimeout = 10 * 1000; // 单次操作超时10秒

// ========== 第一步:单独用独立Runspace执行重启命令 ==========
using (Runspace restartRunspace = RunspaceFactory.CreateRunspace(connInfo))
{
    restartRunspace.Open();
    using (PowerShell ps = PowerShell.Create())
    {
        ps.Runspace = restartRunspace;
        ps.AddCommand("Restart-Computer")
          .AddParameter("Force", true) // 强制重启,跳过程序阻止
          .AddParameter("Timeout", 5); // 给系统5秒触发重启,不需要等完全关机
        ps.Invoke();
    }
} // 此处重启用的Runspace会自动释放,完全不需要保留

// ========== 第二步:轮询检测设备是否恢复 ==========
bool deviceOnline = false;
int maxRetryCount = 20; // 最多重试20次,合计5分钟超时,可自行调整
int retryCount = 0;

while (!deviceOnline && retryCount < maxRetryCount)
{
    retryCount++;
    Thread.Sleep(15000); // 每次检测间隔15秒,可自行调整

    try
    {
        // 每次检测都新建独立的Runspace
        using Runspace detectRunspace = RunspaceFactory.CreateRunspace(connInfo);
        detectRunspace.Open();
        using PowerShell detectPs = PowerShell.Create();
        detectPs.Runspace = detectRunspace;
        detectPs.AddScript("Get-ComputerInfo | Select-Object -ExpandProperty OsName");
        var result = detectPs.Invoke();
        
        // 调用成功且返回值正常即判定设备恢复
        if (result.Count > 0 && !result.Any(item => item == null))
        {
            deviceOnline = true;
        }
    }
    catch (PSRemotingTransportException)
    {
        // 传输异常说明设备还未启动完成,继续轮询即可
        continue;
    }
}

常见异常规避

  • 不要给Restart-Computer加-Wait参数等待重启完成,该参数的底层实现逻辑不稳定,容易触发Runspace死锁
  • 不要在同一个PowerShell实例里同时加入重启命令和检测命令,远程会话断开会直接导致整个实例进入损坏状态
  • 如果目标设备是工作组环境而非域环境,需要在本地WinRM配置中把目标IP加入信任列表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:36:08