For each loop in powershell to run parallely on different servers

Faizan Sayed 46 Reputation points
2021-01-14T12:35:47.147+00:00

Hi , I want to perform disk cleanup on 500 VDIs using below script and create a proper report with VDI status and disk space detail using below script .But I want to run the cleanup parallely on all VDIs not one after other as done in for each loop ..Hence I have tried foreach -parallel but its not working .Please suggest how can I modify this script to perform cleanup parallely on all VDI

$InputFile="H:\Ignio\Lastlogon\vdi list 3.csv"
$AllVDI = Get-Content $InputFile
$collection = @()
$file = "C:\report.csv"
$Starters = (Get-Date)

ForEach-Object -parallel ($VDI in $AllVDI){

if((Test-Connection -ComputerName $VDI -count 1 -ErrorAction 0)) {
    $Isonline = "Online"

if((Test-WSMan -ComputerName $VDI -ErrorAction 0)){
    $Remoting = "Enabled"

Invoke-Command -ComputerName $VDI -Credential $cred -ScriptBlock {

                            Stop-Service -Name wuauserv -Force -Confirm:$false -ErrorAction Ignore -WarningAction Ignore
                            Remove-Item -Path "C:\Windows\Temp\*" -Recurse -Force -ErrorAction Ignore
                            Remove-Item -Path "C:\Windows\SoftwareDistribution\download\*" -Recurse -Force -ErrorAction Ignore
                                  Start-Service -Name wuauserv -Confirm:$false -ErrorAction Ignore    }

   $Space = Invoke-Command -ComputerName $VDI -Credential $cred  -ScriptBlock {Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'"}|Select-Object SystemName,
    @{ Name = "Drive" ; Expression = { ( $_.DeviceID ) } },
    @{ Name = "Size (GB)" ; Expression = {"{0:N1}" -f ( $_.Size / 1gb)}},
    @{ Name = "FreeSpace (GB)" ; Expression = {"{0:N1}" -f ( $_.Freespace / 1gb ) } },

    $free = $Space.'FreeSpace (GB)'
    $Size = $Space.'Size (GB)'
    $Drive=$Space.Drive
    $Action="     Yes"

}

else {$Remoting = "Disabled";}
}

else {$Isonline = "Offline";}


$object = [PSCustomObject]@{

            'VDI' = $VDI
            'Status'="$Isonline"
            'WinRM'="$Remoting" 
            'CleanUp Performed'=$Action
            'Drive'=$Drive
            'Size (GB)'=$Size
            'FreeSpace (GB)'= $free
            }

$collection += $object

}
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,552 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Ian Xue 37,706 Reputation points Microsoft Vendor
    2021-01-15T09:28:28.397+00:00

    Hi,

    You're confusing the ForEach-Object cmdlet with the ForEach keyword. It should be ForEach ($VDI in $AllVDI) or $AllVDI | ForEach-Object -parallel. The ForEach-Object -parallel is introduced in Powershell 7 yet the ForEach keyword doesn't support -parallel.
    https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-7.1
    https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_foreach?view=powershell-7.1

    Another way to run the script in parallel is using jobs
    https://devblogs.microsoft.com/scripting/parallel-processing-with-jobs-in-powershell/

    Best Regards,
    Ian Xue

    ============================================

    If the Answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.