Powershell 在远程计算机上运行Invoke命令时发生OutOfMemory错误

Powershell 在远程计算机上运行Invoke命令时发生OutOfMemory错误,powershell,memory,memory-management,memory-leaks,out-of-memory,Powershell,Memory,Memory Management,Memory Leaks,Out Of Memory,在运行了30台机器之后,PowerShell和运行脚本的机器内存不足。如何避免这种情况 shell将消耗正在运行的计算机上所有16 GB的内存。解决方案(如外壳内存过大)可能不起作用,例如如果要使用PowerShell,请编写PowerShell $Machines = Get-Content Machines.txt foreach($Machine in $Machines) { $session = New-PSSession -ComputerName

在运行了30台机器之后,PowerShell和运行脚本的机器内存不足。如何避免这种情况


shell将消耗正在运行的计算机上所有16 GB的内存。解决方案(如外壳内存过大)可能不起作用,例如

如果要使用PowerShell,请编写PowerShell

$Machines = Get-Content Machines.txt
    foreach($Machine in $Machines)
      {
        $session = New-PSSession -ComputerName $Machine -Credential $creds 
        Invoke-Command -ComputerName $Machine -ScriptBlock {
           #Download 
           & 'wget' 'http://software/software.7z'
           #Extract
           & '7z' 'x' 'C:\software.7z'  '-r' '-y'
           $cleanscript = "Remove-Item C:\software.7z  -Force"
           $cleanscript  | Out-File C:\RemoveZip.ps1 -Encoding ascii
           & "C:\RemoveZip.ps1"
           $script = "CALL C:\software\setup.exe"
           $script  | Out-File C:\software.cmd -Encoding ascii
           & "C:\software.cmd"
       } -Credential $creds 
      }    

我怀疑所有远程文件写入和外部调用都可能导致问题(另外,如果您使用的是v5+,请在
7z
上使用
*Archive
cmdlet)。此外,您正在生成一个会话,但从未使用过它。

不确定内存问题,但有几件事可以尝试

  • 你的新会话没有任何作用,所以要么扔掉它,要么使用它。然后,您可以在同一个会话上多次调用命令,而不是发送大的块
  • 也许将它们与-nowait并行运行,然后等待对象也会有助于解决内存问题
  • 不要foreach,使用管道:)$machines |%{invoke命令-machine$\

  • 在脚本执行期间,我监视了PowerShell的内存空间。运行wget命令时,内存立即开始增加,进度输出填充控制台缓冲区并占用PowerShell进程内存。我使用

    $Machines = Get-Content -Path Machines.txt
    ForEach ($Machine in $Machines)
    {
        Invoke-Command -ComputerName $Machine -Credential $creds -ScriptBlock {
            #Download 
            Invoke-WebRequest -Uri 'http://software/software.7z' -OutFile 'C:\software.7z'
    
            #Extract
            Start-Process -FilePath '7z.exe' -ArgumentList 'x','C:\software.7z','-r','-y' -NoNewWindow -Wait
            Remove-Item -Path C:\software.7z -Force
    
            Start-Process -FilePath 'C:\software\setup.exe'
        }  
    }
    
    这保持了内存使用的稳定,也大大加快了执行速度


    当然,如果在PSSession上运行PowerShell 5.1 Copy Files可以用
    -Wait
    来代替,那么当我们可以使用较短的
    &
    操作符时,要额外键入大量的内容。@Bill_Stewart根据我使用
    &
    的经验,它是异步的。另外,为什么要抱怨“额外键入”呢在编写脚本时?只需指出它是不必要的。此外,
    &
    操作符会阻止脚本,直到命令完成(即,它不是异步的)。这很容易演示。根据您的链接,该过程会生成其他任务并关闭主线程,因此最终会发生异步事件。您可以模拟解析对以下内容所做的操作:
    &vs\u enterprise.exe--wait--quiet--norestart--installpath C:\vs\2017
    ForEach对象比ForEach对象慢,除非您PSv5.1上的e不确定在包装网络调用时循环的速度与它有什么关系,你也有来源吗?管道操作总是比较慢。自己运行一个测试:
    Measure Command{ForEach($i in 1..10000){$i}
    Measure Command{1..10000}{$}
    平均慢6-7倍。可能重复
            & 'wget' '-q' 'http://software/software.7z'