Powershell: Restart-Computer 远程重启

Background: 维护的Win10机器太多,有时需要reboot,一台一台手工太慢。

Solution:

  (方法A) 利用Powershell的Restart-Computer 远程reboot 。这里根据协议又可以细分为默认DCOM和指定WSMan两种方法。这里只提DCOM的方法,WSMan与Powershell本身远程有密切关系,可以后面再探究。

  (方法B) 用Invoke-Command远程执行Restart-Computer

要求:机器都在一个网段内,能相互访问。

结论:方法A与B都可以远程reboot

必要条件:

Remote端机器的要求

1. 彻底关闭firewall (public/private/domain)或者

或 Firewall必须允许Windows Remote Management 通过,推荐其他几个也允许。

2. 启动有admin权限的powershell,

 (1) 执行 Enable-PSRemoting -SkipNetworkProfileCheck -force 

 (2) winrm quickconfig 确保执行默认没有提示异常。比如如下

WinRM service is already running on this machine.
WSManFault
    Message
        ProviderFault
            WSManFault
                Message = WinRM firewall exception will not work since one of the network connection types on this machine is set to Public. Change the network connection type to either Domain or Private and try again.

Error number:  -2144108183 0x80338169
WinRM firewall exception will not work since one of the network connection types on this machine is set to Public. Change the network connection type to either Domain or Private and try again.

如果出现了,就要执行Set-NetConnectionProfile -NetworkCategory private 绕过这个限制。再次执行winrm quickconfig 。成功的话见到下面提示

PS C:\WINDOWS\system32> winrm quickconfig
WinRM service is already running on this machine.
WinRM is not set up to allow remote access to this machine for management.
The following changes must be made:

Enable the WinRM firewall exception.
Configure LocalAccountTokenFilterPolicy to grant administrative rights remotely to local users.

Make these changes [y/n]? y

WinRM has been updated for remote management.

WinRM firewall exception enabled.
Configured LocalAccountTokenFilterPolicy to grant administrative rights remotely to local users.

3. 必要的service

主控机(发起reboot要求的)

1. 默认用Restart-Computer的DCOM协议,使用下面code达成并发重启多台目的。这里的Code适用于默认的Win10 Powershell 5.1。

#https://theitbros.com/the-rpc-server-is-unavailable-0x800706ba/
#A. Disable Firewall OR 
#B.1 on active Firewall ,enable | allow Windows Management on private & public network
#B.2 Make sure Windows Mangement service is running
#To confirm : On active Firewall ,create new inbound rule:TCP port within range 49152 to 65535
$user_1="share"
$pass_1= "Aa123456"


$secured_pass_1=ConvertTo-SecureString -String $pass_1 -AsPlainText -Force
$credential_1= New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user_1 , $secured_pass_1

$restartBlock={
    param($computername , $cred)
    Write-Output "timeout=6 minutes , restarting "$computername #Job won't output info to console , Receive-Job is the only way to receive
    #shutdown -m is another way remote restart machines ,however , before invcation , net use /user is demanded
    Restart-Computer -ComputerName $computername -force -Credential $cred -Wait -Timeout 600 #credential must be passed in , as scriptBlock could not access variables outside
}
$machines_1=@("10.176.33.196")

[System.Collections.ArrayList]$jobs=@() #Normal Array is of fixed size , I must empoyee ArrayList
$completedJobs=New-Object -TypeName "System.Collections.ArrayList"

#Restart-Computer -ComputerName 10.176.33.206 -force -Credential $credential_2

foreach ($machine in $machines_1)
{
    $job= Start-Job -ScriptBlock $restartBlock -ArgumentList $machine , $credential_1
    $jobs.Add($job)
}


$quit=$jobs.Count 

while ($quit -ne 0)
{

    foreach ($job in $jobs)
    {
        if ($job.State -eq "Running")
        {
            $info=Receive-Job -Job $job 6>&1
            if($info)
            {
                Write-Host $info
            }
        }        
   
        if ((($job.State -eq "Completed") -or ($job.State -eq "Failed")) -and (-Not $completedJobs.Contains($job)))
        {
            $info=Receive-Job -Job $job 6>&1
            if($info)
            {
                Write-Host $info
            }
            Write-Host "Job Completed : $($job|Select-Object Name,State)"

            $quit--
            if ($quit -eq 0)
            {
            return
          
            }
            $completedJobs.Add($job)
          
        }

    }
    Start-Sleep 5
    Write-Host "$quit Jobs are still running"
}



2. 可以先reboot一台远程机器试试,看是否有异常,比如:a. Access is Denied b. PRC is unavialable

如果使用Invoke-Command也成功执行,如下图,前提条件如上面要求

利用Ws-Man还能远程执行其他各种命令,比如列出远程内容。非常强大

各种异常情况diagnostic:

1. 阅读Microsoft官方的常见解决方案

2. 尝试主控机上用Enter-PSSession -ComputerName x.x.x.x -Credential $MyCredential的方式连接远程,看看有啥报错。正常如下

PS C:\WINDOWS\system32> Enter-PSSession -ComputerName 10.176.33.131 -Credential $credential_1

[10.176.33.131]: PS C:\Users\share\Documents> exit

PS C:\WINDOWS\system32> 

踩到的坑: remote端已经关闭了firewall,结果报Access is denied。最后发现必须远程端成功执行winrm quickconfig,估计是要达到"Configured LocalAccountTokenFilterPolicy to grant administrative rights remotely to local users."这个条件。

另一参考文档,感觉本地和remote端执行winrm set winrm/config/client @{TrustedHosts="*"} 与Restart-Computer无关。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值