It's always a bad idea to send out a package on a Friday afternoon - and hope for the best - because the longest afternoons are usually the Friday ones, they can last several days when you need to remediate a couple of 1000 hosts where application installations got corrupted because of your Friday SCCM package. What you want, before hitting the full list of 1000s of servers with a package is to send it out to a couple and quickly see the result. However, if you send out a package it can take up to an hour to see the results in SCCM - depending on your SCCM site settings... How can you make it quicker? Invoke a client action on each host called "Machine Policy Retrieval & Evaluation Cycle".
SCCM Client Actions |
Background:
SCCM client has several agents and those can perform actions, such as downloading policies and packages from the server, perform software or hardware inventories...etc. Because all these agents are built on WMI, you can invoke actions by creating WMI instances of specific WMI classes on the remote machine.
OK, so the idea is there. When you want to break.. khm deploy something on many, many servers, you just pick about 50 or maybe 100 firts, send out the package and then... and this is where powershell comes in: run the following script to invoke the MAchine Policy Retrieval & Evaluation Cycle which will make the client download the package and run it + report back to the SCCM server.
$hostlist = @($Input)
if($($hostlist.length) -gt 0){
foreach ($srv in $hostlist) {
# Binding \\$srv\root\ccm:SMS_Client
$SMSCli = [wmiclass] "\\$srv\root\ccm:SMS_Client"
if($SMSCli){
#Invoking $actionName
$check = $SMSCli.RequestMachinePolicy()
$check = $SMSCli.EvaluateMachinePolicy()
}
else{
write-host "$srv, Could not bind WMI class SMS_Client"
}
}
}
Save it as a something.ps1 file and use it like this:
PS C:\> gc hostlist.txt | something.ps1
Clipboard friendly code:
$hostlist = @($Input)
if($($hostlist.length) -gt 0){
foreach ($srv in $hostlist) {
# Binding \\$srv\root\ccm:SMS_Client
$SMSCli = [wmiclass] "\\$srv\root\ccm:SMS_Client"
if($SMSCli){
#Invoking $actionName
$check = $SMSCli.RequestMachinePolicy()
$check = $SMSCli.EvaluateMachinePolicy()
}
else{
write-host "$srv, Could not bind WMI class SMS_Client"
}
}
}
All I get is:
ReplyDeleteCannot convert value "\\thesnypc\root\ccm:SMS_Client" to type "Syste
m.Management.ManagementClass". Error: "Access is denied. (Exception from HRESUL
T: 0x80070005 (E_ACCESSDENIED))"
At C:\temp\mpr.ps1:6 char:32
+ $SMSCli = [wmiclass] <<<< "\\$srv\root\ccm:SMS_Client"
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Regards
Thomas Ehler
the@science.au.dk
Hi Mia, that can be because of several things:
Delete- you don't have administrative access to the remote host
- WMI is broken on the remote host, you can check it by running WMIExplorer and checking if you can open the ccm namespace: http://www.powershellpro.com/wmi-explorer/160/
Access is denied -> you should use an adequate account
ReplyDeleteI liked this so much I turned it into a PowerShell cmdlet with some error checking. Code lives here https://github.com/1RedOne/SCCM-Cmdlets/, and feel free to comment or add to it.
ReplyDeletewhat cmdlet?
Deletenice one, cheers!
ReplyDeleteEveryone always assumes a One-to-many setting. If you are that deployment tech waiting for the newly imaged machine you just advertised a bunch of apps to but don't want to wait the possible 20 min, create a batch file with this:
ReplyDeleteWMIC /namespace:\\root\ccm path sms_client CALL TriggerSchedule "{00000000-0000-0000-0000-000000000021}" /NOINTERACTIVE
WMIC /namespace:\\root\ccm path sms_client CALL TriggerSchedule "{00000000-0000-0000-0000-000000000022}" /NOINTERACTIVE
Nice... can add this to my post-build script on my VM templates. Much lighter than vb.
ReplyDelete