I would use the job engine instead and do something like below.
This is not fully tested, but it should work might have missed something somewhere.
This way you also get them to run in parallel and if one restart hangs it is only that job taking time and if a job takes too long time we remove this job.
Code below:
function restart-myComputer (
[Parameter(ParameterSetName="restart", Mandatory=".")]
[Parameter(ParameterSetName="bg", Mandatory=".")]
[string]$computer,
[Parameter(ParameterSetName="restart")]
[int]$wait,
[Parameter(ParameterSetName="bg")]
[switch]$bg)
{
if ($bg) {
Start-Job -name $computer -ScriptBlock ([scriptblock]::create("Restart-Computer -PSComputerName $computer -Force -ErrorAction stop")) > $null
} else {
Restart-Computer -PSComputerName $computer -Force -ErrorAction stop
Start-Sleep -Seconds $wait
}
}
function remove-myJobs (
[Parameter(ParameterSetName="remove")]
[string[]]$names,
[Parameter(ParameterSetName="remove")]
[int]$maxRunTime = 30
{
$d = get-date
[string[]]$stillRunningJobArr = @()
foreach ($name in $names) {
$job = get-job -name $name
$diffTime = $d - $job.PSBeginTime
if($diffTime.TotalSeconds -gt $maxRunTime) {
remove-job -name $name -Force
write-host "Removed job $name that ran longer then $maxRunTime seconds"
} else {
write-host "Job $name has still not been running for more then $maxRunTime"
$stillRunningJobArr += $name
}
}
return $stillRunningJobArr
}
function remove-allMyJobs (
[Parameter(ParameterSetName="remove")]
[int]$maxRunTime = 30)
{
$d = get-date
foreach ($job in get-job) {
$diffTime = $d - $job.PSBeginTime
$name = $job.name
if($diffTime.TotalSeconds -gt $maxRunTime) {
remove-job -name $name -Force
write-host "Removed job $name that ran longer then $maxRunTime seconds"
} else {
write-host "Job $name has still not been running for more then $maxRunTime"
}
}
}
function restart-myComputers (
[Parameter(ParameterSetName="restart", Mandatory=".")]
[Parameter(ParameterSetName="bg", Mandatory=".")]
[string[]]$computers,
[Parameter(ParameterSetName="bg", Mandatory=".")]
[int]$maxConcurrentJobs,
[Parameter(ParameterSetName="bg", Mandatory=".")]
[Parameter(ParameterSetName="restart")]
[int]$wait,
[Parameter(ParameterSetName="bg")]
[switch]$bg)
{
[string[]]$restartedComputerArr = @()
if ($bg) {
foreach ($computer in $computers) {
if((get-job -state 'Running').Count -gt $maxConcurrentJobs) {
$restartedComputerArr = stop-myJobs -$restartedComputerArr -maxRunTime $maxRunTime
sleep $wait # Wait to get as many jobs to complete as possible.
}
Restart-myComputer -computer $computer -bg
$restartedComputerArr += $computer
}
} else {
Restart-myComputer -computer $computer -wait $wait
}
remove-allMyJobs
}