首页 > 解决方案 > Powershell 脚本在机器之间循环,但如果暂时失去网络,则会挂起

问题描述

我有一个 powershell 脚本,它解析一个充满机器名称的 txt 文件,然后一个接一个地创建与系统的会话,运行一些命令,然后移动到下一个系统。该脚本通常需要大约 10-30 秒才能在每个系统上运行,具体取决于脚本中遇到的情况。

有时,当前正在检查的系统会由于各种原因失去网络连接。发生这种情况时,控制台开始写入有关尝试重新连接 4 分钟的黄色警告消息,然后在无法重新连接时断开会话。即使它在 4 分钟内再次建立连接,之后它也不会做任何事情,就像脚本只是冻结一样。它不会移动到下一个系统并且它不会停止脚本,我必须手动停止它,或者如果我手动运行脚本,我可以点击 control+c 来跳出当前循环,然后它然后移动到列表中的下一台机器。

如果遇到警告,有什么方法可以跳出当前循环,以便它可以移动到下一台机器?那将是我理想的解决方案。谢谢!

脚本很简单。。

foreach($server in Get-Content .\machines.txt) {
    if($server -match $regex){

invoke-command $server -ErrorAction SilentlyContinue -ScriptBlock{
command1
command2
command3
}
}

这就是发生的事情

PS C:\temp> .\script.ps1
machine1
machine2
machine3
machine4
machine5
WARNING: The network connection to machine5 has been interrupted. Attempting to reconnect for up to 4 minutes...
WARNING: Attempting to reconnect to machine5 ...
WARNING: Attempting to reconnect to machine5 ...
WARNING: Attempting to reconnect to machine5 ...
WARNING: The network connection to machine5 has been restored.

但它永远不会继续到 machine6

标签: powershell

解决方案


当我使用多台机器远程工作时,我通常会在机器上并行启动进程。因此,当单台机器超时时,我的影响较小。我为此https://devblogs.microsoft.com/powershell/powershell-foreach-object-parallel-feature/使用 powershell 7 ForEach-Object -Parallel Feature

尝试这样的事情:

$Credential=Get-Credential

#all Necessary parameters must be in the Object i give to ForEach Object
$myHosts = @(
    #Hosts i want to connect to with values i want to use in the loop
    @{Name="probook";cred=$Credential;param1="one_1";param2="two_1"}
    @{Name="probook";cred=$Credential;param1="one_2";param2="two_2"}
)

$var1="one"
$var2="two"

$myHosts | ForEach-Object  -Parallel {
    #Variables outside of this "Parallel" Loop are not available. Because this is startet as separate SubProcess
    #All Values come from the Object i piped in the ForEach-Object 
    $myHost=$_ 
    #This is written to your local Shell
    Write-Host ("Computer: "+ $env:Computername)
    Write-Host $myHost.param1
    Write-Host $myHost.param2
    Write-Host $myHost.cred.UserName

    Invoke-Command -ComputerName $myHost.Name -Credential $myHost.cred -ArgumentList @($myHost.param1,$myHost.param2) -ScriptBlock {
        #Variables outside of of this Invoke Command Script Block are not available because this is a new Remote-Shell on the remote Host
        #Parameters in Ordner of -Argument List
        param($param1,$param2)

        #Do your things on the Remote-Host here

        #This is not Visbible -> it is only written on the "remote Shell"
        Write-Host $env:Computername

        #Here you get Back Values from the remote Shell
        $env:Computername
        $param1
        $param2
    }
} -ThrottleLimit 5

推荐阅读