First published on TECHNET on Apr 04, 2011
Jim Truher and I have been seeing some usage of the
Get-SCSMObject cmdlet lately that will cause really bad performance when run in a production environment. Things will work fine in a dev/test environment where the quantity of data is small but as soon as you put it into a fully loaded production environment it will cause massive problems. This same kind of bad programming could be done in .NET code, but I never see it happen there. I think for some reason it is just easier to sort of not think through what is really happening when you are writing scripts with the all powerful pipe in PowerShell.
The bad part here is that Get-SCSMObject in this case is going to get
incident in the database and bring it back to the management server (or wherever this command is being run). Then Where-Object is going to loop through all of those comparing the Status property to see if it is Resolved. This works great on a dev or test system that just has a few incidents in it. In a production system with 150,000 incidents, this is going to be
slow and make the processor work very hard on the management server.
This really should be done by leveraging the power of SQL Server to just get the incidents we care about. There is a –Filter parameter on the Get-SCSMObject cmdlet that can be used for these purposes. Rewriting the above using –Filter would look like this:
$cString = "Status != '$CId' and Status != '$RId' and TargetResolutionTime < '$Now' and TargetResolutionTime Is Not Null"
$crit = new-object $cType $cString,$Class
Get-SCSMObject -criteria $crit
That’s a little harder than we would like it to be though so Jim is working on an improvement to the –Filter for SMLets that will allow you to specify more advanced filter criteria something like this: