2
$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 
      }    

After running through 30 machines, PowerShell and the machine running the script runs out of memory. How can this be avoided?

The shell consumes all 16 GBs of memory on running machine. Solutions like exceeding memory for the shell may not work e.g. OutOfMemory Exception on remote execution using Powershell Invoke-Command

G42
  • 9,791
  • 2
  • 19
  • 34
CodeEmpower
  • 635
  • 1
  • 11
  • 29
  • Possible duplicate of [OutOfMemory Exception on remote execution using Powershell Invoke-Command](https://stackoverflow.com/questions/9665981/outofmemory-exception-on-remote-execution-using-powershell-invoke-command) – Maxim Jan 10 '18 at 17:26

3 Answers3

1

If you want to use PowerShell, write 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'
    }  
}

I suspect all that remote file writing and external calls may have caused problems (also, if you're on v5+, use the *Archive cmdlets over 7z). Additionally, you were generating a session but never using it.

Maximilian Burszley
  • 18,243
  • 4
  • 34
  • 63
1

I monitored the memory space for PowerShell during the execution of the script. The Memory instantly starts increasing when running the wget command, the progress output fills the console buffer and eating the PowerShell process memory. I used

        & 'wget' '-q' 'http://software/software.7z' 

which kept memory usage stabilized and also speeded up the execution massively

Hide wget output in Linux

Of course if running PowerShell 5.1 Copy-Files over PSSession can be used instead

CodeEmpower
  • 635
  • 1
  • 11
  • 29
0

Not sure about the memory issues but a few things you could try.

  1. Your New-PsSession doesn't do anything, so either get rid of it, or use it. then you can do invoke-command several times on the same session, instead of sending the big block
  2. Maybe running them in parallel with -nowait, and then wait-job'ing the objects would also help memory issues.
  3. don't foreach, use the pipeline :) $machines | %{ invoke-command -machine $_...
Steve
  • 976
  • 12
  • 12