2013 PowerShell Scripting Games Advanced Event 4 – Auditors Love Greenbar Paper

The requirements for the 2013 Scripting Games Advanced Event 4 can be found here. For this event I created multiple functions and I’m going to quote chapter 6, section 1 of the “Learn PowerShell Toolmaking in a Month of Lunches” book written by Don Jones and Jeffery Hicks, published by Manning:

A function should do one and only one of these things:
Retrieve data from someplace
Process data
Output data to some place
Put data into some visual format meant for human consumption

I started out by naming my function to create the audit report properly (New-UserAuditReport). If you having trouble picking a name for your function, it’s probably because you’ve broken the previous rule and your function does more than one thing.

Of course, all of the functions (4 of them) all have their own comment based help.

Here’s the validation that I performed on the filename and extension via a regular expression. This not only enforces the htm and html file extension specified in the requirements, but also ensures that the file name is valid on a Windows system. There’s no sense in allowing the script to process all the way to the end only to have it fail because the file name is not valid on a Windows system. Be proactive, not reactive. This MSDN article explains what is not valid in a Windows filename.


I couldn’t decide whether to use the cmdlets that are part of the Active Directory module or not because they may not be present on the system this is being run from and they only work on Windows Server 2008 R2 or higher unless you have a list of ingredients to include a Leprechaun as discussed in this TechNet blog to make them work with Windows Server 2003 domain controllers. Here’s a “Hey, Scripting Guy! blog” on the same subject that refers to 2008 non-R2 domain controllers as well. The problem is that since the scenario didn’t specify what OS the domain controllers are running, these cmdlets may not work.

Using ADSI (Active Directory Service Interfaces) on the other hand would be something that would work on systems that didn’t have the AD PowerShell module installed and it would also work against older domain controllers.

What I decided is why make a decision? Why not have the best of both worlds? Try the AD cmdlets and I mean literally try the AD cmdlets as shown in the first try catch block in the code below and then if there’s an issue, try ADSI as shown in the second (nested) try catch block in the code shown below as well:


If neither one works then the script exits with a warning instead of continuing to only error out somewhere further along in the code. That’s what the problem variable is for.


There is an issue on the Scripting Games website where the “Plain” tab doesn’t show the inline CSS so be sure to use the “Code” tab when copying and pasting the code to use on your own machine.

I figured those auditors would love some old school Greenbar paper. Here’s an example of six results showing a “Greenbar” style webpage (aka virtual Greenbar paper):


You may be wondering why I would chose to use the “LastLogonTimestamp” property when there are other properties such as “LastLogon” that already have human readable dates to start with? That’s because the LastLogon property is not replicated to all domain controllers in the domain and LastLogonTimestamp is beginning with Windows Server 2003. So it’s either query all the domain controllers in the domain or convert the date. From an efficiency standpoint it’s better to convert the date rather than possibly querying hundreds of domain controllers. See this TechNet blog article for more information about those two properties.


Now for the two functions that “Get” the data. The first is “Get-ADRandomUser”:


As you can see, this is a reusable function. Here’s the output that it creates (which is objects):


The ADSI one was a little trickier because I needed it to return the same data as the AD one. This one is called “Get-ADSIRandomUser”:


Although the type of object that this function produces is different, it’s still objects and it produces the same output from a properties and data standpoint as the previous function:


And finally, there is the “Set-AlternatingCSS” function which is a modified version of a function from Don Jones’s “Creating HTML Reports in PowerShell” book. Visit PowerShellBooks.com for details about this free ebook (Thank You Don!)


Update 02/09/14
The link to my solution is no longer valid so I’m posting it here since I’ve received some requests for it:

This PowerShell script can also be downloaded from the TechNet script repository.


1 Comment

  1. Rob D.

    Brilliant Greenbar Paper function! I used the CSS “:nth-child()” selector in my style sheet for my greenbar paper effect, but it didn’t work in IE10 for some reason. Reference: http://www.w3schools.com/cssref/sel_nth-child.asp


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: