Before considering functions it is worth reading the following blog post, whose title says it all really Powershell Console, Scripts, Functions, Modules, Cmdlets, Oh My! | MSAdministrator.

Defining Functions

It is easy to define a function in PowerShell, an example is as follows:

Function SimpleIncrease($InValue)
  Write-Host "Input was $($InValue)"
  $OutValue = $InValue + 10
  Write-Host "Result will be $($OutValue)"
  return $OutValue

It is important to note that all function definitions should be at the top of your .ps1 file. You will also see that you don't need arguments or you can have several and you can optionally specify the type, for example the following is valid:

Function DisplayDirectoryInfo([String]$DirName, [Int]$Depth)

Another handy option is giving function parameters default values, this can reduce the amount of code you need. This is a little example:

Function printName($InputName) {
  if ($InputName) {
    Write-Host "Specified name is: $($InputName)"
  } else {
    Write-Host "Specified name is: Not Specified"

Function printName2($InputName = 'Not Specified') {
  Write-Host "Specified name is: $($InputName)"

printName "Geoff"

printName2 "Geoff"

Then if you don't put a return line in then your function returns nothing. As is common with a number of PowerShell things you can do many more advanced things, see Windows PowerShell: Build a Better Function | TechNet Magazine for some details.

Function Parameters

There are a lot of advanced things you can do with parameters, have a look at ValidateScript as documented at about_Functions_Advanced_Parameters | Microsoft Docs and also look at my item on this at Output.

Calling Functions

The only thing to remember when calling a function is that you don't need the brackets, otherwise it is easy, as the following example shows:

$Answer = SimpleIncrease 5
Write-Host "The answer was $($Answer)"

This is vital when you have more than one argument to the function, as then using brackets changes the meaning! So for two arguments you must do something like this:

$DirSize = GetDirectorySize $Path $Depth
Write-Host "The $($Path) directory contains $($DirSize) bytes"

Note, that when you call a PowerShell function, the default is that when you have more than one parameter they are space separated.

Within Functions

Sometimes within a function you want to know what the name of the function is. Whilst you can type this in it is not idea as a simple refactoring could then be misleading. This is where $MyInvocation comes in! Have a look at about_Automatic_Variables | Microsoft Docs for details but something like $MyInvocation.MyCommand will give you the function name you are currently in. Whilst looking into this I found InvocationInfo Class (System.Management.Automation) | Microsoft Docs to be very useful.