40. Modules, Scripts and Functions

Note

The below information is extensively based in information taken from the PowerShell® Notes for Professionals book. I plan to extend this information based on my day to day usage of the language.

PowerShell modules bring extendibility to the systems administrator, DBA, and developer. Whether it’s simply as a method to share functions and scripts.

PowerShell Functions are to avoid repetitive codes. Refer [PS Functions][1] [1]: PowerShell Functions

PowerShell Scripts are used for automating administrative tasks which consists of command-line shell and associated cmdlets built on top of .NET Framework.

40.1: Function

A function is a named block of code which is used to define reusable code that should be easy to use. It is usually included inside a script to help reuse code (to avoid duplicate code) or distributed as part of a module to make it useful for others in multiple scripts.

Scenarios where a function might be useful:

  • Calculate the average of a group of numbers
  • Generate a report for running processes
  • Write a function that tests is a computer is "healthy" by pinging the computer and accessing the c$-share

Functions are created using the function keyword, followed by a single-word name and a script block containing the code to executed when the function name is called.

1
2
3
function NameOfFunction {
  Your code
}

Demo

1
2
3
function HelloWorld {
  Write-Host "Greetings from PowerShell!"
}

Usage:

1
2
HelloWorld
Greetings from PowerShell!

40.2: Script

A script is a text file with the file extension .ps1 that contains PowerShell commands that will be executed when the script is called. Because scripts are saved files, they are easy to transfer between computers.

Scripts are often written to solve a specific problem, ex.:

  • Run a weekly maintenance task
  • To install and configure a solution/application on a computer

Demo

MyFirstScript.ps1:

1
2
Write-Host "Hello World!"
2 + 2

You can run a script by entering the path to the file using an:

  • Absolute path, ex. c:\MyFirstScript.ps1
  • Relative path, ex .\MyFirstScript.ps1 if the current directory of your PowerShell console was C:\

Usage:

1
2
3
.\MyFirstScript.ps1
Hello World!
4

A script can also import modules, define its own functions etc.

MySecondScript.ps1:

1
2
3
4
5
6
7
8
function HelloWorld {
  Write-Host "Greetings from PowerShell!"
}

HelloWorld
Write-Host "Let's get started!"
2 + 2
HelloWorld

Usage:

1
2
3
4
5
.\MySecondScript.ps1
Greetings from PowerShell!
Let's get started!
4
Greetings from PowerShell!

40.3: Module

A module is a collection of related reusable functions (or cmdlets) that can easily be distributed to other PowerShell users and used in multiple scripts or directly in the console. A module is usually saved in its own directory and

consists of:

  • One or more code files with the .psm1 file extension containing functions or binary assemblies (.dll) containing cmdlets
  • A module manifest .psd1 describing the modules name, version, author, description, which functions/cmdlets it provides etc.
  • Other requirements for it to work incl. dependencies, scripts etc.

Examples of modules:

  • A module containing functions/cmdlets that perform statistics on a dataset
  • A module for querying and configuring databases

To make it easy for PowerShell to find and import a module, it is often placed in one of the known PowerShell module-locations defined in $env:PSModulePath.

Demo

List modules that are installed to one of the known module-locations:

1
Get-Module -ListAvailable

Import a module, ex. Hyper-V module:

1
Import-Module Hyper-V

List available commands in a module, ex. the Microsoft.PowerShell.Archive-module

1
2
Import-Module Microsoft.PowerShell.Archive
Get-Command - Module Microsoft.PowerShell.Archive
1
2
3
4
CommandType Name Version Source
----------- ---- ------- ------
Function Compress-Archive 1.0.1.0 Microsoft.PowerShell.Archive
Function Expand-Archive 1.0.1.0 Microsoft.PowerShell.Archive

40.4: Advanced Functions

Advanced functions behave the in the same way as cmdlets. The PowerShell ISE includes two skeletons of advanced functions. Access these via the menu, edit, code snippets, or by Ctrl+J. (As of PS 3.0, later versions may differ) Key things that advanced functions include are:

  • built-in, customized help for the function, accessible via Get-Help
  • can use [CmdletBinding()] which makes the function act like a cmdlet
  • extensive parameter options

Simple version:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<#
    .Synopsis
    Short description
    .DESCRIPTION
    Long description
    .EXAMPLE
    Example of how to use this cmdlet
    .EXAMPLE
    Another example of how to use this cmdlet
#>
function Verb-Noun
{
  [CmdletBinding()]
  [OutputType([int])]
  Param
  (
    # Param1 help description
    [Parameter(Mandatory=$true,
        ValueFromPipelineByPropertyName=$true,
    Position=0)]
    $Param1,
    # Param2 help description
    [int]
    $Param2
  )
  Begin
  {}
  Process
  {}
  End
  {}
}
Complete version:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<#
    .Synopsis
    Short description
    .DESCRIPTION
    Long description
    .EXAMPLE
    Example of how to use this cmdlet
    .EXAMPLE
    Another example of how to use this cmdlet
    .INPUTS
    Inputs to this cmdlet (if any)
    .OUTPUTS
    Output from this cmdlet (if any)
    .NOTES
    General notes
    .COMPONENT
    The component this cmdlet belongs to
    .ROLE
    The role this cmdlet belongs to
    .FUNCTIONALITY
    The functionality that best describes this cmdlet
#>
function Verb-Noun
{
  [CmdletBinding(DefaultParameterSetName='Parameter Set 1',
      SupportsShouldProcess=$true,
      PositionalBinding=$false,
      HelpUri = 'http://www.microsoft.com/',
  ConfirmImpact='Medium')]
  [OutputType([String])]
  Param
  (
    # Param1 help description
    [Parameter(Mandatory=$true,
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true,
        ValueFromRemainingArguments=$false,
        Position=0,
    ParameterSetName='Parameter Set 1')]
    [ValidateNotNull()]
    [ValidateNotNullOrEmpty()]
    [ValidateCount(0,5)]
    [ValidateSet("sun", "moon", "earth")]
    [Alias("p1")]
    $Param1,
    # Param2 help description
    [Parameter(ParameterSetName='Parameter Set 1')]
    [AllowEmptyCollection()]
    [AllowEmptyString()]
    [ValidateScript({$true})]
    [ValidateRange(0,5)]
    [int]
    $Param2,
    # Param3 help description
    [Parameter(ParameterSetName='Another Parameter Set')]
    [ValidatePattern("[a-z]*")]
    [ValidateLength(0,15)]
    [String]
    $Param3
  )
  Begin
  {}
  Process
  {
    if ($pscmdlet.ShouldProcess("Target", "Operation"))
    {}
  }
  End
  {}
}