Trigger/Push Software Installations remotely on SCCM Clients

Targeting software deployments in SCCM works by assigning advertisements/deployments to SCCM collections. SCCM collections can then be populated with target computers by using Active Directory groups containing the respective computers, which will then be added dynamicly to the collection by a SCCM query, after the Active Directory Security Group discovery has run on SCCM side. Then, with the next machine policy retrieval on the SCCM client, the client will recognize its membership in the collection and install the program which has been advertised/deployed to this collection.

This means in other words, the time delay between adding a comptuer to a software deployment group in Active Directory, till the software will be effectively installed on the target computer,  is as big as the sum of the three schedule intervals: The Active Directory Security Group Discovery, the Collection Membership Update and the Policy Retrieval on the client.

For an immediate execution,  a software installation can be triggered programmatically by using a temporay direct collection membership of a computer:

Directly add the target computer to the software distribution collection

$targetClientName = "<TARGETCLIENTNAME>";
$collectionName = "<COLLECTIONNAME>";
$objComputer = Get-WmiObject -query "SELECT ResourceID FROM SMS_R_SYSTEM WHERE NETBIOSNAME LIKE '%$targetClientName%'" -Namespace "ROOT\SMS\site_CO1";
$resourceID = $objComputer.ResourceID;

$searchFilter = "Name = '$softwareName'";
$objCollection = Get-WmiObject SMS_Collection -computer . -Namespace "ROOT\SMS\site_CO1" -filter $searchFilter;
$objCollectionRuleDirect = [WmiClass]"\\\\.\ROOT\SMS\site_CO1:SMS_CollectionRuleDirect";
$objCollectionRuleDirect.properties["ResourceID"].value = $resourceID;
$objCollectionRuleDirect.properties["ResourceClassName"].value = "SMS_R_System";
$objCollectionRuleDirect.properties["RuleName"].value = $targetClientName;
$collectionInParams = $objCollection.GetMethodParameters("AddMembershipRule");
$collectionInParams.collectionRule = $objCollectionRuleDirect;
$objCollection.InvokeMethod("AddMembershipRule", $collectionInParams, $Null);

Update the collection membership of the respective collection

$objCollection.RequestRefresh();

Remotely execute the appropriate client actions on the target computer

# //*** Connect to SCCM client WMI name space ***\\
$SCCMClient = [wmiclass] "\\$targetClientName\root\ccm:SMS_Client";

# //*** Show all available action methods (just as informational note) ***\\
# $SCCMClient | Get-Member;

# //*** Show all available Agent GUIDs (just as informational note) ***\\
# get-wmiobject CCM_Scheduler_ScheduledMessage -namespace root\ccm\policy\machine\actualconfig | select-object ScheduledMessageID, TargetEndPoint | where-object {$_.TargetEndPoint -ne "direct:execmgr"}

# //*** Trigger actions ***\\
try{
   # //*** Trigger "Machine Policy Evaluation and Update Cycle (Download Machine Policy)" ***\\
   $SCCMClient.TriggerSchedule("{00000000-0000-0000-0000-000000000021}");
   # //*** Trigger "Machine Policy Evaluation (Apply Machine Policy)" ***\\

   $SCCMClient.TriggerSchedule("{00000000-0000-0000-0000-000000000022}");
   # //*** Trigger "Software Updates Deployment Evaluation Cycle" ***\\

   $SCCMClient.TriggerSchedule("{00000000-0000-0000-0000-000000000108}");
   # //*** Trigger "Discovery Data Collection Cycle" ***\\
   $SCCMClient.TriggerSchedule("{00000000-0000-0000-0000-000000000003}");
}
catch{
   $_.Exception.Message;
}

Remove the direct collection membership of the computer

$collectionInParams = $objCollection.GetMethodParameters("DeleteMembershipRule");
$collectionInParams.collectionRule = $objCollectionRuleDirect;
$objCollection.PSBase.InvokeMethod("DeleteMembershipRule", $collectionInParams, $Null);

To ensure that the procedure of remotely accessing a SCCM client works, the following prerequisites must be fulfilled:

1. The account executing this actions must  have granted the DCOM “Launch and Activation permissions”. This is true, when the user is a member of the “Distributed COM Users” group on the target machine.

Alternatively, the DCOM permissions “Remote Access”, “Remote Launch” and “Remote Activation” for the appropriate user can be granted explicitely by using Group Policy:

Section: Computer Configuration\Windows Settings\Security Settings\
Local Policies\Security Options"

Policy: DCOM Machine Access Restrictions in Security Descriptor Definition 
Language (SDDL) syntax" (to allow "Remote Access")
Policy: DCOM Machine Launch Restrictions in Security Descriptor Definition 
Language (SDDL) syntax" (to allow "Remote Launch" and "Remote Activation")

2. Remote Management must be enabled as an exception on the client firewall, which can be configured by using Group Policy:

Section: Computer Configuration\Administrative Templates\Network\
Network Connections\Windows Firewall\Domain Profile\

Policy: Windows Firewall: Allow inbound remote administration exception

3. The user must be granted the “Remote Enable” access right on the target system for the CCM node of the WMI namespace. This can be configured from the properties of Computer Management –> Services and Applications –> WMI Control (see screenshot).

Security settings on WMI namespace

The WMI security can also be set programmatically using a VBScript, as described in detail in this  MSDN blog:

'//*** Set WMI "CCM" namespace permissions ***\\

strSD = array(<SECURITYDESCRIPTOR>)

set namespace = createobject("wbemscripting.swbemlocator").connectserver(,"root\CCM")
set security = namespace.get("__systemsecurity=@")
nStatus = security.setsd(strSD)

The correct <SECURITYDESCRIPTOR> value can be retrieved directly from the WMI namespace by exporting the current security descriptor of the object, after configuring the security as wanted:

wmic /namespace:\\root\ccm  /output:sd.txt path __systemsecurity call getSD

This puts the security descriptor into a text file, where it can be fond as like “SD = { … }”. From there it can be cut and pasted into the script as a value for the strSD variable (copy the SD value without the curly brackets).

Note: The prerequisites will also be fullfilled by only implementing point 2., when the user executing the action is member of the local administratiors group.

Additional note: To programmatically run a SCCM program, which is already advertised to a client and appears already in Run Advertised Programs:

%windir%\system32\windowspowershell\v1.0\powershell.exe -Command "& {(New-Object -comobject UIResource.UIResourceMgr).ExecuteProgram('<PROGRAMNAME>', '<PACKAGEID>', 1)}"
Advertisements
This entry was posted in System Center Configuration Manager. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s