Powershell Audit Script

Time for my first stab at WMI, I have just completed my audit script which will give you a nice html audit of each of the computers in a file or if run with no parameters and it will use localhost.

This is a conversion of an old vbscript which I have been using for a while, updated and enhanced and very much quicker !

Usage: Audit.ps1 ‘c:\servers.txt‘ or just run Audit.ps1 with no parameters to audit the localhost.

The txt file must consist of each server on an individual line.

Best viewed in IE but will work in firefox (minus the expanding of cells)

As always your comments are welcome.

10 thoughts on “Powershell Audit Script

  1. Virtu-Al


    Thanks very much for the comments, some amazing tips there, nice to see a little further into the mind of a guru 🙂

    Its an honour to have you comment on my blog and to also have great comments from you. I was planning on a re-write over the xmas break to include some of what you mentioned as Hal had also mentioned about my use of multiple write-outputs.

    This was just a first revision of an old vbscript I had so now I can start making alot more PS friendly and use some of the greatness that powershell provides.

    Thanks again.


  2. Anonymous

    Cool script – I’m running on my machine now.
    Wow – that produced a damn fine report. Very cool. Very useful.

    If you don’t mind, I thought I would share some of my scar tissue on writing PS Scripts.

    You could save yourself a TON of code and make it more readable/maintainable AND make it run faster if you used HERE strings to replace all the:

    Write-Output ” ….” | out-file -append …

    I talk about this in my post: http://blogs.msdn.com/powershell/archive/2008/09/14/rdp-file-generation-use-of-here-strings.aspx

    Out-File -Append can be expensive. I bet your code would go a TON faster if you rewrote the event section to create one big string and then sent that string to “Out-File -Append”. You’d do it this way:

    $report += @”
    your html header stuff
    ForEach ($objEvent in $colLoggedEvents)
    $dtmEventDate = $ObjEvent.ConvertToDateTime($objEvent.TimeWritten)
    $report += @”
    More html. Note that when you want to include
    a variable in your here string you can say
    $var but if you want to get a property of that
    variable you have to say $($var.property) e.g.
    enclose it in $()s
    $report += @”
    closing html

    $report | out-File -Append -encoding ASCII -filepath $fileName

    You have some code:

    Write-Host “Invalid audit path specified: $auditlist”

    This is a terminating error so the right way to do that is:
    Throw “Invalid audit path specified: $auditlist”

    The difference is that this generates an error, populates $Error and allows a calling script to trap the error and do something with it.

    Your keyboard switch statement is really expensive because you didn’t put a BREAK statement after each of the
    statements e.g.

    “00000402”{ $keyb = “BG”;Break }

    if you don’t put the break, the switch statement evaluates the ALL of the conditions.

    You might want to consider turning this into a hashtable at the top of the script
    $keyboardmap = @{
    “00000402” = “BG”
    “00000404” = “CH”
    “00000405” = “CZ”

    Then your code could be:

    $keyb = $keyboardmap.$($ObjKeyboards.Layout)
    if (!$keyb)
    { $keyb = “Unknown”

    It would be a lot faster as well.

    Again – awesome script!
    Jeffrey Snover [MSFT]
    Windows Management Partner Architect
    Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
    Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

  3. Virtu-Al


    Thanks for the kind comments, My first stab at WMI in a powershell script anyway, I guess I have really been using WMI for years in VBscript and scriptomatic 🙂

    Didnt think of adding Processes, great idea, yet another addition when I find time. Perhaps I should work on a Get-Time script !


  4. Wes Stahler

    I demonstrated this script to our Support Center manager. They loved it! You sure this is your first stab at wmi 🙂

    I am going to add processes to it (their suggestion). Thanks for doing this! A GREAT example of what can be done with PowerShell, WMI, and HTML.

  5. Virtu-Al

    Thanks Jeff, means alot coming from a powershell guru like you !

    There both great Ideas, I will definately add them in when I get time 🙂


  6. Jeffery Hicks

    Very impressive. Your next step would be to add support for alternate credentials. My other suggestion is that instead of using localhost, use $env:computername instead. This will give you a “real” computername which is more meaningful than “localhost”.

  7. Virtu-Al

    Please, go ahead, all code is publically available but I would appreciate a mention in the comments 🙂

    Glad it was helpfull !

  8. neiljmorrow

    I’ve been tinkering with a script to do something similar to write reports for a series of domain machines. Mind if I reuse a bit of your code for the reporting bit?

  9. Virtu-Al

    Thanks, always nice to know that my scripts help other people besides myself, wouldn;t go as far as genius though 🙂

    Send your script over via email and I will see if I can integrate it, anything to enhance whats there already !

  10. Aaron Perrault

    OMG!!! You are a genius!! I have a question for you though. How hard would it be to obtain additional information from a server? I have a script that i run, but it is very tedious to run, because i have to pass it credentials and a bunch of other things to get all of the info i want. I can provide a copy of the script if you would like.

    Let me know if you want to take this discussion offline.



Leave a Reply

Your email address will not be published. Required fields are marked *

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