Finding success with SCCM – trigger Schedule


If you’ve ever dealt with SCCM you’ll understand to get a client to forcibly download patches / software from SCCM you’ll need to call WMI to trigger a schedule.

The list of triggers can be found here. Trigger schedule

This post is about how to find / determine success for one of the triggers in this list:

To start with I chose to create a hashTable to hold the triggers with a name:


function New-CMSccmTriggerHashTable
{
    $Sccmhash =@{HardwareInventoryCollectionTask='{00000000-0000-0000-0000-000000000001}'
		SoftwareInventoryCollectionTask='{00000000-0000-0000-0000-000000000002}'
		HeartbeatDiscoveryCycle='{00000000-0000-0000-0000-000000000003}'
		SoftwareInventoryFileCollectionTask='{00000000-0000-0000-0000-000000000010}'
		RequestMachinePolicyAssignments='{00000000-0000-0000-0000-000000000021}'
		EvaluateMachinePolicyAssignments='{00000000-0000-0000-0000-000000000022}'
		RefreshDefaultMPTask='{00000000-0000-0000-0000-000000000023}'
		RefreshLocationServicesTask='{00000000-0000-0000-0000-000000000024}'
		LocationServicesCleanupTask='{00000000-0000-0000-0000-000000000025}'
		SoftwareMeteringReportCycle='{00000000-0000-0000-0000-000000000031}'
		SourceUpdateManageUpdateCycle='{00000000-0000-0000-0000-000000000032}'
		PolicyAgentCleanupCycle='{00000000-0000-0000-0000-000000000040}'
		CertificateMaintenanceCycle='{00000000-0000-0000-0000-000000000051}'
		PeerDistributionPointStatusTask='{00000000-0000-0000-0000-000000000061}'
		PeerDistributionPointProvisioningStatusTask='{00000000-0000-0000-0000-000000000062}'
		ComplianceIntervalEnforcement='{00000000-0000-0000-0000-000000000071}'
		SoftwareUpdatesAgentAssignmentEvaluationCycle='{00000000-0000-0000-0000-000000000108}'
		SendUnsentStateMessages='{00000000-0000-0000-0000-000000000111}'
		StateMessageManagerTask='{00000000-0000-0000-0000-000000000112}'
		ForceUpdateScan='{00000000-0000-0000-0000-000000000113}'
		AMTProvisionCycle='{00000000-0000-0000-0000-000000000120}'}
    $Sccmhash
}

Now any of triggers can be accounted for with this hashtable.


$sccmHash = New-CMSccmTriggerHashTable
$sccmHash['RequestMachinePolicyAssignments']
{00000000-0000-0000-0000-000000000021}

With a human readable form for the trigger a  function to Invoke the schedule for the trigger can be constructed:

function Invoke-CMRequestMachinePolicyAssignments
{
    param([Parameter(Mandatory=$true)]$computername, 
    [Parameter(Mandatory=$true)]$Path = 'c:\windows\ccm\logs',
            [pscredential]$credential)
    $Sccmhash = New-CMSccmTriggerHashTable
    if(Test-CCMLocalMachine $computername)
    {
        $TimeReference =(get-date)
    }
    else
    {
        $TimeReference = invoke-command -ComputerName $computername `
        -scriptblock {get-date} -credential $credential
    }
    if($credentials)
    {
        Invoke-WmiMethod -Class sms_client -Namespace 'root\ccm' 
       ​-ComputerName $computername -credential $credential 
      ​-Name TriggerSchedule 
      ​-ArgumentList "$($Sccmhash["RequestMachinePolicyAssignments"])" 
    }
    else
    {
        $SmsClient =[wmiclass]("\\$ComputerName\ROOT\ccm:SMS_Client")
        $SmsClient.TriggerSchedule`
        ($Sccmhash["RequestMachinePolicyAssignments"])
    }
    $RequestMachinePolicyAssignments = $false

    # can see when this is requested from the Policy agentlog:
    $RequestMachinePolicyAssignments = Test-CMRequestMachinePolicyAssignments`
     -computername $computername -Path $Path -TimeReference $TimeReference `
     -credential $credential

    [PSCustomObject]@{'RequestMachinePolicyAssignments' = $RequestMachinePolicyAssignments
                      'TimeReference' = ($TimeReference)}
}

Once the Request Machine Policy Assignments is triggered.  Another function is called.  This is where a search through the client logs determine success of the trigger invocation.

The value that determines success is Evaluation not required. No changes detected. Which can be found in the PolicyEvaluator.log

In order to find this value we first need to find out if the computer name that was passed is a local machine or a remote machine. This is done with the function Test-CCMLocalMachine. This function is used in both the invoke and the test to determine if excution is on the local machine or a remote machine.  To make sure when searching the log a $TimeReference is used. If it is passed in one of the parameters then that value is used to search through the log.  If it is not passed  the current time from the remote or local machine will be used.


function Test-CMRequestMachinePolicyAssignments
{
    param([Parameter(Mandatory=$true)]$computername, 
    [Parameter(Mandatory=$true)]$Path = 'c:\windows\ccm\logs'
    ,[datetime]$TimeReference,
    [pscredential] $credential)
    if ($TimeReference -eq $null)
    {
        if(Test-CCMLocalMachine $computername)
        {
            $TimeReference =(get-date)
        }
        else
        {
            [datetime]$TimeReference = invoke-command 
            ​-ComputerName $computername -scriptblock {get-date}
        }
    }
    $RequestMachinePolicyAssignments = $false
    # can see when this is requested from the Policy agentlog:
    Push-Location
    Set-Location c:
    if(Test-CCMLocalMachine $computername)
    {
        $p = Get-CMLog -path "$path\policyevaluator.log"
        $runResults = $P |Where-Object{$_.Localtime -gt $TimeReference} `
       | where-object {$_.message -like `
         "*Evaluation not required. No changes detected.*"}
    }
    else
    {
        $p = Get-CCMLog -ComputerName $computerName -path $Path -log policyevaluator -credential $credential
        $runResults = $P.policyevaluatorLog |Where-Object{$_.Localtime -gt $TimeReference} | where-object {$_.message -like "*Evaluation not required. No changes detected.*"}
    }
    Pop-Location
    #if in the 

        if($runResults)
        {
            $RequestMachinePolicyAssignments = $true
        }
    $RequestMachinePolicyAssignments
}

Finding this value in the PolicyEvaluator.log can take up to 45 minutes or more depending on the setup of your SCCM environment.

To allow for finding the value described above and two other triggers. The following script demonstrates its usage:

GetAvailUpdates.ps1

All of the functions shown above can be found in this github repository:

SCCMUtilities

 

I hope this helps someone

Until then

 

Keep Scripting

 

thom

Advertisement

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