Simple method to cycle through a list of computers
Posted on July 27, 2019
- and tagged as
- powershell
Often we need to query a group of computers (using WinRM for example) to obtain some data or run certain commands. This can be tricky as some devices may be offline, so a simple for
loop usually isn’t enough. Storing the computer list in an array and removing a device once it has been successfully processed is one way, but this means we cannot stop/pause our script, and we lose track of all progress if the device we’re running the script on goes down for whatever reason.
Below is a simple boilerplate function for storing the computer list in a file, and cycling though the file for as long as there are unprocessed computers remaining. Once a device has been processed, it is removed from the file immediately.
It a assumes a file is present with a list of hostnames (one per line) called PCList.txt.
function RunLoop {
[CmdletBinding()]
Param ()
[System.Collections.ArrayList]$PCList = Get-Content PCList.txt
while ($PCList.Count -gt 0) {
Write-Host "$((Get-date).toString()): Starting loop, $($PCList.Count) PC(s) remaining"
$TempList = $PCList.Clone()
$ProgressCounter = 1
foreach ($PC in $PCList) {
$Data = $null
Write-Host "Connecting to $PC ($ProgressCounter/$($PCList.count))..."
try {
# Here we run whatever command we need on the remote device
$Data = Invoke-Command -ComputerName $PC -ScriptBlock {Get-Process} -ErrorAction Stop
}
catch {
Write-Host " -> Unable to connect to $PC, skipping" -ForegroundColor Gray
write-Verbose $_.Exception.GetType().FullName
write-Verbose $_.Exception.Message
}
if ($Data) {
try {
Write-Host " -> Successfully got data from $PC" -ForegroundColor Green
# Do whatever we need with $Data, write to a file, etc.
$TempList.Remove($PC)
$TempList | Out-File PCList.txt -Force
}
catch {
Write-Warning $_.Exception.GetType().FullName
Write-Warning $_.Exception.Message
}
}
$ProgressCounter ++
}
$PCList = $TempList
Start-Sleep -Seconds 20
}
}