Using PowerShell Functions: Best Practices

Using PowerShell Functions: Best Practices

  • Comments 6
  • Likes

Summary: Microsoft Scripting Guy, Ed Wilson, talks about some best practices for using Windows PowerShell functions.

Microsoft Scripting Guy, Ed Wilson, is here. Windows PowerShell functions are really powerful, and at the same time, they are incredibly simple to create. This makes Windows PowerShell functions flexible and functional. But this flexibility also means that there is a lot of misunderstanding.

A simple function

At the low end (in terms of readability, functionality, features, and so on), a Windows PowerShell function is creatable on a single line interactively at the Windows PowerShell console. The minimum number of elements required to create a function are:

  • The Function keyword
  • The name of the function
  • A script block

That is it. This means that the following is a legitimate function:

function a {}

It does not do anything, but it is legitimate. Running the code at a command prompt in the Windows PowerShell console creates the function. I can then pipe output to it, and even verify that it exists on the Windows PowerShell function PS drive. The following script illustrates these concepts.

PS C:\> function a {}

PS C:\> gps | a

PS C:\> dir function:a

 

CommandType     Name                                               ModuleName

-----------     ----                                               ----------

Function        a 

Adding functionality to the function

I often need to get a view of data, or a snapshot of data, before I return all of the data. Typically, I pipe the data to the Select-Object cmdlet and pick the last three entries in the data. The following script illustrates this technique (gps is an alias for the Get-Process cmdlet, and select is an alias for the Select-Object cmdlet).

PS C:\> gps | select -Last 3

 

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName

-------  ------    -----      ----- -----   ------     -- -----------

    207       9     1340       3064    40            1848 WUDFHost

    405      19     3636      10012    95            1904 WUDFHost

    214      18     3336       7852    89            2880 ZeroConfigService

I use this type of code when I am troubleshooting or simply perusing the status of a computer. Because I have established a pattern that pipes data to the Select-Object cmdlet and chooses the last three items, I can put this into a function that accepts pipelined input and outputs the last three items.

Because I am writing the function interactively in the Windows PowerShell console, and because I will be using it a lot, I give it a really short name. Here I call it “l” (as in lower case letter “L”). Inside the script block, I use the automatic variable $input, which is the input piped into a function.

The $input variable only exists inside the context of a function, and only for the time the function is called. If I check the value of $input outside of the function, it is empty. So what I pass to the function is then piped to the Select-Object cmdlet, and the last three items are returned from the function. The function is shown here.

function l {$input | select -Last 3}

To use the function, I pipe results to the function. The following script selects the last three processes.

PS C:\> gps | l

 

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName

-------  ------    -----      ----- -----   ------     -- -----------

    207       9     1340       3064    40            1848 WUDFHost

    405      19     3636      10012    95            1904 WUDFHost

    214      18     3336       7852    89            2880 ZeroConfigService

I can select the last three services (gsv is an alias) as shown here.

gsv | l

Or maybe I want to look at the last three entries in the event log as shown here.

Get-EventLog application | l

I can even use the range operator and select the last three numbers. This command is shown here.

1..10 | l

These commands and their associated output are shown in the following image.

Image of command output

Best Practices Week will continue tomorrow when I will continue talking about functions.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi Ed,

    I wasn't aware of the $input variable inside function scope. Thanks!

    Carlo

  • Hi Ed,

    This is a very good Blog. I learnt more about variables inside Function Scopes.

    Good Job!

  • @Happysysadm Awesome. Thanks for the feedback. Glad to help.

    @Cyberwarfare1 Thank you. I am glad you like the blog.

  • Knowing about $input is really a nice thing. Thanks Ed.

  • @PosHV Thanks, I am glad you found the article useful.

  • Good info