2013 Scripting Games Event 3

As much as I like feedback on my Scripting Games entries, I still see voters using the BOFH mode.

I’m sure my entry http://scriptinggames.org/entrylist.php?entryid=729 shouldn’t be rated with 1 star according to the scoring guidelines that you absolutely need to read before voting.

Really, you’d fire me? Did I fail?
I think you should see what it looks like as sometimes a picture is worth a thousand words:

First I’ve had a look at the built-in cmdlet Get-Volume that comes with the Storage module in Windows 8 / Windows 2012 and that has already a pretty output in the console:

But, this cmdlet cannot target older version of Windows because it queries a WMI namespace and class that only exists on Windows 8 based operating systems.

Get-Content Function:\Get-Volume

This cmdlet is great but not appropriate for the scenario.

Then, I started the traditional way. I created a header, added some HTML data…

$HTMLheader = @"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">


There’s nothing wrong with this approach. It will work but it’s a bit cumbersome.

Then I remembered that Don Jones wrote a free ebook named “Creating HTML Reports in PowerShell” that you can download on this page: http://powershell.org/wp/newsletter/

I’ve just copied and used the awsome function he wrote. He already did the hard work, why would I reinvent the wheel? 😎

The only thing I changed is the colors in the report. I extracted the blue colors from Excel with MSPaint and translated RGB colors to Hexadecimal with this website: http://www.rgbtohex.net/hextorgb/

I also didnt’ know how to create an horizontal bar in HTML. I googled the “horizontal bar Html” keywords and found the answer on this page: http://www.w3schools.com/tags/tag_hr.asp

Mike F Robbins won the Advanced Event2 2nd with this entry http://scriptinggames.org/entrylist_.php?entryid=552 where he demonstrated how to use the CIM (Common Information Model) to query computers over the WSMAN protocol or failing over DCOM for older versions of Windows.

I liked his approach but I also like sometimes a very straightforward approach because it would make a difference, a boost on performance when you query thousands of computers/servers.
I’ve seen many entries that use first the Test-Connection cmdlet before using the Get-WmiObject cmdlet to retrieve data from remote computers. They actually probably don’t realize that Test-Connection uses WMI behind the scene. It even has a -Credential parameter. Here’s what the NOTES in the help of the Test-Connection cmdlet say:
. The more WMI classes you query, the longer it will last.

You may wonder why I remove Credentials when creating a CIM session over WSMAN that targets the localhost. It isn’t really required. Well, I just remove them because my vanilla Windows 8 computer has WinRM turned off by default 😦

So, my PROCESS block has 2 parts. I first try to establish a CIM session over WSMAN with the remote computer and then failover DCOM if WSMAN doesn’t work. I collect all the successfully opened CIM sessions into an array. When writing this code I wondered whether CIM sessions are throttled like PSSessions. The Get-Volume cmdlet has a -ThrottleLimit parameter whereas the New-CIMSession and New-CimSessionOption cmdlets don’t.

In the second part of the PROCESS block, I query the Win32_Volume WMI class using the -Filter parameter of the Get-CIMinstance cmdlet.
Why Win32_Volume ? Well, it’s more exhaustive than Win32_LogicalDisk. The Win32_Volume WMI class will list the system reserved partition, a NTFS hidden volume (see above image of the HTML report). It will also list local disks that have been mounted (mountpoints, in other words) as well as mounted VHD drives. My C: drive is actually a VHD located on the F: drive. Boe Prox wrote a nice blog post on mountpoints that you can find here.

The other “cool” thing in this second part is that I’m using some of the properties of the CIM session object to display the target computer name (the one passed as parameter to the function) and the protocol being used to communicate with the remote computer.

I also extracted the real NetBIOS name of the computer from the CIM data retreived that the person who rated my script with one star didn’t notice or understand 😦 I forgive you, I’m using some of the new Powershell Version 3.0 syntax enhancements πŸ˜€

$NetBiosName = $CimData.SystemName | Select-Object -Unique

Mike uses the following classic code to achieve the same thing from WMI data:

$MachineName = $DiskSpace | Select-Object -ExpandProperty SystemName -Unique

See his approach for Event3: http://mikefrobbins.com/2013/05/16/2013-powershell-scripting-games-advanced-event-3-bringing-bad-habits-from-the-gui-to-powershell/


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 )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s