PowerShell with a Purpose Blog

Want to write an Advanced Function ("script cmdlet?") Here's how.

I'm off to speak at the Wisconsin IT Symposium this week, so I thought I'd offer a beefy article to tide you over.

This isn't meant to be so much a USEFUL Advanced Function as it is an all-in-one demo of what Advanced Functions can look like. Notice:
  • Comment-based help, producing properly-formatted help when you run "Help Get-Info"
  • Support for -whatif and -confirm parameters (added by "SupportsShouldProcess()")
  • Support for ByValue and ByPropertyName parameter binding of pipeline input
There are some additional examples at the end; remove those and save this as a .psm1 file to create a Script Module!

I'll have several upcoming articles about how to construct this type of function... just wanted to share the final product in the meantime :). 

03.Retrieves operating system and BIOS information from one or more remote computers.
05.Get-Info retrieves operating system and service pack version information, along with BIOS serial number information, from one or more remote computers. It uses WMI to retrieve this information, so the appropriate firewall ports must be opened.
07.The output objects have properties for OS Version, OS Build Number, Service Pack version, and BIOS Serial Number. The computer name is also included in its own property.
09.Because WMI is used, computers are processed sequentially. Unreachable computers will incur a timeout of approximately 30 seconds.
11.Bind pipeline input by value
12.'localhost','win-por9tp458l7','not-online' | Get-Info
14.Use parameter
15.Get-Info -computername 'localhost' -errorlog 'errors.txt'
17.Bind pipeline input ByPropertyName - assumes CSV file has a "computername" column
18.Import-Csv inventory.csv | Get-Info -errorlog 'retries.txt'
19..PARAMETER ComputerName
20.One or more computer names.
21..PARAMETER ErrorLog
22.Path and filename where you wish unreachable computer names to be logged.
23..PARAMETER ErrorBehavior
24.'Log' or 'Ignore,' depending on what you want to happen when a computer cannot be reached.
26.function Get-Info {
27.    [CmdletBinding()]
28.    param(
29.        [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,HelpMessage='Computer name(s) to target')]
30.        [string[]]$computername,
32.        [Parameter(HelpMessage='Path and filename of file for unreachable computer names')]
33.        [string]$errorlog = 'unreachable.txt',
35.        [Parameter(HelpMessage='What to do when connection errors occur')]
36.        [ValidateSet('Log','Ignore')]
37.        [string]$errorbehavior = 'Log'
38.    )
39.    BEGIN {
40.        del $errorlog -erroraction 'SilentlyContinue'
41.    }
42.    PROCESS {
43.        try {
44.            $skip = $false
45.            $os = Get-WmiObject win32_operatingsystem -ComputerName $computername -ErrorAction 'Stop'
46.            $bios = Get-WmiObject win32_bios -ComputerName $computername -ErrorAction 'Stop'
47.        } catch {
48.            $skip = $true
49.            if ($errorbehavior -eq 'Log') {
50.                $computername | Out-File $errorlog -append
51.            }
52.        }
53.        if (-not $skip) {
54.            $obj = New-Object PSObject
55.            $obj | Add-Member NoteProperty ComputerName $computername
56.            $obj | Add-Member NoteProperty OSVersion ($os.caption)
57.            $obj | Add-Member NoteProperty OSBuild ($os.buildnumber)
58.            $obj | Add-Member NoteProperty SPVersion ($os.servicepackmajorversion)
59.            $obj | Add-Member NoteProperty BIOSSerial ($bios.serialnumber)
60.            Write-Output $obj
61.        }
62.    }
63.    END {}
66.# bind pipeline input by value
67.'localhost','win-por9tp458l7','not-online' | Get-Info
69.# use parameter
70.Get-Info -computername 'localhost' -errorlog 'errors.txt'
72.# bind pipeline input ByPropertyName
73.# assumes CSV file has a "computername" column
74.Import-Csv inventory.csv | Get-Info -errorlog 'retries.txt'

Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.