2021-09-05 17:06:38 -06:00
|
|
|
<#
|
|
|
|
#>
|
|
|
|
|
|
|
|
param
|
|
|
|
(
|
|
|
|
# Computer to wake up
|
|
|
|
[Alias("Computer")]
|
|
|
|
[String]
|
2021-09-05 23:55:19 -06:00
|
|
|
$TargetComputer = "",
|
|
|
|
# XML database file containing computer details
|
|
|
|
[Alias("List", "database", "db")]
|
|
|
|
[String]
|
|
|
|
$WolDatabase = "WOLDatabase.xml",
|
|
|
|
# Skip connectivity readiness check
|
|
|
|
[Alias("NoCheck", "NoReadiness")]
|
2021-09-05 18:33:46 -06:00
|
|
|
[Switch]
|
2021-09-05 23:56:46 -06:00
|
|
|
$NoConnectivityCheck = $false,
|
|
|
|
# Initial wait period in seconds before first connectivity check
|
2021-09-05 18:33:46 -06:00
|
|
|
[Int]
|
2021-09-05 23:56:46 -06:00
|
|
|
$WaitBeforeConnectivityCheck = 10,
|
|
|
|
# connectivity readiness check total timeout
|
|
|
|
[Int]
|
|
|
|
$Timeout = 300,
|
|
|
|
# connectivity readiness port to check
|
|
|
|
[Alias("CheckPort")]
|
|
|
|
[Int]
|
|
|
|
$ConnectivityPort = 3389
|
2021-09-05 17:06:38 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2021-09-05 23:53:33 -06:00
|
|
|
function exitGracefully()
|
|
|
|
{
|
|
|
|
Write-Host -ForegroundColor Green "`r`nFinished.`r`n"
|
|
|
|
Exit 0
|
|
|
|
}
|
|
|
|
|
|
|
|
# constants
|
|
|
|
Set-Variable -Name wolModuleName -Value "wol-magicPacket" -Option Constant
|
2021-09-05 17:06:38 -06:00
|
|
|
|
|
|
|
# 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
|
2021-09-05 23:55:19 -06:00
|
|
|
if (!(Test-Path -Path $WolDatabase -PathType Leaf))
|
2021-09-05 17:06:38 -06:00
|
|
|
{
|
2021-09-05 23:55:19 -06:00
|
|
|
$errMessage = "Unable to find or read Wake-On-LAN database file ($WolDatabase)"
|
2021-09-05 17:06:38 -06:00
|
|
|
exitError $errMessage
|
|
|
|
}
|
|
|
|
|
|
|
|
# get target computer name if not already specified
|
2021-09-05 23:55:19 -06:00
|
|
|
if ( [String]::IsNullOrWhiteSpace($TargetComputer))
|
2021-09-05 17:06:38 -06:00
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
2021-09-05 23:55:19 -06:00
|
|
|
$TargetComputer = Read-Host -Prompt 'Computer to wake-up'
|
|
|
|
} while ( [String]::IsNullOrWhiteSpace($TargetComputer))
|
2021-09-05 17:06:38 -06:00
|
|
|
}
|
2021-09-05 18:33:24 -06:00
|
|
|
Write-Host
|
2021-09-05 17:06:38 -06:00
|
|
|
|
2021-09-05 18:33:24 -06:00
|
|
|
# read database and assemble list of target computers
|
2021-09-05 23:55:19 -06:00
|
|
|
[xml]$db = Get-Content -Path $WolDatabase
|
2021-09-05 17:06:38 -06:00
|
|
|
$broadcastIP = $db.WOLDatabase.Configuration.BroadcastAddress
|
|
|
|
$port = $db.WOLDatabase.Configuration.Port
|
|
|
|
$dnsSuffix = $db.WOLDatabase.Configuration.DnsSuffix
|
2021-09-05 17:25:15 -06:00
|
|
|
$targetComputers = [System.Collections.Generic.List[PSObject]]::new()
|
2021-09-05 23:55:19 -06:00
|
|
|
$db.WOLDatabase.Computers.Computer | Where-Object { $_.name -match "$TargetComputer" } | ForEach-Object { $targetComputers.Add($_) }
|
2021-09-05 18:33:24 -06:00
|
|
|
$removeFromTargetComputers = [System.Collections.Generic.List[String]]::new()
|
2021-09-05 17:25:15 -06:00
|
|
|
|
2021-09-05 22:48:20 -06:00
|
|
|
# exit if nothing to do (i.e. empty targetComputers list)
|
|
|
|
if ($targetComputers.Count -eq 0)
|
|
|
|
{
|
2021-09-05 23:55:19 -06:00
|
|
|
Write-Host -ForegroundColor Yellow "No computers found matching '$TargetComputer'. Nothing to do.`r`n"
|
2021-09-05 22:48:20 -06:00
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
2021-09-05 18:33:24 -06:00
|
|
|
# send WOL magic packets
|
2021-09-05 17:25:15 -06:00
|
|
|
$targetComputers | ForEach-Object {
|
2021-09-05 18:33:24 -06:00
|
|
|
$wolError = @()
|
|
|
|
$name = $_.name
|
|
|
|
$friendlyName = $_.friendlyName
|
|
|
|
if ( [String]::IsNullOrWhiteSpace($friendlyName))
|
2021-09-05 17:06:38 -06:00
|
|
|
{
|
|
|
|
Write-Host "Processing request to wake-up '$name'... " -NoNewline
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Write-Host "Processing request to wake-up '$friendlyName'... " -NoNewline
|
|
|
|
}
|
|
|
|
|
|
|
|
# send magic packet
|
2021-09-05 18:33:24 -06:00
|
|
|
$_.mac | Send-MagicPacket -BroadcastIP $broadcastIP -Port $port -ErrorAction SilentlyContinue -ErrorVariable +wolError
|
|
|
|
if ($wolError.Count -eq 0)
|
2021-09-05 17:06:38 -06:00
|
|
|
{
|
|
|
|
Write-Host -ForegroundColor Green "[OK]"
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Write-Host -ForegroundColor Red "[ERROR]"
|
2021-09-05 18:33:24 -06:00
|
|
|
$removeFromTargetComputers.Add($name)
|
2021-09-05 17:06:38 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-05 18:33:24 -06:00
|
|
|
# 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
|
|
|
|
}
|
|
|
|
|
2021-09-05 23:56:46 -06:00
|
|
|
# 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]"
|
|
|
|
}
|
|
|
|
}
|
2021-09-05 18:33:24 -06:00
|
|
|
|
2021-09-05 23:56:46 -06:00
|
|
|
# exit gracefully
|
|
|
|
exitGracefully
|