What To Do / Not to Do in PowerShell: Part 3

Take a look at the left-hand side of your keyboard. Odds are, you'll find a key labeled "Tab," or perhaps a key with a "->" symbol on it. Also notice a key labeled "Enter" or "Return," and that big, blank key at the ver bottom.  Please make these keys your friend. Why? Take a look at this code:

Don Jones

May 26, 2011

2 Min Read
ITPro Today logo in a gray background | ITPro Today

Take a look at the left-hand side of your keyboard. Odds are, you'll find a key labeled "Tab," or perhaps a key with a "->" symbol on it. Also notice a key labeled "Enter" or "Return," and that big, blank key at the ver bottom.

Please make these keys your friend.

Why? Take a look at this code:
 

function Get-Info {[CmdletBinding()]param([Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)][Alias('host')][string[]]$computername,[string]$logfile='c:failed.txt')BEGIN {Del $logfile -ErrorAction 'SilentlyContinue'}PROCESS {foreach ($computer in $computername) {try {           $continue=$true      write-verbose "Attempting connection to $computer"    $os = Get-WmiObject -class Win32_OperatingSystem -ComputerName $computer -ErrorAction 'Stop'} catch {  $computer | Out-File $logfile -append                         $continue = $False            }if ($continue) {    $bios = Get-WmiObject -class Win32_BIOS -ComputerName $computer $obj = New-Object -TypeName PSObject $obj | Add-Member -MemberType NoteProperty -Name ComputerName -value ($computer) -passthru |Add-Member -MemberType NoteProperty -Name OSVersion -value ($os.caption) -passthru |Add-Member -MemberType NoteProperty -Name OSBuild -value ($os.buildnumber) -passthru |Add-Member -MemberType NoteProperty -Name SPVersion -value ($os.servicepackmajorversion) -passthru |Add-Member -MemberType NoteProperty -Name BIOSSerial -value ($bios.serialnumber)  write-output $obj  } } }}


Pretty awful, isn't it? It's hard to read. It's even harder to debug, because it's so poorly-formatted. Whenever I'm teaching class, I tell my students: "If you need help, just ask. But, if your code looks anything like this," and I show them the example above, "don't bother!" I just can't read it.

Now, isn't this version much easier to read and interpret?
 

function Get-Info {    [CmdletBinding()]    param(        [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]        [Alias('host')]        [string[]]$computername,        [string]$logfile = 'c:failed.txt'    )    BEGIN {        Del $logfile -ErrorAction 'SilentlyContinue'    }    PROCESS {        foreach ($computer in $computername) {            try {                $continue = $true                write-verbose "Attempting connection to $computer"                $os = Get-WmiObject -class Win32_OperatingSystem -ComputerName $computer -ErrorAction 'Stop'            } catch {                $computer | Out-File $logfile -append                $continue = $False            }            if ($continue) {                $bios = Get-WmiObject -class Win32_BIOS -ComputerName $computer                $obj = New-Object -TypeName PSObject                $obj | Add-Member -MemberType NoteProperty -Name ComputerName -value ($computer) -passthru |                       Add-Member -MemberType NoteProperty -Name OSVersion -value ($os.caption) -passthru |                       Add-Member -MemberType NoteProperty -Name OSBuild -value ($os.buildnumber) -passthru |                       Add-Member -MemberType NoteProperty -Name SPVersion -value ($os.servicepackmajorversion) -passthru |                       Add-Member -MemberType NoteProperty -Name BIOSSerial -value ($bios.serialnumber)                write-output $obj            }        }    }}


The difference? Tabs. Spaces. Carriage returns. Code within a { construct } of some kind is indented exactly four characters (one tab). That series of Add-Member statements are formatted to line up, visually reminding me that they're all part of the same logical command - see the pipe character at the end of each? PowerShell will recognize that the command continues on the next line when a line ends in a pipe. 

It's just a bit of whitespace, but it makes all the difference in the world. So please, format your code!

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like