Run ConfigMgr Client Cycle Actions on Multiple Clients with PowerShell

Not a script that hasn’t been done before, but this is my version which allows pipeline input of the computer name so that you can run one of the ConfigMgr Client Cycle actions on multiple computers, or include it as a function in a script etc.

The following actions are supported and are equivalent to running a cycle from the ‘Actions’ tab of the ConfigMgr Client Control Panel:

Application Deployment Evaluation Cycle
Discovery Data Collection Cycle
File Collection Cycle
Hardware Inventory Cycle
Machine Policy Retrieval and Evaluation Cycle
Software Inventory Cycle
Software Metering Usage Report Cycle
Software Updates Deployment Evaluation Cycle
Software Updates Scan Cycle
User Policy Retrieval and Evaluation Cycle
Windows Installer Source List Update Cycle

Some examples:

Invoke-CMClientCycle -ComputerName PC001 -Cycle Application_Deployment_Evaluation

Triggers the “Application Deployment Evaluation Cycle” on PC001 and only returns output for errors.

Get-ADComputer -filter * -searchbase "OU=Desktops,OU=England,OU=Computers,OU=United Kingdom,dc=contoso,dc=com" |
Sort Name |
Select -ExpandProperty Name |
Invoke-CMClientCycle -Cycle Machine_Policy_Retrieval_and_Evaluation -Verbose

Gets the list of desktops in the England OU and triggers the “Machine Policy Retrieval and Evaluation cycle” on each machine. Verbose output details each machine where the action
was triggered.

(Get-ADComputer -filter * -searchbase "OU=Desktops,OU=England,OU=Computers,OU=United Kingdom,dc=contoso,dc=com" |
Sort Name |
Select -ExpandProperty Name).ForEach({Invoke-CMClientCycle -ComputerName $PSItem -Cycle Machine_Policy_Retrieval_and_Evaluation -Verbose})

Gets the list of desktops in the England OU and triggers the “Machine Policy Retrieval and Evaluation cycle” on each machine. Verbose output details each machine where the action
was triggered. Uses the ‘ForEach’ method in PowerShell 4.0.

The Script


<#

.SYNOPSIS
    Triggers a ConfigMgr Client Cycle Action on a remote computer

.DESCRIPTION
    Triggers a ConfigMgr Client cycle action on a remote computer. Accepts pipeline input for computer name so can be run against many machines or in a script.

.PARAMETER ComputerName
    The name of the target computer

.PARAMETER Cycle
    The cycle to run.  Choose from the list.

.EXAMPLE
    Invoke-CMClientCycle -ComputerName PC001 -Cycle Application_Deployment_Evaluation

    Triggers the "Application Deployment Evaluation Cycle" on PC001 and only returns output for errors.

.EXAMPLE
    Get-ADComputer -filter * -searchbase "OU=Desktops,OU=England,OU=Computers,OU=United Kingdom,dc=contoso,dc=com" | 
        Sort Name | 
        Select -ExpandProperty Name | 
        Invoke-CMClientCycle -Cycle Machine_Policy_Retrieval_and_Evaluation -Verbose

    Gets the list of desktops in the England OU and triggers the "Machine Policy Retrieval and Evaluation cycle" on each machine.  Verbose output details each machine where the action 
    was triggered.

.EXAMPLE
    (Get-ADComputer -filter * -searchbase "OU=Desktops,OU=England,OU=Computers,OU=United Kingdom,dc=contoso,dc=com" | 
        Sort Name | 
        Select -ExpandProperty Name).ForEach({Invoke-CMClientCycle -ComputerName $PSItem -Cycle Machine_Policy_Retrieval_and_Evaluation -Verbose})

    Gets the list of desktops in the England OU and triggers the "Machine Policy Retrieval and Evaluation cycle" on each machine.  Verbose output details each machine where the action 
    was triggered.  Uses the 'ForEach' method in PowerShell 4.0.

.NOTES
    Cmdlet name: Invoke-CMClientCycle
    Author:      Trevor Jones
    Contact:     @trevor_smsagent
    DateCreated: 2015-05-26
    Link:        https://smsagent.wordpress.com

#>


[CmdletBinding(SupportsShouldProcess=$True)]
    param
        (
        [Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True, HelpMessage="The target computer name")]
            [ValidateScript({if(!(Test-Connection -Quiet -Count 2 -ComputerName $PSItem)) {Write-warning "$psItem is not contactable.  A validation error will be returned."} else{$true}})]
            [string[]]$ComputerName,
        [Parameter(Mandatory=$True)]
            [ValidateSet("Application_Deployment_Evaluation",
                "Discovery_Data_Collection",
                "File_Collection",
                "Hardware_Inventory",
                "Machine_Policy_Retrieval_and_Evaluation",
                "Software_Inventory",
                "Software_Metering_Usage_Report",
                "Software_Updates_Deployment_Evaluation",
                "Software_Updates_Scan",
                "User_Policy_Retrieval_and_Evaluation",
                "Windows_Installer_Source_List_Update")]
            [string]$Cycle
        )


