powershellsccm

Powershell script to send WoL via SCCM


I'm looking to put a short Powershell script together that asks for an asset number then sends a WoL request via Config Manager/SCCM to that asset to wake it up. Most Powershell WoL scripts I've seen seem to achieve this without SCCM, by creating magic packets sending them via mac addresses - I don't want to do it this way.

I was searching online to see if anyone has already achieved this and came across this page:

https://ccmexec.com/2019/01/wake-up-single-computer-or-collection-of-computers-in-configmgr-1810-using-powershell/

On that page they were demonstrating a script written by Written by Johan Schrewelius and Jörgen Nilsson that consists of the following:

[CmdletBinding()]
Param(
    $CmpName = $Null,
    $CollId = "SMS00001",
    $SiteServer = "<site server fgdn>"
)

if (!$CmpName -and $CollId -eq "SMS00001") {

    Write-Host "Seems wrong to wake every single computer in the environment, refusing to perform."
    exit 1
}

$SiteCode = (Get-WmiObject -ComputerName "$SiteServer" -Namespace root\sms -Query 'SELECT SiteCode FROM SMS_ProviderLocation').SiteCode

if ($CmpName) {

    $ResourceID = (Get-WmiObject  -ComputerName "$SiteServer" -Namespace "Root\SMS\Site_$($SiteCode)" -Query "Select ResourceID from SMS_R_System Where NetBiosName = '$($CmpName)'").ResourceID

    if ($ResourceID) {
        $CmpName = @($ResourceID)
    }
}

$WMIConnection = [WMICLASS]"\\$SiteServer\Root\SMS\Site_$($SiteCode):SMS_SleepServer"
$Params = $WMIConnection.psbase.GetMethodParameters("MachinesToWakeup")
$Params.MachineIDs = $CmpName
$Params.CollectionID  = $CollId
$return = $WMIConnection.psbase.InvokeMethod("MachinesToWakeup", $Params, $Null) 

if (!$return) {
    Write-Host "No machines are online to wake up selected devices"
}

if ($return.numsleepers -ge 1) {
    Write-Host "The resource selected are scheduled to wake-up as soon as possible"
}

This script can be run by saving the file as something like wol.ps1, then setting the $SiteServer variable to the SCCM FQDN then running .\wol.ps1 -CmpName 'asset number' to send the WoL request to an individual asset, or .\wol.ps1 -CmpName 'SCCM collection ID' to send the WoL request to an SCCM collection of assets.

This is already pretty good, but I'm looking for is a basic Read-Host script that requests an asset number then sends the WoL request to just that asset, and does nothing more than that. I've tried dismantling the parameter in this script to get the minimum parts required to achieve this, but I just can't wrap my head around it, aside from the information it requests from the SCCM server and requesting the asset's SCCM resource ID, I can't quite figure out how it works.

I'll probably figure it out eventually, but I thought I'd throw it up here to see if anyone has already done this before, or if someone can see how this script achieves what it does and can help me funnel it into a simple short series of actions post user input.

Cheers in advance.


Solution

  • Param(
        $SiteServer = "Your SCCM Server"
    )
    
    $CmpName = Read-host "Enter asset number"
    $SiteCode = (Get-WmiObject -ComputerName "$SiteServer" -Namespace root\sms -Query 'SELECT SiteCode FROM SMS_ProviderLocation').SiteCode
    
    if ($CmpName) {
    
        $ResourceID = (Get-WmiObject  -ComputerName "$SiteServer" -Namespace "Root\SMS\Site_$($SiteCode)" -Query "Select ResourceID from SMS_R_System Where NetBiosName = '$($CmpName)'").ResourceID
    
        if ($ResourceID) {
            $CmpName= @($ResourceID)
        }
    }
    $WMIConnection = [WMICLASS]"\\$SiteServer\Root\SMS\Site_$($SiteCode):SMS_SleepServer"
    $Params = $WMIConnection.psbase.GetMethodParameters("MachinesToWakeup")
    $Params.MachineIDs = $CmpName
    $return = $WMIConnection.psbase.InvokeMethod("MachinesToWakeup", $Params, $Null) 
    
    if (!$return) {
        Write-Host "No machines are online to wake up selected devices"
    }
    
    if ($return.numsleepers -ge 1) {
        Write-Host "The resource selected are scheduled to wake-up as soon as possible"
    }