PowerShell with a Purpose Blog

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:
 

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!

Hide comments

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.
Publish