Powershell - SCCM - Readvertise a previously installed softwarepackage remotly (not from console)

Ever came to the situation, that you have to rerun an advertisement on a computer after a failed installation with SCCM? This could happen if you want to install flashplayer or adobe acrobat or some kind of software that is frequently used by the user. We had problems on installing software while wsus was installing its updates and the msi installer said “Hmm… perhaps, another installation is running already, so I cant do anything for you (BLAME!), sorry”. I hate this message, because its a pain in the ass to readvertise these failed softwarepackages on a single computer.

As some posts earlier mentioned, I am writing an administration webapplication to administrate our environment. This includes softwaredeployment too. We address our softwarepackages by Active Directory groups. Every time we create a new softwarepackage, we create a seperate computer collection in SCCM and link it to a newly created ad group. Every member of this ad group (computers for instance) gets the linked software by SCCM.

While it’s a bit difficult to get some automation into the readvertisement with all these groups and links, we wrote a script, that is triggered by my webgui and does this job on the client computer side for us.

As you can imagine, the first prerequisite for this script to run is: Yes, admin privilages on the client computer. If you don’t have admin rights, just do the conventional way: walk over there and install the software by hand.

What does your script in detail?

That was the question I was waiting for. It’s a bit complicated, but I try to explain what my script does.

These are the prerequisites:

  1. Admin privilages on the client computer
  2. An administrative powershell
  3. A computername, netbiosname, dns name, or ipaddress of your machine
  4. The advertisementID of your advertisement. But pay attention! The used advertisementID is the one of your computer and not the one from your SCCM server. You can get your advertisementID at your sccm client computer reports. (It’s the AdvertisementID you can see at your sccm console). If you want to get the advertisementID by packageID just scroll down a bit to the topic " Get the client advertisementID by packageID"

If you have your (client) advertisementID (should look something like XXX00012, where XXX is your sitecode) we can now start on how the script actually works. This script does everything by using (the mighty) WMI. First we query the CCM_Softwaredistribution to change a value of a current advertisement.

This key ist called “ADV_RepeatRunBehavior”. As the name says, this key controls, when your advertisement have to rerun. Normally this key has “RerunIfFail” as value. But the advertisement doesn’t rerun over and over again until the installation is successfull (thats why you are here and reading this post). We set the value of our advertisement from “RerunIfFail” to “RerunAlways”. Afterwards we query the CCM_Scheduler_ScheduledMessage to get the ScheduledMessageID (which looks like a GUID with your advertisementID as first segment).

This id is used for the scheduler to identify your advertisement. So all we have to do is to trigger the SMS_Client (method: TriggerSchedule), pass through our ScheduledMessageID and fire it up. After submitting our request the SMS_Client on your computer comes up and with “hey, some kind of software needs to be installed (if you configured this in SCCM)”.

All we have to do after your advertisement is rerunning is to reset “ADV_RepeatRunBehavior” to its previous state which was “RerunIfFail”. I don’t want to destroy anything, so I read this value before changing it at the beginning of my script and put it back in, after we are done with our readertisement.

Im not finished with this script yet, it’s a little beta script to test the rerun on my local computer. There is no exception handling, no trapping, no checking on the return values. I like this kind of raw script, because you can take what you want without renaming all functions, and rewrite all the exceptional thing. Let me know (@comments) if you want to get the final script with all the exception handing and the ping checker. I added a beta version of the rerun script at the end of this post.

Very important

You can’t rerun all of your previously commited advertisement. The SMS_Client delete your advertisements after… I don’t know on which conditions these items are deleted. Every rerunable advertisement is stored in the CCM_SoftwareDistribution database. So you have to check first if your advertisement is available.

Get the client advertisementID by packageID

If you don’t want to find the client advertisementID by reading your reports you can get it by quering the “CCM_Softwaredistribution” for the fields “PKG_Name” (the SCCM packagename) or “PKG_PackageID” (the SCCM PackageID you can see at your SCCM console). To get a list of all readvertisable advertisements, just use this WMI query on your client.

1
2
# // Query the CCM_Softwaredistribution database to get all readvertisable advertisment IDs
get-wmiobject -query "SELECT ADV_AdvertisementID, PKG_Name, PKG_PackageID FROM CCM_Softwaredistribution " -namespace "root\CCM\Policy\Machine\ActualConfig" -Computer $Computer

The Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# // Kudos
# // Author: Marco Di Feo
# // Website: http://www.marco-difeo.de
# // Scriptname: rerun_sccm_advertisement_on_client.ps1
# //
# // Usage: This script can be modified to fit your needs
# // Pingback: /2011/10/13/powershell-sccm-readvertise-a-previously-installed-softwarepackage-remotly/
# //
# // #######################################################################################
# // Declaration
# // #######################################################################################

# // Your SCCM advertisementID
$ADVID = "XXX200BC"
# // Computername on which the magic takes place ( . is the local computer)
$Computer = "."
# // #######################################################################################
# // Script start
# // #######################################################################################
#
# // Variable to store your current repeat run behaviour (mostly RerunIfFail)
$CurrentRepeatRunBehaviour = ""
# // Should check if the computer is already online or not.
# // Query the CCM_Softwaredistribution class to set the ADV_RepeatRunBehavior. This variable defines, when your advertisement has to rerun
# // Mostly, this key has the value "RerunIfFail"
$Advertisement = get-wmiobject -query "SELECT * FROM CCM_Softwaredistribution WHERE ADV_AdvertisementID LIKE '$($ADVID)' " -namespace "root\CCM\Policy\Machine\ActualConfig" -Computer $Computer -Authentication PacketPrivacy -Impersonation Impersonate
# -> if returnvalue.length == 1
# // Store your current ADV_RepeatRunBehavior value
$CurrentRepeatRunBehaviour = $Advertisement.ADV_RepeatRunBehavior
# // Set the ADV_RepeatRunBehavior to RerunAlways. We set this back to its previous value after triggering the SCCM_Client to rerun your advertisement
$Advertisement.ADV_RepeatRunBehavior = "RerunAlways"
# // Commit your changes
$Advertisement.put()

# // Get the ScheduledMessageID. You need this ID to trigger the scheduler to process your advertisement to rerun
$ScheduledMessageID = (get-wmiobject -query "SELECT ScheduledMessageID FROM CCM_Scheduler_ScheduledMessage WHERE ScheduledMessageID LIKE '$($ADVID)-%' " -namespace "root\CCM\Policy\Machine\ActualConfig" -Computer $Computer -Authentication PacketPrivacy -Impersonation Impersonate).ScheduledMessageID
# -> if != ""

# // Get Root Namespace of your SMS_Client for triggering the rerun
$SMSClient = [WmiClass]"\\$($Computer)\ROOT\ccm:SMS_Client"
# // Get the ParameterList from the TriggerSchedule method
$ParameterList = $SMSClient.psbase.GetMethodParameters("TriggerSchedule")
# // Set sScheduleID to your previously determined ScheduledMessageID
$ParameterList.sScheduleID = $ScheduledMessageID
# // Invoke the TriggerSchedule WMI Method and commit your ParameterList (which only contains your ScheduledMessageID)
$SMSClient.psbase.InvokeMethod("TriggerSchedule",$ParameterList,$NULL)

# // After triggering the TriggerSchedule your advertisement will rerun immediately, but lets wait a sec or two
sleep 3

# // Reset the ADV_RepeatRunBehaviour field of CCM_Softwaredistribution, so no undesired advertise will rerun
# // Query your CCM_Softwaredistribution
$Advertisement = get-wmiobject -query "SELECT * FROM CCM_Softwaredistribution WHERE ADV_AdvertisementID LIKE '$($ADVID)' " -namespace "root\CCM\Policy\Machine\ActualConfig" -Computer $Computer -Authentication PacketPrivacy -Impersonation Impersonate
# // Set the ADV_RepeatRunBehavior to the previous value
$Advertisement.ADV_RepeatRunBehavior = $CurrentRepeatRunBehaviour
# // Commit changes
$Advertisement.put()
# // YAY, we are done!
# // Party!
# //

Here you can download a much more final version of the rerun script: Powershell Readvertisement Script

Licensed under CC BY-NC-SA 4.0
Zuletzt aktualisiert am Oct 13, 2011 20:50 UTC
comments powered by Disqus
Developer / Inventor / Creator
Erstellt mit Hugo
Theme Stack gestaltet von Jimmy