Triggering ConfigMgr Client Actions from a Task Sequence

This week, we were working on testing Windows 7 to Windows 10 In-Place Upgrades and ran into an issue where our clients weren’t updating their Operating System version in the ConfigMgr console. After some helpful responses on Twitter, I was able to add a client action trigger step to the end of my Task Sequence. In my production environment, we have a child task sequence that we call that has several client action steps in it including Request Machine Assignments (Machine Policies) {00000000-0000-0000-0000-000000000021}, Hardware Inventory {00000000-0000-0000-0000-000000000001} and now a Discovery Inventory {00000000-0000-0000-0000-000000000003}.

The idea behind this Task Sequence is to create a Run Command Line step for each of the ConfigMgr client schedule IDs. From there, the sky’s the limit. It just seemed like a great way to just get them all into one place for easy access. You can add it to your Task Sequence as a child Task Sequence or even advertise it as a standalone Task Sequence for newly imaged devices. Additionally, if you want to know what each item does or which logs to look into, just Google it. That’s what I did! 🙂

Some people may ask why not just put all of the actions I want into a script. Because I don’t want to. There are scripts out there that do this same thing in Powershell, but I wanted steps that would be easy for anyone to enable/disable without having to dig into a separate script to debug or change things.

Just use caution. Test! Test! Test!

DISCLAIMER

Use with caution and test in your lab first. Also, I have not tested all of these actions. Some of them may be deprecated. The list came from here

Script to Create Task Sequence

I stole the base code for this from Johan Arwidmark’s (@jarwidmark) Creating Task Sequences in ConfigMgr via PowerShell blog post. The script is simple. Customize it as you see fit. It creates a list of actions that get added to an Enabled and Disabled group in a new Task Sequence. The Disabled Group is set to Disabled in the Task Sequence, but each item below it is not, can move steps in and out of the groups in your TS easily once you’ve created the Task Sequence.

A Square Dozen Image

You will need to connect to your ConfigMgr site to run this. The easiest way to do that is to open the ConfigMgr Console and click the upper left corner menu. Select Connect vis Windows PowerShell ISE. Then run the script that pops up. Don’t edit that script! Once in ISE, copy the following code into a new window, customize it and run it.

 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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
$ClientActions = @()

#number of seconds the script will sleep before triggering the next action. This gets set on each commandline.
#Set to 0 to skip sleep.
$SleepInSeconds = 120

#Comment Out any client actions that you don't want to add to your TS.

#Move actions here that will be added to the Enabled Client Actions group.
$EnabledActions = @()
$EnabledActions += [pscustomobject]@{ ActionName =  'Request Machine Assignments'; ActionID = '{00000000-0000-0000-0000-000000000021}' }
$EnabledActions += [pscustomobject]@{ ActionName =  'Hardware Inventory'; ActionID = '{00000000-0000-0000-0000-000000000001}' }
$EnabledActions += [pscustomobject]@{ ActionName =  'Discovery Inventory'; ActionID = '{00000000-0000-0000-0000-000000000003}' }

