Take a look at it on GitHub here: https://github.com/andrebocchini/sccm-powershell-automation-module Andre really did an awesome job on this module!
This Module for SCCM 2007 (which does not come with a set of PowerShell Cmdlets) allows you to query Computers, Collections, Advertisements etc... (Check the Full list of Cmdlets)
After inspecting the code, I tweaked some parts of the code, especially on the Get-WmiObject queries.
Those modifications are now part of the module.
Here is an example :
# In the module we have the following query # (I had Backtick to fit in my blog, don't do this at home! ;-) ) $computer = Get-WMIObject ` -ComputerName $siteProvider ` -Namespace "root\sms\site_$siteCode" ` -Class "SMS_R_System" | Where { $_.ResourceID -eq $resourceId } # Let's measure our command on a big environment (+6000 computers) # Note that I replaced some values, you need to specify the SiteProvider, SiteCode and # ResourceID. Measure-Command {Get-WMIObject` -ComputerNameIt took 42 seconds to finish this command, that's pretty long...` -Namespace "root\sms\site_ " ` -Class "SMS_R_System" | where-object { $_.ResourceID -eq }} Days : 0 Hours : 0 Minutes : 0 Seconds : 42 Milliseconds : 273 Ticks : 422735527 TotalDays : 0.000489277230324074 TotalHours : 0.0117426535277778 TotalMinutes : 0.704559211666667 TotalSeconds : 42.2735527 TotalMilliseconds : 42273.5527
Basically the command has to gather ALLLLLL the objects from the class SMS_R_System and then send it throught the pipe to Where-Object to filter on the ResourceID property.
Let's try to improve this and use some filtering!
# Let's measure our command on a big environment (+6000 computers) with some filtering # Note that I replaced some values, you need to specify the SiteProvider, SiteCode and # ResourceID. Measure-Command {Get-WMIObject` -ComputerNameWOW! This time Only 200 Milliseconds!! Pretty Awesome! Filtering is definitely the way to go! ;-)` -Namespace "root\sms\site_ " ` -Query "Select * From SMS_R_System WHERE ResourceID=' '"} Days : 0 Hours : 0 Minutes : 0 Seconds : 0 Milliseconds : 202 Ticks : 2026858 TotalDays : 2.34590046296296E-06 TotalHours : 5.63016111111111E-05 TotalMinutes : 0.00337809666666667 TotalSeconds : 0.2026858 TotalMilliseconds : 202.6858
All I did is really filtering on the ResourceID property with Get-WmiObject, I don't need to retrieve all the data.
In Powershell you should Always Always Always ALWAYSS try to filter before sending the output to the pipeline, and this apply to all the Cmdlets...
This was well resumed by the Scripting Guy, Ed Wilson [Top Ten PowerShell Best Practices]:
Filter on the left. It is more efficient to filter returning data as close to the source of data as possible. For example, you do not want to return the entire contents of the system event log across the network to your work station, and then filter events for a specific event ID. Instead, you want to filter the system event log on the server, and then return the data.
Resources
- WMI Query Language via PowerShell (+Ravikanth Chaganti +Shay Levy +Aleksandar Nikolic +Philip LaVoie and Robert Robelo) Free Ebook, If you are learning PowerShell This is a must read !! Those guys did an awesome work
- System Center Configuration Manager Software Development Kit
Thanks for Reading! If you have any questions, leave a comment or send me an email at fxcat@lazywinadmin.com. I invite you to follow me on Twitter: @lazywinadm
Hi. I've been taking a look at Andre Bocchini's automation tools and see so much potential for me. I have a question you might be able to answer. I'm using the Get-SCCMDistributionList cmdlet and passing -siteprovider & -sitecode arguments to it but it seems to only work for Primary sites as secondary sites don't have a root\sms repository. My goal is to be able to remove a package from a number of sites. I wonder can you help?
ReplyDelete