PowerShell neat function tricks for free

Finished going through a recent NA TechEd2012 video Turn PowerShell Commands into Reusable CLI and GUI Tools by Don Jones.

Some of the advice I sort of knew and and followed.

  • I knew how to make a PowerShell script module.
  • I knew about the .SYNOPSIS, .EXAMPLE stuff.
  • I sort of knew about using the param/paremeters though I didn't really understand it, just used it in a limited framework copy/paste sort of way. After the video I have a much better handle on how to leverage it.

What I really got out of it though was some new and better ways to leverage built in switches more effectively which I had no real clue about.

  • Documenting not though #comments but using Write-Verbose so that the -verbose switch works and you can see what a script is doing without pulling it up in an editor.
  • useing write-debug to leverage the -debug switch for your functions
  • Using try/catch in your scripts so if a first part fails, then it skips the next parts on that one server.
  • A clear example on how to use Write-Object with a PSObject which I just used without understanding it.
  • Using $errorLogPath to create an error log

Below is the script he built for the presentation with the various examples. Save the below code as MyTools.psm1 and load it up. Then run it against multiple systems without switches and using the -debug and -verbose switches. Better yet, go watch the video.

function Get-OSInfo {
    <#
    .SYNOPSIS
    Gets computer info stuff from places.
    .DESCRIPTION
    Example script by Don Jones during TechEd2012 NA Presentation
    <a href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012/WCL404
" title="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012/WCL404
">http://channel9.msdn.com/Events/TechEd/NorthAmerica/2012/WCL404
</a>    .EXAMPLE 
    test -computername localhost
    .EXAMPLE
    test -comp one, two, three
    .EXAMPLE
    get-content names.txt | test
    .PARAMETER ComputerName
    One or more computer names, or IP Addresses, whatever.
    #>
    [cmdletBinding()]
    param(
        [Parameter(mandatory=$True,ValueFromPipeline=$True)]
        [string[]]$ComputerName, 
        [string]$errorLogPath = 'C:\scripts\test\oops.txt'
    )
 
    BEGIN {}
    PROCESS {
        foreach ($computer in $ComputerName){
            Write-Verbose "About to query $computer"
            write-debug "computer is next ..."
            try { 
                $everything_ok = $true
                $os = Get-WmiObject -Class win32_operatingsystem -ComputerName $computer -ErrorVariable MyErr -ErrorAction Stop
            } catch {
                $everything_ok = $false
                Write-Verbose "computer failed, logging to $errorLogPath"
                Write-Verbose "Error was $MyErr"
                $computer | out-file $errorLogPath -Append
            }
            if ($everything_ok) {
                $bios = Get-WmiObject -Class win32_bios -ComputerName $computer
                $cs = Get-WmiObject -Class win32_computersystem -ComputerName $computer
                $props = @{'ComputerName' = $computer;
                           'OSVersion' = $os.version;
                           'SPVersion' = $os.servicepackmajorversion;
                           'BIOSSerial' = $bios.serialnumber;
                           'Model' = $cs.model;
                           'Manufacturer' = $cs.manufacturer}
 
                $obj = New-Object -TypeName PSObject -Property $props
                Write-Debug "About to dump output... ready?"
                Write-Output $obj
            }
        }
    }
    END{}
}

Commenting on this Blog entry is closed.

Tags: