Winter Scripting Games 2014: Practice event…my way

The practice event named Server Inventory is now over and the submitted entries will be judged by very experienced Powershell pratitioners: Don Jones, Jason Helmick, Jeffery Hicks, Ed Wilson and Richard Siddaway.

There are always multiple ways to solve a problem and here’s my way 😀
This event could be written as a script (vs. a module or a function). I’ve decided to write it for Windows 2012 or Windows 8 or above platforms.

It may not be very explicit in the first requires statements but the DnsClient module is available on Windows 8 or above and the ActiveDirectory module is available if you install RSAT on a Windows 8 or if you enable the feature on the Windows server.

Add-WindowsFeature -Name RSAT-AD-PowerShell -Restart:$false

As it’s a script, the execution policy should also be modified so that it allows running scripts.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

I didn’t add the #Requires -RunAsAdministrator but I validated administrator privileges in the Begin block like this:

using what I previously did in this post.

As I see the event, it could be split into 3 parts.

  1. The network part
  2. I’m not the network guy and I don’t like to reinvent the wheel, so I borrowed two functions from Powershell MVP Dr. Tobias Weltner and Carlos Perez:

    I’ve added a comment based help and some strong parameter validation.

    Now that I could return an array of IP addresses from the subnet submitted in a CIDR notation, I created a workflow to get the name of computer from its IP Address and its operating system version.

    I’ve used the new cmdlet Resolve-DnsName that can be found in the DnsClient module. I’ve also used the ActiveDirectory that store the operating system version as soon as I had the computername.

    As you can see, I’ve chosen to test the Powershell remoting of each server with the Test-WSMan cmdlet because my inventory method is based on remoting. That also means that a recent version of Powershell is installed on each server and the the remoting is configured appropriately. In my case, the default TCP port 5985 would be used and should be also allowed in firewall incoming rules…

    To extract the operating system build from AD in a more standard way, I’ve used a regular expression and the following link help me to write it.

    I did this because you can guess the service pack from the build number as of Windows Vista.
    The main process block in my script is that short:

    I’ve used the following resource to implement it: a must read.

    In the end block of the script, I exported the active and inactive IP Addresses in CSV format like this:

  3. The inventory part
  4. There are many ways to gather the inventory data. I’ve tried to show some of them depending on the target operating system and its version of powershell. I’ve chosen to use fan-out remoting capability provided by the Invoke-Command cmdlet combined with its ability to use jobs.

    Last year, I discovered what the server manager was doing behind the scene and used this technique to gather data on Windows 2012 servers. To query whether Exchange, SharePoint, SQL or IIS were installed, I used the services way.

    Another more classic way to gather inventory data on recent Windows Server editions is the following:

    Another way to know if SQL, IIS and SharePoint are installed consists in loading their snap-in except for Exchange (I couldn’t find a common denominator)

    And there’s also the registry way:

    To query when the last hotfix was installed, the most reliable way isn’t through the WMI Win32_QuickFixEngineering class or the Get-Hotfix cmdlet but with the Microsoft Update comobject like this:

    (New-Object -ComObject Microsoft.Update.Session).            
    QueryHistory(0,1) |            
     Select -ExpandProperty Date

    And for fun there’s another way to gather inventory data, with systeminfo.exe. Either you convert its output to CSV (see this Power Tips) or using a regular expression (I used this in Scripting Games 2012):

    Instead of waiting for jobs to complete without displaying progress this way:

    Get-Job | Where Name -match 'InvScan_' |             
     Wait-Job -Timeout -1 | Out-Null

    … I did the following to display some progress:

    While (Get-Job | Where Name -match 'InvScan_' | Where State -eq 'Running') {            
     $Total = (Get-Job | Where Name -match 'InvScan_') ;            
     $completed = (Get-Job | Where Name -match 'InvScan_' | Where State -eq 'Completed') ;            
     $WPHT = @{            
        Activity = 'Waiting for scan inventory to complete' ;            
        Status = ('{0} over {1}' -f $Completed.Count,$Total.Count) ;            
        PercentComplete = (($Completed.Count)/($Total.Count)*100) ;            
     Write-Progress @WPHT            
     Start-Sleep -Seconds 1            
  5. the visualisation part
  6. I didn’t want to install Office on a server just to be able to create the powerpoint presentation. I created a parameter switch dedicated for this part. So, on a Windows 8 or 8.1 workstation with at least Office 2010 installed, using the switch would just read the results of the inventory saved in a share and create the slides.

    To create charts, I thought it would be easier to save the chart as an image rather than creating data in Excel and then create the chart in Powerpoint linked to it.

    I found the following article about charting with PowerShell that helped me build the images and create my ConvertTo-Pie function. To create the second function New-PPTXFile, I found the inspiration in the following code posted by JayKul on

    My powerpoint presentation has 2 slides that look like this:

I’ve uploaded my solution for the practice event as a public gist available on this link
It’s probably not perfect but I had fun and learned many things 😀
As I write these last lines, the first event of the Winter Scripting Games has already been published, so, it’s your turn now.

Game plan for high performing team

I’ve borrowed both the title of this post and the following picture from Don Carew, Eunice Parisi-Carew and Ken Blanchard to illustrate what your team will go through for each event of the Winter Scripting Games.

Note: I’ll use italics whenever I quote the above authors or someone else.
(TDS = Team Development Stage)

There are two key variables. Productivity is the team’s ability to work together and achieve results. Morale is the team’s motivation, confidence and cohesion.

After each team member read the whole event description (including the criteria used by the judges for scoring), you and your team should immediately go through the first stage (TDS1) called orientation where productivity is low (you didn’t write any code yet) and morale is moderately high. Team members are moderately eager and have high expectations. They need direction and have some anxiety about their roles and their connections with the team.

To go through phase 1, you and your team will need to adopt a structuring approach. I think that you’ll need to:

  1. Identify the main goal of the event
  2. For the practice event, the main goal could be: inventory servers by scanning an IPv4 subnet, gather data like the CPU, RAM,…installed components and save data to files in a reusable format.

  3. Identify skills among your team
  4. Some team members may be more familiar than others about the network part. They should know what a CIDR is. Some may be more familiar with WMI,…

  5. Divide to conquer
  6. You should split each problem into tasks and create one function to achieve one task. Each function should do one single thing and do it well.

  7. Clarify roles
  8. Make sure that each member in your team has had a role assigned, i.e. is responsible for writing the function that does this…

Now each team member starts his journey and writes some code 😀 …

… and your team is actually slowly moving toward phase 2 (TDS2) called dissatisfaction.

Productivity is low to some. Skills and knowledge are slowly developping. Some results are occuring. Morale is low. There is a discrepency between expectations and reality. Team members have feelings of anger, frustration, confusion and discouragement.

This is in my opinion the most difficult phase to overcome.
As soon as you feel that morale is at its lowest point, it means that you matured enough to share your code on the scripting games site and get the help of coaches.

Coaches will do their best to provide high quality support and direction to your team. Resolving is the keyword for this phase. But don’t get me wrong. Some conflicts may arise among your team. You’re on your own to solve these conflicts. My last advice about this situation is that you’ve to listen and you can also use a tool like the “ladder of inference to avoid jumping to conclusions”. The following article provides some tips that may help you.

Be prepared for the Winter Scripting Games, 3, 2, 1, Go!

  1. Read the 2014 Winter SG Players Guide
  2. Sharpen your skills by:
  3. Be timely informed by
  4. Prepare your toolbox
  5. Last but not least be on time
    • Review the games schedule
    • As it’s up to you to translate UTC times in your local time, have some nifty pieces of code ready
    • # When will event 1 start in my local time zone?            
      (Get-Date '2014-01-19 01:00:00').ToLocalTime()            
      # How long until event 1 is due?            
      New-TimeSpan -End ([datetime]'2014-01-26 01:00:00').ToLocalTime()

Don’t forget to have fun 😎

PS: …and if you don’t have time and/or aren’t on holidays, do at least what’s written in green (point 1. and 3.1).