99 lines
4.4 KiB
PowerShell
99 lines
4.4 KiB
PowerShell
function Wait-ServersAreReachable {
|
|
<#
|
|
.Synopsis
|
|
Waits on the list of $Servers to become reachable by WinRM with a timeout.
|
|
.Parameter Servers
|
|
The servers to connect to and wait for.
|
|
.Parameter TimeoutMinutes
|
|
The number of minutes to wait until this function times out.
|
|
.Parameter RetryDelaySeconds
|
|
The number of seconds to wait between WinRM connection test attempts.
|
|
#>
|
|
Param (
|
|
[Parameter(Mandatory = $true)]
|
|
[string[]]$Servers,
|
|
[Parameter(Mandatory = $false)]
|
|
[int]$TimeoutMinutes = 10,
|
|
[Parameter(Mandatory = $false)]
|
|
[int]$RetryDelaySeconds = 5
|
|
)
|
|
|
|
$logLead = (Get-LogLeadName)
|
|
|
|
# if there are no servers to wake up, skip it!
|
|
if(Test-IsCollectionNullOrEmpty $Servers) {
|
|
Write-Host "$logLead : No servers to act on. Skipping.."
|
|
return
|
|
}
|
|
|
|
$csvServers = $Servers -join ", "
|
|
Write-Host "$logLead : Waiting on Servers to Become Reachable: $csvServers"
|
|
|
|
# Create counters to track how many servers have been reached, and start the timer.
|
|
$connectCount = 0
|
|
$totalConnected = 0
|
|
$serverCount = $Servers.Count
|
|
$stopWatch = [System.Diagnostics.Stopwatch]::StartNew()
|
|
|
|
# Assign Servers to a ServerList, which we will whittle down as servers become reachable.
|
|
$serversNotConnectedTo = $Servers
|
|
Write-Host "$logLead : Attempting to connect to all servers. Will retry to connect for $TimeoutMinutes minutes for any that can't connect."
|
|
|
|
while($connectCount -lt $serverCount) {
|
|
$hostResults = Invoke-Parallel -objects $serversNotConnectedTo -returnObjects -numThreads 32 -script {
|
|
param($server)
|
|
$session = $null
|
|
$logLead = "[Wait-ServersAreReachable]"
|
|
try {
|
|
$so = New-PSSessionOption -OpenTimeout 10000 -CancelTimeout 30000 -OperationTimeout 30000 -MaxConnectionRetryCount 1
|
|
$session = New-PSSession $server -ErrorAction SilentlyContinue -SessionOption $so
|
|
$success = (1 -eq (Invoke-Command -Session $session -ErrorAction Stop -ScriptBlock { return 1 }))
|
|
|
|
if($success) {
|
|
Write-Host "$logLead : Connected successfully to $server"
|
|
return @{"y" = $server} # Single Hashtable added as an item in array $hostResults
|
|
} else {
|
|
|
|
# Write-Verbose instead of Write-Host to reduce chattiness. The servers that are failing are written out in the end.
|
|
Write-Verbose "$logLead : Could not connect to $server"
|
|
return @{"n" = $server} # Single Hashtable added as an item in array $hostResults
|
|
}
|
|
} catch {
|
|
Write-Verbose "$logLead : Error connecting to $server"
|
|
return @{"n" = $server} # Single Hashtable added as an item in array $hostResults
|
|
} finally {
|
|
if($null -ne $session) {
|
|
Remove-PSSession $session
|
|
}
|
|
}
|
|
}
|
|
|
|
# Get count of servers we can connect to. Array of Hashtables, filtered on the Keys, value = server name
|
|
$connectCount = ( ($hostResults | Where-Object{$_.Keys -eq "y"}).Values ).Count
|
|
$totalConnected += $connectCount
|
|
|
|
# Replace $serversNotConnectedTo with the remaining servers that are failing, so that we do not re-test good servers.
|
|
$serversNotConnectedTo = ($hostResults | Where-Object{$_.Keys -eq "n"}).Values
|
|
|
|
Write-Verbose "$logLead : connectCount = $connectCount"
|
|
Write-Verbose "$logLead : totalConnected = $totalConnected"
|
|
Write-Verbose "$logLead : serverCount = $serverCount"
|
|
|
|
if(([int]$stopWatch.Elapsed.TotalMinutes) -ge $TimeoutMinutes) {
|
|
Write-Warning "$logLead : Exceeded timeout of $TimeoutMinutes minutes. Exiting."
|
|
break
|
|
}
|
|
|
|
if($totalConnected -lt $serverCount) {
|
|
Write-Host "$logLead : Connected to $totalConnected out of $serverCount servers. Sleeping $RetryDelaySeconds seconds."
|
|
Start-Sleep -Seconds $RetryDelaySeconds
|
|
} else {
|
|
Write-Host "$logLead : Successfully connected to all servers."
|
|
break
|
|
}
|
|
}
|
|
|
|
if($totalConnected -lt $serverCount) {
|
|
throw "$logLead : Couldn't connect to all servers in alloted time of $TimeoutMinutes minutes.`nCouldn't connect to: $serversNotConnectedTo "
|
|
}
|
|
} |