#Move actions here that will be added to the Disabled Client Actions group.
#These are simply added to the TS so that they are available if you need them.
#You can comment out the ProcessActions step at the end of the script if you would like to exclude these altogether.
$DisabledActions = @()
$DisabledActions += [pscustomobject]@{ ActionName =  'Software Inventory'; ActionID = '{00000000-0000-0000-0000-000000000002}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'File Collection'; ActionID = '{00000000-0000-0000-0000-000000000010}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'IDMIF Collection'; ActionID = '{00000000-0000-0000-0000-000000000011}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Client Machine Authentication'; ActionID = '{00000000-0000-0000-0000-000000000012}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Evaluate Machine Policies'; ActionID = '{00000000-0000-0000-0000-000000000022}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Refresh Default MP Task'; ActionID = '{00000000-0000-0000-0000-000000000023}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'LS (Location Service) Refresh Locations Task'; ActionID = '{00000000-0000-0000-0000-000000000024}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'LS (Location Service) Timeout Refresh Task'; ActionID = '{00000000-0000-0000-0000-000000000025}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Policy Agent Request Assignment (User)'; ActionID = '{00000000-0000-0000-0000-000000000026}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Policy Agent Evaluate Assignment (User)'; ActionID = '{00000000-0000-0000-0000-000000000027}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Software Metering Generating Usage Report'; ActionID = '{00000000-0000-0000-0000-000000000031}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Source Update Message'; ActionID = '{00000000-0000-0000-0000-000000000032}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Clearing proxy settings cache'; ActionID = '{00000000-0000-0000-0000-000000000037}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Machine Policy Agent Cleanup'; ActionID = '{00000000-0000-0000-0000-000000000040}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'User Policy Agent Cleanup'; ActionID = '{00000000-0000-0000-0000-000000000041}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Policy Agent Validate Machine Policy / Assignment'; ActionID = '{00000000-0000-0000-0000-000000000042}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Policy Agent Validate User Policy / Assignment'; ActionID = '{00000000-0000-0000-0000-000000000043}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Retrying/Refreshing certificates in AD on MP'; ActionID = '{00000000-0000-0000-0000-000000000051}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Peer DP Status reporting'; ActionID = '{00000000-0000-0000-0000-000000000061}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Peer DP Pending package check schedule'; ActionID = '{00000000-0000-0000-0000-000000000062}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'SUM Updates install schedule'; ActionID = '{00000000-0000-0000-0000-000000000063}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'NAP action'; ActionID = '{00000000-0000-0000-0000-000000000071}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Hardware Inventory Collection Cycle'; ActionID = '{00000000-0000-0000-0000-000000000101}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Software Inventory Collection Cycle'; ActionID = '{00000000-0000-0000-0000-000000000102}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Discovery Data Collection Cycle'; ActionID = '{00000000-0000-0000-0000-000000000103}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'File Collection Cycle'; ActionID = '{00000000-0000-0000-0000-000000000104}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'IDMIF Collection Cycle'; ActionID = '{00000000-0000-0000-0000-000000000105}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Software Metering Usage Report Cycle'; ActionID = '{00000000-0000-0000-0000-000000000106}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Windows Installer Source List Update Cycle'; ActionID = '{00000000-0000-0000-0000-000000000107}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Software Updates Assignments Evaluation Cycle'; ActionID = '{00000000-0000-0000-0000-000000000108}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Branch Distribution Point Maintenance Task'; ActionID = '{00000000-0000-0000-0000-000000000109}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'DCM policy'; ActionID = '{00000000-0000-0000-0000-000000000110}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Send Unsent State Message'; ActionID = '{00000000-0000-0000-0000-000000000111}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'State System policy cache cleanout'; ActionID = '{00000000-0000-0000-0000-000000000112}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Scan by Update Source'; ActionID = '{00000000-0000-0000-0000-000000000113}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Update Store Policy'; ActionID = '{00000000-0000-0000-0000-000000000114}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'State system policy bulk send high'; ActionID = '{00000000-0000-0000-0000-000000000115}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'State system policy bulk send low'; ActionID = '{00000000-0000-0000-0000-000000000116}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'AMT Status Check Policy'; ActionID = '{00000000-0000-0000-0000-000000000120}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Application manager policy action'; ActionID = '{00000000-0000-0000-0000-000000000121}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Application manager user policy action'; ActionID = '{00000000-0000-0000-0000-000000000122}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Application manager global evaluation action'; ActionID = '{00000000-0000-0000-0000-000000000123}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Power management start summarizer'; ActionID = '{00000000-0000-0000-0000-000000000131}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Endpoint deployment reevaluate'; ActionID = '{00000000-0000-0000-0000-000000000221}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'Endpoint AM policy reevaluate'; ActionID = '{00000000-0000-0000-0000-000000000222}' }
$DisabledActions += [pscustomobject]@{ ActionName =  'External event detection'; ActionID = '{00000000-0000-0000-0000-000000000223}' }

$TS = New-CMTaskSequence -CustomTaskSequence -Name "Run ConfigMgr Client Actions"
 
$EnabledGroup = New-CMTaskSequenceGroup -Name "Enabled Client Actions"
Add-CMTaskSequenceStep -InsertStepStartIndex 0 -TaskSequenceName $TS.Name -Step $EnabledGroup

$DisabledGroup = New-CMTaskSequenceGroup -Name "Disabled Client Actions" -Disable
Add-CMTaskSequenceStep -InsertStepStartIndex 1 -TaskSequenceName $TS.Name -Step $DisabledGroup

Function ProcessActions ($ClientActions, $Group)
{
    Foreach ($Action in $ClientActions)
    {
        #Format the sleep command for appending
        $Sleep = If($SleepInSeconds -gt 0) {";Start-Sleep -seconds $($SleepInSeconds);"} else {$Sleep = ''}

        #Format TS CommandLine
        $cmdLine = [string]::Format("%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -Command `"Invoke-WmiMethod -Namespace root\CCM -Class SMS_Client -Name TriggerSchedule '{0}'{1}`"",$Action.ActionID, $Sleep)
        Write-Host $cmdLine

        #Create TS Step
        $Step = New-CMTaskSequenceStepRunCommandLine -StepName "$($Action.ActionName)" -CommandLine "$($cmdLine)" -ContinueOnError

        #Append Step to group
        Set-CMTaskSequenceGroup -TaskSequenceName $TS.Name -StepName $Group.Name -AddStep $Step
    }
}

ProcessActions $EnabledActions $EnabledGroup
ProcessActions $DisabledActions $DisabledGroup

Results

Once you have run the script, you should end up with a Task Sequence like this:

A Square Dozen Image

A Square Dozen Image

And entries like this:

You should see entries in your smsts.log like this. Each step has Continue On Error turned on, so you will want to look at the logs to see if the steps are actually working.

A Square Dozen Image

 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
Expand a string: WinPEandFullOS    TSManager   6/14/2018 10:31:22 PM   8664 (0x21D8)
Executing command line: smsswd.exe /run: %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -Command "Invoke-WmiMethod -Namespace root\CCM -Class SMS_Client -Name TriggerSchedule '{00000000-0000-0000-0000-000000000021}';sleep -seconds 120;"    TSManager   6/14/2018 10:31:22 PM   8664 (0x21D8)
[ smsswd.exe ]  InstallSoftware 6/14/2018 10:31:22 PM   9480 (0x2508)
PackageID = ''  InstallSoftware 6/14/2018 10:31:22 PM   9480 (0x2508)
BaseVar = '', ContinueOnError=''    InstallSoftware 6/14/2018 10:31:22 PM   9480 (0x2508)
ProgramName = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -Command "Invoke-WmiMethod -Namespace root\CCM -Class SMS_Client -Name TriggerSchedule '{00000000-0000-0000-0000-000000000021}';sleep -seconds 120;"'   InstallSoftware 6/14/2018 10:31:22 PM   9480 (0x2508)
SwdAction = '0001'  InstallSoftware 6/14/2018 10:31:22 PM   9480 (0x2508)
Command line for extension .exe is "%1" %*  InstallSoftware 6/14/2018 10:31:22 PM   9480 (0x2508)
Set command line: Run command line  InstallSoftware 6/14/2018 10:31:22 PM   9480 (0x2508)
Working dir 'not set'   InstallSoftware 6/14/2018 10:31:22 PM   9480 (0x2508)
Executing command line: Run command line    InstallSoftware 6/14/2018 10:31:22 PM   9480 (0x2508)
InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
__GENUS          : 1    InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
__CLASS          : __PARAMETERS InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
__SUPERCLASS     :  InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
__DYNASTY        : __PARAMETERS InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
__RELPATH        : __PARAMETERS InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
__PROPERTY_COUNT : 1    InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
__DERIVATION     : {}   InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
__SERVER         : WS01 InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
__NAMESPACE      : ROOT\ccm InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
__PATH           : \\WS01\ROOT\ccm:__PARAMETERS InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
ReturnValue      :  InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)
PSComputerName   : WS01 InstallSoftware 6/14/2018 10:31:25 PM   9480 (0x2508)

Update 6/15/2018

I submitted a PR on GitHub to add all of the schedule codes to the SDK and it got MERGED!

https://github.com/MicrosoftDocs/SCCMdocs/pull/604#event-1683727219 https://docs.microsoft.com/sccm/develop/reference/core/clients/client-classes/triggerschedule-method-in-class-sms_client