Where-object vs WQL

No matter what you’re doing in PowerShell there are guaranteed to be at least 5 different ways to accomplish your goal.  Early on I would suggest focusing on the functionality, but after your script is working as intended.  A little time spent tuning and optimizing your various functions and loops will go a long way.   Sometimes an IF statement is faster than a switch. Likewise while vs. until vs. foreach… Take the time and try the various options.  Performance varies greatly depending on what type of object you’re working with, and what you’re doing with that object.   So far in my quest for posh speed I have found two things to be globally true:

  1. The less data you pass down the pipe line the faster your script will run.
  2. 99% of the time filtering at the source is 25%-50% faster then using select-object/where-object.

Along those lines I FINALY figured out how to do a “where not” WQL query!  Low and behold Glenn’s global laws of performance held true again…

If execution times are keeping you in the dark ages of automation.  Look no further than your own code.  I am yet to find a task where PowerShell doesn’t crush VBscript/WSH/BAT.

~Glenn

Managing required Snapins

I’m often hesitant to rely on snap-ins in my production scripts.  My fear is that a Jr Sysad will grab the script and attempt to run it.   Without the required Snap-ins the script will fail, and that failure will be “my fault”.  I solved this little problem by adding the following to any scripts that requires snap-ins.

write-Host “Loading required PSSnapins…”
# Load the PSCX if they are not already loaded…
if (!(Get-PSSnapin | ?{$_.name -eq “pscx”})){Add-PSSnapin pscx -ErrorAction Stop}

Now when the script fails I can at least point at the error, and say “what do you mean you don’t know why it’s not working, it’s right there!”

Thank you aleksandar !
Talk about doing it the hard way, all I had to do was add the “#requires” header to the first line of my scripts.

#requires -pssnapin pscx

Gotta love PowerShell every time you think you solved a problem, someone points out a feature of the parser that handles it natively!

~Glenn

-whatif, I don’t use it…

Thank you PowerShell team, thank you quest!!! 

Long story short, I tapped the up arrow one too many times.  Had I not tacked on a last second -whatif. I would have reset the password on 20,000+ user accounts.   OUCH!

Tack it on early and often!  No matter how comfortable you may be.  The truth is PowerShell is so damn powerful it must be treated with great respect, and a small amount of fear.  Mistakes here can REALY mess stuff up.  The PowerShell team gave us the tools to cover our butts, use them!

~Glenn

ConfigMgr 2007 SP1 downloading prerequisite components

Shaun Cassell does a very nice job explaining what can go wrong HERE.  One thing he doesn’t spell out is that you cannot have ANY spaces. For those of you who don’t know, when you install/upgrade ConfigMgr 2007.  The setup wizard actually has to contact MS servers to download required components.  You can do this ahead of time by running.

<path>setup.exe /download <path>

If you run the above command and nothing happens.. goto %SYSTEMDRIVE%ConfigMgrSetup.txt, if that log file contains.

<07-13-2008 10:02:24> Download folder F:SCCMUPDATES” does not exist
<07-13-2008 10:02:24> Failed to download prerequisite components (0x80070003)

Stop… you have spaces somewhere, the most sure fire way around this is to map a drive. Map a drive to the source and target destination folders.  Furthermore if you start downloading updates, and it “fails” check your destination. If any updates at all have successfully downloaded.  Start it back up, that is a network timeout.

<

p class=”headermaintitle”>Will work:
\servershareSCConfigMgr07SMSSETUPBINI386setup.exe /download c:SCCMUpdates
D:SCConfigMgr07SMSSETUPBINI386setup.exe /download c:SCCMUpdates
S:setup.exe /download T:

<

p class=”headermaintitle”>Will NOT work:
\serversome shareSCConfigMgr07SMSSETUPBINI386setup.exe /download c:SCCMUpdates
D:SCConfigMgr07SMSSETUPBINI386setup.exe /download c:SCCM Updates

OR… A little POSH goodness.  Before I figured out what was going on. I wrote this quick Powershell script to download them for me. 😉

~ Glenn

XML vs CSV

Okay, so I know what .Net is, but how was I supposed to know it was this powerful.  For anyone who has every worked with xml in VBScript… I feel your pain.  With that knowledge of the headache, that was the “Msxml2.DOMDocument” com object.  I have avoided XML like the plague.   Problem is I was completely oblivious to what “.Net support” really meant!  I have several projects at work where I use PowerShell to “interact” with REST based web services.  Not wanting to take that XML dive, I requested “PowerShell hooks”, and was obliged.

When our programmers asked me, what I wanted returned?  I told them to give me a CSV in the format of a custom PS Object.  At the time, this seemed a no brainier.  Not only do I not have to worry about WSDL/ADO/XML, but also the data would stay objectized.

It worked GREAT that was until I started to manipulate large data sets.  Then my simple system fell apart. Downloading and saving that CSV file, before I could import that data.  Was simply too much, and was drastically degrading performance.  Therefore, I asked the question on the PowerShell community forums about optimizing such a task. The response I got lead me to crack open Bruce’s PowerShell in Action.  Low and behold, where has .Net been all my life!

Posted By bsonposh on 07/06/2008 10:51 AM
Actually… the *-clixml are meant for serializing and deserializing objects. Import-cliXML expects a VERY specific format.

If you want to “import” XML you can just type it
[XML]$myxml = < some data >

That is it… Just by type casting your object with [xml] the .net framework does the rest.  Not only is it easier then my custom CSV’s but its twice as fast!

~Glenn Sizemore