My Problem

As always there are different ways of doing things. PowerShell is no different.

Today I’ve looked at functions in PowerShell.

I’ll start with an ease function that does something:

function Do-Something ($param1, $param2)
{
   Write-Host "Hello!" $param1 $param2
}

So I’ve got some parameters and my function uses these parameters

But I want better control over my functions also I would like to document my code better. Are there any options/standards?

My Solution

Yes there is a better way. Below are a few of the ideas I found:

Intellisense

First I’m adding the descriptions of my function. So that my intellisense in the PowerShell ISE will help me write my PowerShell scripts quicker.

function Do-Something

<#
.SYNOPSIS
Do something very important
.DESCRIPTION
Do something very important and use a few more word.
.EXAMPLE
Do-Something
.PARAMETER param1
My parameter
#>
{
<p style="padding-left:30px;">Write-Host "Do something"</p>
}

So what are all the options:

  • .SYNOPSIS –a brief explanation of what the script or function does.
  • .DESCRIPTION – a more detailed explanation of what the script or function does.
  • .PARAMETER name – an explanation of a specific parameter. Replace name with the parameter name. You can have one of these sections for each parameter the script or function uses.
  • .EXAMPLE – an example of how to use the script or function. You can have multiple .EXAMPLE sections if you want to provide more than one example.
  • .NOTES – any miscellaneous notes on using the script or function.
  • .LINK – a cross-reference to another help topic; you can have more than one of these. If you include a URL beginning with http:// or https://, the shell will open that URL when the Help command’s –online parameter is used.

 

Parameters

Then I want to get more control over my parameters:

function Get-Something {

[CmdletBinding()]
param
(
   [Parameter(Mandatory=$True,ValueFromPipeline=$True,
   ValueFromPipelineByPropertyName=$True,
   HelpMessage='This')]
   [Alias('myalias')]
   [ValidateLength(3,30)]
   [string[]]$mystring
)

The syntax for the above parameter example is for a single parameter. After “[CmdletBinding()]” is is possible however to add multiple parameter sections.

 

[CmdletBinding()]
param
(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage='The url where to activate the feature')]
[Alias('$url')]
[ValidateLength(3,120)]
[string]$siteorweburl = 'https:/ /defaultsite',
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage='The id of the feature')]
[Alias('$featureid')]
[ValidateLength(3,120)]
[string]$featureId = '000000-0000-000-0000-000000',
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage='The name of the feature')]
[Alias('$featurename')]
[ValidateLength(3,120)]
[string]$featureName = ''
)

 

Now one more thing. I’ve found when I developed PowerShell scripts that I was initiation variables throughout my code. making it difficult to see the scope of some variables resulting in bugs.

In PowerShell it is possible to make each function split in 3 sections/blocks.

begin, process and end.

Another example:

function Get-Something {
<p style="padding-left:30px;">[CmdletBinding()]
param
(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage='This')]
[Alias('host')]
[ValidateLength(3,30)]
[string[]]$mystring1,
[string]$mystring2 = 'Hello'
)
begin
{
   write-verbose = "Hello Begin"
}
process
{
write-verbose "Do something"
   }
   end
   {
      write-verbose "Do End"
   }
}

So you could now initialise variable in the begin section and dispose them at the end.

General Standards

  • 1 function does 1 thing
  • Function names follow the Standard “Verb-Object” e.g. Get-List
  • Variables should use camelCase standard.
  • indent your code properly ( 😉 )

Related

Import Module

Advertisements