Using PowerShell to Rerun an SCCM Client Advertisement
I wrote the following function to rerun an advertisement on a remote client computer using either the AdvertisementID or the PackageID. Like all sample code found online, please run through a test environment first, and use at your own risk!
1<#
2
3*******************************************************************************************************************************
4** All code is for demonstration only and should be used at your own risk. I cannot accept liability for unexpected results. **
5*******************************************************************************************************************************
6
7Use: You're welcome to use, modify, and distribute this script. I'd love to hear about how you're using it or
8modifications you've made in the comments section of the original post over at ChristopherKibble.com.
9
10#>
11
12Function Start-CCMRerunAdvertisement {
13
14 <#
15 .SYNOPSIS
16 Restarts an SCCM advertisement on a remote computer.
17 .DESCRIPTION
18 This script will remotely connect to a computer running the CCM Client,
19 find an advertisement by the Advertisement ID or the Package ID (or
20 both), and then restart the advertisement.
21 .NOTES
22 File Name : Start-CCMRerunAdvertisement.ps1
23 Version : 2017-09-21 (v1.0)
24 Author : Christopher Kibble (www.ChristopherKibble.com)
25 Tested : PowerShell Version 5
26 .PARAMETER ComputerName
27 The name of the remote computer to connect to.
28 .PARAMETER AdvertisementID
29 All or part of the Advertisement ID to run. Wildcards accepted.
30 Defaults to *. Either this or PackageID must be specified.
31 .PARAMETER PackageID
32 All or part of the Package ID to run. Wildcards accepted.
33 Defaults to *. Either this or AdvertisementID must be specified.
34 .PARAMETER MaxRun
35 If more than one advertisement meets your criteria, how many of the
36 advertisements to run. Defaults to 1.
37 .PARAMETER MoreThanPing
38 In environments where ICMP may not allow pinging a remote computer,
39 this switch will make the script attempt to connect to C$ on the remote
40 computer in order to determine if it's online.
41 .EXAMPLE
42 Start-CCMRerunAdvertisement -ComputerName SANDIAGO-001 -AdvertisementID "US000001"
43 #>
44
45 [CmdLetBinding()]Param(
46 [Parameter(Mandatory=$true)][string]$computerName,
47 [Parameter(Mandatory=$false)][string]$advertisementId = "*",
48 [Parameter(Mandatory=$false)][string]$packageId = "*",
49 [Parameter(Mandatory=$false)][int]$maxRun = 1,
50 [Parameters(Mandatory=$false)][switch]$moreThanPing = $false
51 )
52
53 # TODO LIST:
54 #
55 # - Better error control when WMI connections fail.
56 # - Are we using the best method to sort when using MaxRun?
57 #
58
59 if($advertisementId -eq "*" -and $packageId -eq "*") {
60 Write-Error "You must supply either an AdvertisementID or a PackageID"
61 return "Missing Parameters"
62 break
63 }
64
65 $searchString = "$advertisementId-$packageId-*"
66
67 if(!(Test-Connection -ComputerName $computername -ErrorAction SilentlyContinue)) {
68
69 if($moreThanPing) {
70 if(!(Get-ChildItem "\\$computername\c$" -ErrorAction SilentlyContinue)) {
71 Write-Error "System Offline"
72 Return "System Offline"
73 break
74 }
75 } else {
76 Return "System Offline"
77 break
78 }
79
80 }
81
82 Write-Verbose "Getting ID of ScheduleMessage on $computername"
83
84 $schMsgs = Get-WmiObject -ComputerName $computername -Namespace "root\ccm\policy\machine\actualconfig" -Class CCM_Scheduler_ScheduledMessage
85
86 $thisMsg = $schMsgs | ? { $_.ScheduledMessageID -like $searchString } | Sort ActiveTime -Descending | select -First $maxRun
87
88 if(!$thisMsg) {
89 Write-Verbose "Cannot Find Advertisement/Package on Target Computer"
90 Return "Cannot Find Advertisment"
91 break
92 }
93
94 $thisMsg | % {
95
96 [xml]$activeMessage = $_.activeMessage
97
98 $amProgramId = $activeMessage.SoftwareDeploymentMessage.ProgramID
99 $amAdvId = $activeMessage.SoftwareDeploymentMessage.AdvertisementID
100 $amPkgId = $activeMessage.SoftwareDeploymentMessage.PackageID
101 $ScheduledMessageId = $_.ScheduledMessageId
102
103 Write-Verbose "Restarting $amArogramId (ADV=$amAdvId) (PKG=$amPkgId) for Schedule Message $ScheduledMessageId"
104
105 $softwareDist = Get-WmiObject -ComputerName $computername -Namespace "root\ccm\policy\machine\actualconfig" -Class CCM_SoftwareDistribution -Filter "ADV_AdvertisementID = '$amAdvId' and PKG_PackageID = '$amPkgId'"
106
107 $original_Rerun = $softwareDist.ADV_RepeatRunBehavior
108
109 if($original_Rerun -ne "RerunAlways") {
110 write-verbose "Changing Rerun Status from $original_Rerun to RerunAlways"
111 $softwareDist.ADV_RepeatRunBehavior = "RerunAlways"
112 $softwareDist.put() | Out-Null
113 }
114
115 Write-Verbose "Triggering Schedule on $computername"
116 Invoke-WmiMethod -ComputerName $computername -Namespace "root\ccm" -Class "SMS_CLIENT" -Name TriggerSchedule $ScheduledMessageId | Out-Null
117
118 Write-Verbose "Sleeping for 5 seconds"
119 Start-Sleep -Seconds 5
120
121 if($original_Rerun -ne "RerunAlways") {
122 Write-Verbose "Changing Rerun Status back to $original_Rerun"
123 $softwareDist.ADV_RepeatRunBehavior = "$original_Rerun"
124 $softwareDist.put() | Out-Null
125 }
126
127 Return "Reran Advertisement"
128
129 }
130
131}