# Set variables based on choice
if ($cycle -eq "Application_Deployment_Evaluation")
    {
        $strAction = "{00000000-0000-0000-0000-000000000121}"
        $actionDesc = "Application Deployment Evaluation Cycle"
    }
if ($cycle -eq "Discovery_Data_Collection")
    {
        $strAction = "{00000000-0000-0000-0000-000000000003}"
        $actionDesc = "Discovery Data Collection Cycle"
    }
if ($cycle -eq "File_Collection")
    {
        $strAction = "{00000000-0000-0000-0000-000000000104}"
        $actionDesc = "File Collection Cycle"
    }
if ($cycle -eq "Hardware_Inventory")
    {
        $strAction = "{00000000-0000-0000-0000-000000000001}"
        $actionDesc = "Hardware Inventory Cycle"
    }
if ($cycle -eq "Machine_Policy_Retrieval_and_Evaluation")
    {
        $strAction = "{00000000-0000-0000-0000-000000000021}"
        $actionDesc = "Machine Policy Retrieval and Evaluation Cycle"
    }
if ($cycle -eq "Software_Inventory")
    {
        $strAction = "{00000000-0000-0000-0000-000000000002}"
        $actionDesc = "Software Inventory Cycle"
    }
if ($cycle -eq "Software_Metering_Usage_Report")
    {
        $strAction = "{00000000-0000-0000-0000-000000000031}"
        $actionDesc = "Software Metering Usage Report Cycle"
    }
if ($cycle -eq "Software_Updates_Deployment_Evaluation")
    {
        $strAction = "{00000000-0000-0000-0000-000000000108}"
        $actionDesc = "Software Updates Deployment Evaluation Cycle"
    }
if ($cycle -eq "Software_Updates_Scan")
    {
        $strAction = "{00000000-0000-0000-0000-000000000113}"
        $actionDesc = "Software Updates Scan Cycle"
    }
if ($cycle -eq "User_Policy_Retrieval_and_Evaluation")
    {
        $strAction = "{00000000-0000-0000-0000-000000000026}"
        $actionDesc = "User Policy Retrieval & Evaluation Cycle"
    }
if ($cycle -eq "Windows_Installer_Source_List_Update")
    {
        $strAction = "{00000000-0000-0000-0000-000000000032}"
        $actionDesc = "Windows Installer Source List Update Cycle"
    }

if ($cycle -eq "User_Policy_Retrieval_and_Evaluation")
    {
        # Get UserSID
            try
                {
                    Write-verbose "Triggering the $actionDesc on $ComputerName"
                    $userSID = (get-wmiobject -computerName $ComputerName -query "SELECT UserSID FROM CCM_UserLogonEvents WHERE LogoffTime = NULL" -namespace "ROOT\ccm" -ErrorAction Stop).UserSID
                    $userSID = $userSID.Replace("-","_")
                }
            catch {write-host "$ComputerName`: $_" -ForegroundColor Red}

        # Change User Policy request trigger to 1 minute (temporarily)
            try
                {
                    $a = Get-WmiObject -ComputerName $ComputerName -Namespace "root\ccm\Policy\$userSID\ActualConfig" -Class CCM_Scheduler_ScheduledMessage -ErrorAction Stop | Where-Object {$_.ScheduledMessageID -eq "{00000000-0000-0000-0000-000000000026}"}
                    Set-WmiInstance -Path $a -Arguments @{Triggers=@("SimpleInterval;Minutes=1;MaxRandomDelayMinutes=0")} -Verbose -ErrorAction Stop | Out-Null
                    $a.Put() | Out-Null
                }
            catch {write-host "$ComputerName`: $_" -ForegroundColor Red}
    }
Else
    {
        # Trigger the action
            try
                {
                    Write-verbose "Triggering the $actionDesc on $ComputerName"
                    Invoke-WmiMethod -ComputerName $ComputerName -Namespace root\ccm -Class SMS_Client -Name TriggerSchedule -ArgumentList $strAction -ErrorAction Stop | Out-Null
                }
            catch {write-host "$ComputerName`: $_" -ForegroundColor Red}
    }

2 thoughts on “Run ConfigMgr Client Cycle Actions on Multiple Clients with PowerShell

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 )

Facebook photo

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

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.