Working with Functions in Windows PowerShell

  • 11/11/2015

Including functions in the Windows PowerShell environment

In Windows PowerShell 1.0, you could include functions from previously written scripts by dot-sourcing the script. The use of a module, which was introduced in Windows PowerShell 2.0, offers greater flexibility than dot-sourcing because you can create a module manifest, which specifies exactly which functions and programming elements will be imported into the current session.

Using dot-sourcing

This technique of dot-sourcing still works in Windows PowerShell 5.0, and it offers the advantage of simplicity and familiarity. In the TextFunctions.ps1 script shown following, two functions are created. The first function is called New-Line, and the second is called Get-TextStats. The TextFunctions.ps1 script is shown here.

TextFunctions.ps1

Function New-Line([string]$stringIn)
{
 "-" * $stringIn.length
} #end New-Line

Function Get-TextStats([string[]]$textIn)
{
 $textIn | Measure-Object -Line -word -char
} #end Get-TextStats

The New-Line function creates a string of hyphen characters as long as the length of the input text. This is helpful when you want an underline that is sized to the text, for text separation purposes. An example of using the New-Line text function in this manner is shown here.

CallNew-LineTextFunction.ps1

Function New-Line([string]$stringIn)
{
 "-" * $stringIn.length
} #end New-Line

Function Get-TextStats([string[]]$textIn)
{
 $textIn | Measure-Object -Line -word -char
} #end Get-TextStats

# *** Entry Point to script ***
"This is a string" | ForEach-Object  {$_ ; New-Line $_}

When the script runs, it returns the following output.

This is a string
----------------

Of course, this is a bit inefficient and limits your ability to use the functions. If you have to copy the entire text of a function into each new script you want to produce, or edit a script each time you want to use a function in a different manner, you dramatically increase your workload. If the functions were available all the time, you might be inclined to use them more often. To make the text functions available in your current Windows PowerShell console, you need to dot-source the script containing the functions into your console, put it in a module, or load it via your profile. You will need to use the entire path to the script unless the folder that contains the script is in your search path. The syntax to dot-source a script is so easy that it actually becomes a stumbling block for some people who are expecting some complex formula or cmdlet with obscure parameters. It is none of that—just a period (dot), followed by a space, followed by the path to the script that contains the function. This is why it is called dot-sourcing: you have a dot and the source (path) to the functions you want to include. This is shown here.

PS C:\> . C:\fso\TextFunctions.ps1

After you have included the functions in your current console, all the functions in the source script are added to the Function drive. This is shown in Figure 6-1.

FIGURE 6-1

FIGURE 6-1 Functions from a dot-sourced script are available via the Function drive.

Using dot-sourced functions

After the functions have been introduced to the current console, you can incorporate them into your normal commands. This flexibility should also influence the way you write the function. If the functions are written so they will accept pipelined input and do not change the system environment—by adding global variables, for example—you will be much more likely to use the functions, and they will be less likely to conflict with either functions or cmdlets that are present in the current console.

As an example of using the New-Line function, consider the fact that the Get-CimInstance cmdlet allows the use of an array of computer names for the -ComputerName parameter. In this example, BIOS information is obtained from two separate workstations. This is shown here.

PS C:\> Get-CimInstance win32_bios -ComputerName dc1, c10


SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : BIOS Date: 05/23/12 17:15:53  Ver: 09.00.06
SerialNumber      : 5198-1332-9667-8393-5778-4501-39
Version           : VRTUAL - 5001223
PSComputerName    : c10

SMBIOSBIOSVersion : Hyper-V UEFI Release v1.0
Manufacturer      : Microsoft Corporation
Name              : Hyper-V UEFI Release v1.0
SerialNumber      : 3601-6926-9922-0181-5225-8175-58
Version           : VRTUAL - 1
PSComputerName    : dc1

You can improve the display of the information returned by Get-CimInstance by pipelining the output to the New-Line function so that you can underline each computer name as it comes across the pipeline. You do not need to write a script to produce this kind of display. You can enter the command directly into the Windows PowerShell console. The first thing you need to do is to dot-source the TextFunctions.ps1 script. This makes the functions directly available in the current Windows PowerShell console session. You then use the same Get-CimInstance query you used earlier to obtain BIOS information via WMI from two computers. Pipeline the resulting management objects to the ForEach-Object cmdlet. Inside the script block section, you use the $_ automatic variable to reference the current object on the pipeline and retrieve the PSComputerName property. You send this information to the New-Line function so the server name is underlined, and you display the BIOS information that is contained in the $_ variable.

The command to import the New-Line function into the current Windows PowerShell session and use it to underline the server names is shown here.

PS C:\> . C:\fso\TextFunctions.ps1
PS C:\>  Get-CimInstance win32_bios -ComputerName dc1, c10 | ForEach-Object { $_.PSComputerName
; New-Line $_.PSComputerName ; $_}

The results of using the New-Line function are shown in Figure 6-2.

FIGURE 6-2

FIGURE 6-2 Functions that are written to accept pipelined input find an immediate use in your daily work routine.

The Get-TextStats function from the TextFunctions.ps1 script provides statistics based upon an input text file or text string. After the TextFunctions.ps1 script is dot-sourced into the current console, the statistics it returns when the function is called are word count, number of lines in the file, and number of characters. An example of using this function is shown here.

Get-TextStats "This is a string"

When the Get-TextStats function is used, the following output is produced.

              Lines               Words          Characters Property
              -----               -----          ---------- --------
                  1                   4                  16

In this section, the use of functions was discussed. The reuse of functions could be as simple as copying the text of the function from one script into another script. It is easier, however, to dot-source the function than to reuse it. This can be done from within the Windows PowerShell console or from within a script.