Keith's profileKeith Hill's BlogPhotosBlogListsMore Tools Help
    October 30

    PowerShell QuickTip: Preparsing Scripts to Check for Syntax Errors

    There are a number scenarios where you need to update a script to add a minor feature or fix a bug but you can't really run the script to test your changes.  Perhaps the script is destructive and you'd have to comment out a bunch of script to test and then remember to uncomment the code.  Or perhaps the script can only be run on a production server and won't run on your dev PC.  Wouldn't be nice if there were a way to at least have PowerShell try to parse the script after your updates and report parse/syntax errors.  In a previous post I discussed how to do this when dealing with a script full of just functions (ie no directly executing script).  This approach doesn't work if your scripts contain script at the top level.  However there is another way that will at least tell you if there is a problem or not:

    # Contents of file TestScript.ps1
    param($path, [switch]$verbose)

    if ($verbose) {
        $VerbosePreference = 'Continue'
    }

    trap { Write-Warning $_; $false; continue }
    & `
    {
        $contents = get-content $path
        $contents = [string]::Join([Environment]::NewLine, $contents)
        [void]$ExecutionContext.InvokeCommand.NewScriptBlock($contents)
        Write-Verbose "Parsed without errors"
        $true
    }

    Note that this doesn't give useful error information such as the actual line of script that is bad but at least you will know if there is a problem or not.

    Many thanks to Karl Prosser of PowerAnalyzer fame for giving me the pointer to the $ExecutionContext.InvokeCommand.NewScriptBlock method.

    Update: Fixed some script problems pointed out by Shay.  Thanks!

    October 28

    PowerShell QuickTip: Using PSTypeNames to See the TypeName and Inheritance Chain

    I've mentioned plenty of times that PowerShell is all about .NET objects, well actually PowerShell "adapted" .NET objects.  Quite often it is handy to know which type of object you are dealing with.  You have a couple of options here:

    PS> (get-date).GetType().Fullname

    That uses the GetType method that is available on all .NET objects.  However PowerShell also allows you to use COM objects which don't (typically) have the GetType method available.  However all objects you use in PowerShell have been adapted by what is called the "Extended Type System".  That is, PowerShell dynamically wraps .NET and COM objects to provide standardized features.  One of those is a property called PSTypeNames that is available on *all* objects you will encounter in PowerShell - both .NET and COM.  You can use it like so to get the object's typename:

    PS> (get-date).pstypenames[0]
    System.DateTime

    To get an object's complete inheritance chain, just get the pstypenames property like so:

    PS> (get-date).pstypenames
    System.DateTime
    System.ValueType
    System.Object

    October 03

    Windows Powershell Virtual User Group Presentation

    Here are the slides that I presented at today's LiveMeeting.  Thanks to Marco Shaw for setting up the group!