<# #> param ( # Array of strings listing computer name(s) to wake up. Names will be matched using RegEx [Alias("Computer")] [String[]] $TargetComputer = "", # XML database file containing computer details [Alias("List", "database", "db")] [String] $WolDatabase = "WOLDatabase.xml", # Skip connectivity readiness check [Alias("NoCheck", "NoReadiness")] [Switch] $NoConnectivityCheck = $false, # Initial wait period in seconds before first connectivity check [Int] $WaitBeforeConnectivityCheck = 10, # connectivity readiness check total timeout [Int] $Timeout = 300, # connectivity readiness port to check [Alias("CheckPort")] [Int] $ConnectivityPort = 3389 ) function exitError($errMessage, $PSItem, $exitCode = 1) { if ( [String]::IsNullOrEmpty($errMessage)) { Write-Host -ForegroundColor Red "`n`rABNORMAL EXIT: exitError function called without exit message!`n`r" exit 99 } Write-Host -ForegroundColor Red "`r`nERROR: ${errMessage}." if ($PSItem) { Write-Host -ForegroundColor Red "`r`nAdditional information:`r`n$PSItem" } Write-Host Exit $exitCode } function exitGracefully() { Write-Host -ForegroundColor Green "`r`nFinished.`r`n" Exit 0 } # constants Set-Variable -Name wolModuleName -Value "wol-magicPacket" -Option Constant # exit on error if Send-MagicPacket module is not loaded if (!(Get-Module -Name $wolModuleName)) { try { Import-Module -Name $wolModuleName -ErrorAction Stop } catch { $errMessage = "Unable to load '$wolModuleName'" exitError $errMessage $PSItem } } # exit if database cannot be found/read if (!(Test-Path -Path $WolDatabase -PathType Leaf)) { $errMessage = "Unable to find or read Wake-On-LAN database file ($WolDatabase)" exitError $errMessage } # get target computer name if not already specified if ( [String]::IsNullOrWhiteSpace($TargetComputer)) { do { $TargetComputer = Read-Host -Prompt 'Computer to wake-up' } while ( [String]::IsNullOrWhiteSpace($TargetComputer)) } Write-Host # read database and assemble list of target computers [xml]$db = Get-Content -Path $WolDatabase $broadcastIP = $db.WOLDatabase.Configuration.BroadcastAddress $port = $db.WOLDatabase.Configuration.Port $dnsSuffix = $db.WOLDatabase.Configuration.DnsSuffix $targetComputers = [System.Collections.Generic.List[PSObject]]::new() $TargetComputer | ForEach-Object { $tgt = $_ $db.WOLDatabase.Computers.Computer | Where-Object { $_.name -match $tgt } | ForEach-Object { $targetComputers.Add($_) } } $removeFromTargetComputers = [System.Collections.Generic.List[String]]::new() # exit if nothing to do (i.e. empty targetComputers list) if ($targetComputers.Count -eq 0) { Write-Host -ForegroundColor Yellow "No computers found matching '$TargetComputer'. Nothing to do.`r`n" exit 0 } # send WOL magic packets $targetComputers | ForEach-Object { $wolError = @() $name = $_.name $friendlyName = $_.friendlyName if ( [String]::IsNullOrWhiteSpace($friendlyName)) { Write-Host "Processing request to wake-up '$name'... " -NoNewline } else { Write-Host "Processing request to wake-up '$friendlyName'... " -NoNewline } # send magic packet $_.mac | Send-MagicPacket -BroadcastIP $broadcastIP -Port $port -ErrorAction SilentlyContinue -ErrorVariable +wolError if ($wolError.Count -eq 0) { Write-Host -ForegroundColor Green "[OK]" } else { Write-Host -ForegroundColor Red "[ERROR]" $removeFromTargetComputers.Add($name) } } # remove computers from targetComputers if WOL packet was not successfully sent $removeFromTargetComputers | ForEach-Object { $removeName = $_ $targetComputers.Remove(($targetComputers | Where-Object { $_.name -eq $removeName })) | Out-Null } # exit if connectivity check skipped or if no computers to test if ($NoConnectivityCheck) { Write-Host "`r`nSkipping connectivity checks." exitGracefully } elseif ($targetComputers.Count -eq 0) { exitError "No successful wake-up packets sent" -exitCode 5 } # wait for initialWaitTime seconds to let computer(s) wake up for ($i = $WaitBeforeConnectivityCheck; $i -gt 0; $i--) { Write-Progress -Activity "Waiting for computer(s) to wake-up..." -SecondsRemaining $i Start-Sleep 1 } Write-Progress -Activity "Waiting for computer(s) to wake-up..." -Completed # iterate computers and test connectivity $targetComputers | ForEach-Object { $name = $_.name $friendlyName = $_.friendlyName $fqdn = -join ($name, $dnsSuffix) $connectionError = "" if ( [String]::IsNullOrWhiteSpace($friendlyName)) { Write-Host "Testing connection readiness of '$name'... " -NoNewline } else { Write-Host "Testing connection readiness of '$friendlyName'... " -NoNewline } if (!(Test-NetConnection -ComputerName $fqdn -Port $ConnectivityPort -InformationLevel Quiet -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -ErrorVariable connectionError)) { Write-Host -ForegroundColor Red "[ERROR]" Write-Host -ForegroundColor Red "`tAdditional information:", $connectionError[-1].ToString() } else { Write-Host -ForegroundColor Green "[OK]" } } # exit gracefully exitGracefully