Prof. Powershell

Functions That Act Like Cmdlets

The third part in a series on writing simple functions to work in PowerShell.

We've been looking at functions and how that can accept input via parameters and how they write to the pipeline. Here's the last function we've been working with as an example:

Function Check-Service {
  Param([string]$computername=$env:computername,
    [string]$service="spooler" )

  $wmi=get-wmiobject win32_service -filter "name='$service'" -computername $computername
  if ($wmi.state -eq "running") {
  write $True
  }
  else {
  write $False
  }
}

Suppose you wanted to check a list of computers using this function. It can be done using ForEach-Object:

get-content computers.txt | foreach {
  If (check-service -computername $_ -service browser) {
    write-host $_ -fore Green}
    else {
  write-host $_ -fore Red}
  }
}

Each computername from computers.txt is piped to ForEach which has an If statement that uses the function (remember it returns $True or $False). If the service is running the computer name is written in Green; otherwise, it is written in Red. Again, focus more on the technique here, not the specifics of the function itself. For most of your scripting work, especially starting out, this should be sufficient.

But there is another approach. By adding some special script blocks to a function, we can make it behave more like a cmdlet and it can take pipeline input directly. Here's the basic outline:

Function Do-Something{
  BEGIN {#code executes once before any pipelined input is processed }
  PROCESS {
    #code executes once for each pipelined object.
    #Use $_ to reference the current object in the pipeline.
  }
  END { #code executes once after all objects have been processed}
}

The Begin and End script blocks are optional. The Process script block is where the action is:

Function Show-CSpace {
  Begin {}
  Process {
    $c=Get-WmiObject win32_logicaldisk -filter "deviceid='c:'" $_
    -computername $c | select @{name="Server";Expression=
  {$_.__SERVER}},Size,FreeSpace
  }
  End {}
}

This example is designed to work in the pipeline. In the process script block we can see the $_ used for the computername parameter. What this means is that every string object piped into this function will be used as the computername. The functions output is a custom object with the Server name, the C: drives size and freespace. Here's how all the pieces go together:

PS C:\> get-content servers.txt | show-Cspace | sort FreeSpace | export-csv cspace.csv

By using a function that participates in the pipeline, I've created my own PowerShell tool without having to program a cmdlet. With that, the more Powershell you know, the more you can develop complex functions. I hope you'll be back for another "Prof. PowerShell" lesson soon.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular