Back to top

FREE eBook: The Most USEFUL PowerShell CmdLets and more…

Grab a copy!

How To Create Parameters In PowerShell Step By Step

PowerShell Parameter is an input to the Advanced Function or CmdLet and uses Parameter Attributes, Arguments, and Argument Values to further describe and limit the input so we can get the desired result from the function.

But do not be intimidated by these many technical terms since we will dive into each of them and explain everything with awesome examples.

Here are the types of parameters that we can create:

  • Static parameters are the parameters that are always available in the function.
  • Dynamic parameters are the parameters that are available only under certain conditions.
  • Switch parameters are the parameters with no parameter value. You just turned them on or off.

In order for someone to understand the parameters, I would like to use a recipe analogy. Imagine that you want to prepare a dish. You would go to the local market with fresh and nice vegetables, fruit, fish, meat but you do not want to buy all of them, rather you will buy only the necessary ingredients for the recipe. After you bought all the recipe ingredients you prepare them and follow the recipe instruction to make the dish which is our goal. Voilà, bon appétit!

Let’s go back to the PowerShell world and connect the analogy story with PowerShell terms.

  • Ingredients of the recipe are input parameters
  • The process that we follow how to prepare the dish is the code of our Advanced Function or CmdLet.
  • Finally, our prepared dish is the result of function or CmdLet.

How To Create PowerShell Parameters

I will provide general steps to create PowerShell Parameters and then follow with practical examples to illustrate the steps and actual PowerShell syntax.

Follow these steps in order to create the PowerShell Parameter(s):

  1. Use param () statement right after function definition to define all the input parameters within it. This step is done only once!
  2. Give a name to the parameter starting with $. For example, $parameter_name
  3. Define the parameter data type in front of parameter name defined within []
  4. Optionally give a default value to the parameter after the parameter name using = and the default value
  5. Optionally decide do you need parameter attributes and define them accordingly. Look at the list of possible parameter attributes below.
  6. Optionally decide which arguments and argument values you need to define for each parameter attribute defined in the previous step. Look at the list of possible arguments in the list below.
  7. Separate definition of each parameter with a comma “,” if more parameters will be created.
  8. Repeat the steps from 2 to 7 for each parameter definition.
  9. Test each defined parameter with correct calls to Advanced Function or CmdLet. You can test either after each parameter created or at the end when all parameters have been created.

We will use some of the listed attributes and arguments in the examples that will follow.

Here is Attributes List:

  • Parameter
  • Alias
  • AllowEmptyString (Validation Attribute)
  • AllowEmptyCollection (Validation Attribute)
  • ValidateCount
  • ValidateLength
  • ValidatePattern
  • ValidateRange
  • ValidateScript
  • ValidateSet
  • ValidateNotNull
  • ValidateNotNullOrEmpty
  • ValidateDrive
  • ValidateUserDrive
  • ArgumentCompleter

Here is Arguments List:

  • Mandatory
  • Position
  • ParameterSetName
  • ValueFromPipeline
  • ValueFromRemainingArguments
  • HelpMessage

PowerShell Parameters Examples

NOTE: I have written a library of CmdLets called Efficiency Booster PowerShell Project and I will use some of the CmdLets from the project in the examples.

Please feel free to download the zip file that contains the source code for the project so you can easily follow along.

Example 1 – Parameters of Get-CPUInfo CmdLet

Get-CPUInfo CmdLet is part of Common module and if you have downloaded the source code it can be found in the folder …\[My] Documents\WindowsPowerShell\Modules\03common

Get-CPUInfo CmdLet gets as result CPU properties from the list of computers and for this CmdLet, we have defined the following parameters:

  • computers
  • filename
  • errorlog
  • client
  • solution

Here is parameter definition code:

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename,
    [Parameter( Mandatory=$false,
                HelpMessage="Write to error log file or not.")]
    [switch]$errorlog,
    [Parameter(Mandatory=$true, 
                HelpMessage="Client for example OK = O client, BK = B client")]
    [string]$client,
    [Parameter(Mandatory=$true,
                HelpMessage="Solution, for example FIN = Financial, HR = Human Resource")]
    [string]$solution     
)

So let’s dive into each parameter, explain them and use previously defined steps on how to create the parameter.

Parameter computers

If we want to describe the “computers” parameter in “common” English it would be like this. We have created the parameter “computers” which is an array of strings with the default value of ‘localhost’. This parameter has an alternate or alias name of value ‘hosts’. The parameter can accept both values from the pipeline and values from the pipeline by property name. It belongs to the ‘ServerNames’ parameter set. The help message describes further this parameter to assist the users of CmdLet to apply the appropriate value.

Step 1 – We have defined the parameter between the param() statement.

IMPORTANT: This statement is used only once and contains all the parameters.

param ()

Step 2 – We gave the Name to the Parameter computers” starting with $ sign as PowerShell syntax demands.

param ( $computers ) 

Step 3 – In front of the parameter name we have defined between [ ] the
Parameter Data Type string[] representing an array of strings separated with “,”.

param ( [string[]]$computers )

Step 4 – This parameter has Default Value ‘localhost’ defined after the parameter name using “=”.

param ( [string[]]$computers = 'localhost' ) 

Step 5 – We have defined two Attributes for this parameter:

  • Alias
  • Parameter

We define the Attribute between [ ] and after attribute name, we define all the arguments inside the ( ).

param (
    [Parameter()]
    [Alias()] 
    [string[]]$computers = 'localhost'
)

Step 6 – For each attribute defined in the previous step, we define Arguments and Argument Values as needed within () after the attribute name.

The Alias attribute has a string argument defined between ( ) of value ‘hosts’.

param (
    [Parameter()]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost'
)

The Parameter attribute has several Arguments and Argument Values defined between ( ) after the attribute name. Separate each Argument = Argument Value pair with “,”. Here are all the arguments and arguments values define:

  • Argument ValueFromPipeline with Argument Value true which means that this parameter accepts value from pipeline
  • Argument ValueFromPipelineByPropertyName with Argument Value true which means that this parameter accepts value from the pipeline by property name.
  • Argument ParameterSetName with Argument Value “ServerNames” which means that this parameter belongs to “ServerNames” Parameter Set. If you want to read the article dedicated to PowerShell Parameter Sets please click here.
  • Argument HelpMessage with Argument Value defined as a string that further assist the user in which values to input for this parameter.
param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost'
)

Step 7 – We put “,” after computers parameter default value in order to define the next parameter.

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',
)

Step 8 – We repeat steps 2-7 for the next parameter which is the filename parameter.
Step 9 – Look the section How To Run PowerShell With Parameters of this article where I have tested all the parameters’ features using different examples of calling the CmdLet.

Parameter filename

The filename parameter is a string data type with no default value and no alias name basically it is the name of the text file that has a list of servers. It belongs to the FileName parameter set. Help message gives us the explanation that this parameter is actually the name of the text file with the list of servers in it.

Step 2 – We gave the Name to the parameter Filename starting with $ sign as PowerShell syntax demands.

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    $filename    
)

Step 3 – In front of the parameter name we have defined the Parameter Data Type as a string between [ ].

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [string]$filename    
)

Step 4 – No Default Value for this parameter.

Step 5 – This parameter has only one Attribute and that is [Parameter()]

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',
    [Parameter( )]   
    [string]$filename    
)

Step 6 – The Parameter attribute has two Arguments and Argument Values defined between () after the attribute name. Separate each argument = argument value pair with “,”. Here are all the arguments and arguments values defined.

  • Argument ParameterSetName with Argument value “FileName” which means that this parameter belongs to the “FileName” Parameter Set. If you want to read the article dedicated to PowerShell Parameter Sets please click here.
  • Argument HelpMessage with Argument value defined as a string that further assist the user in which values to input for this parameter.
param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename    
)

Step 7 – We put “,” after the filename parameter in order to define the next parameter.

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename,    
)

Step 8 – We repeat steps 2-7 for the next parameter which is the errorlog parameter.

REMEMBER: Look the section How To Run PowerShell With Parameters of this article where I have tested all the parameters’ features using different examples of calling the CmdLet.

Parameter errorlog

The errorlog parameter is interesting for its data type which is switch data type. That basically means if we pass this parameter to function call parameter value is true (turned on) and if we do not pass it the parameter value is false (turned off). Otherwise, this is a parameter with no default value, no alias, and it is not mandatory which means it is optional.

Step 2 – We gave the Name to the parameter errorlog starting with $ sign as PowerShell syntax demands.

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename,
    $errorlog   
)

Step 3 – In front of the parameter name we have defined the Parameter Data Type as switch between []. That means this parameter has no input values and can be true if passed or false if not passed.

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename,
    [switch]$errorlog   
)

Step 4 – No Default Value for this parameter.

Step 5 – This parameter has only one Attribute and that is [Parameter()]

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename,
    [Parameter( )]
    [switch]$errorlog   
)

Step 6 – The Parameter attribute has two Arguments and Argument Values defined between () after the attribute name. Separate each argument = argument value pair with “,”. Here are all the arguments and arguments values defined.

  • Argument Mandatory with Argument value false which means that errors will not be logged by default.
  • Argument HelpMessage with Argument value defined as a string that further assist the user in which values to put for this parameter.
param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename,
    [Parameter( Mandatory=$false,
                HelpMessage="Write to error log file or not.")]
    [switch]$errorlog   
)

Step 7 – We put “,” after the errorlog parameter in order to define the next parameter.

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename,
    [Parameter( Mandatory=$false,
                HelpMessage="Write to error log file or not.")]
    [switch]$errorlog,   
)

Step 8 – We repeat steps 2-7 for the next parameter which is the client parameter.

REMEMBER: Look the section How To Run PowerShell With Parameters of this article where I have tested all the parameters’ features using different examples of calling the CmdLet.

Parameter client

The Client parameter is a mandatory parameter of the string data type. My convention is to use two characters for this parameter, but it is not limited to two characters. For example, ImproveScripting as a client would be IS.

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename,
    [Parameter( Mandatory=$false,
                HelpMessage="Write to error log file or not.")]
    [switch]$errorlog,
    [Parameter(Mandatory=$true, 
                HelpMessage="Client for example OK = O client, BK = B client")]
    [string]$client    
)

REMEMBER: Look the section How To Run PowerShell With Parameters of this article where I have tested all the parameters’ features using different examples of calling the CmdLet.

Parameter solution

The Solution parameter is a mandatory parameter of the string data type. I am coming from the ERP world and usually, ERP clients have Financial and HR installations so values for the solution parameter would be: FIN for Financial solution and HR for Human Resource solution but you can come up with your own solution values.

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename,
    [Parameter( Mandatory=$false,
                HelpMessage="Write to error log file or not.")]
    [switch]$errorlog,
    [Parameter(Mandatory=$true, 
                HelpMessage="Client for example OK = O client, BK = B client")]
    [string]$client,
    [Parameter(Mandatory=$true,
                HelpMessage="Solution, for example FIN = Financial, HR = Human Resource")]
    [string]$solution     
)

REMEMBER: Look the section How To Run PowerShell With Parameters of this article where I have tested all the parameters’ features using different examples of calling the CmdLet.

Example 2 – Script Block Parameter Of Measure-BenchmarksCmdLet CmdLet

Source code: Download from here
Project: Efficiency Booster PowerShell Project
Module: Utils
Script Location: …\[My] Documents\WindowsPowerShell\Modules\02utils

For Measure-BenchmarksCmdLet CmdLet I have created a $ScriptBlock parameter of the ScriptBlock data type and it is a mandatory parameter.

INFO: Measure-BenchmarksCmdLet CmdLet is used to benchmark the code and give you information about how long it takes for some code to run, how many objects (rows) are in resultset, etc. I will write about this awesome CmdLet in some future posts so bookmark my blog and come back to read about it soon! For now, look at the result of this CmdLet below.

param (
    [Parameter(Mandatory=$true)] 
    [ScriptBlock]$ScriptBlock,
    [Parameter( Mandatory=$false,
                HelpMessage="Write to error log file or not.")]
    [switch]$errorlog
)
Resultset of Measure-BenchmarksCmdLet CmdLet

Example 3 – InputObject Parameter of Save-ToExcel CmdLet

Source code: Download from here
Project: Efficiency Booster PowerShell Project
Module: Utils
Script Location: …\[My] Documents\WindowsPowerShell\Modules\02utils

For Save-ToExcel CmdLet I have created a $InputObject parameter of the PSobject data type. This parameter process the result from some CmdLet that has been pipelined into Save-ToExcel CmdLet and saves that result as Excel Sheet.

INFO: Save-ToExcel CmdLet is a very effective CmdLet that saves the result of CmdLet as an Excel Sheet using pipelining. I will write about this awesome CmdLet and PowerShell Pipelines in some future posts so bookmark my blog and come back to read about them soon! For now, look at the result of this CmdLet below.

UPDATE: Here is the post that explains everything you want to know about Excel and PowerShell. How To Create, Write And Save An Excel File Using PowerShell.

There are many other parameters in this CmdLet but I wanted to emphasize the $InputObject parameter.

param (
    [Parameter(Mandatory=$true,
                ValueFromPipeline=$true, 
                HelpMessage="Input rows to be saved as Excel file.")] 
    [PSobject[]]$InputObject,    
    [Parameter(Mandatory=$true, 
                HelpMessage="Excel file name.")]
    [string]$ExcelFileName,    
    [Parameter(Mandatory=$true, 
                HelpMessage="Excel workbook title.")]
    [string]$title,    
    [Parameter(Mandatory=$true, 
                HelpMessage="Excel workbook author.")]
    [string]$author,    
    [Parameter(Mandatory=$true, 
                HelpMessage="Excel worksheet name.")]
    [string]$WorkSheetName,    
    [Parameter(HelpMessage="Write to error log file or not.")]
    [switch]$errorlog,    
    [Parameter( HelpMessage="Send email.")]
    [switch]$sendemail,    
    [Parameter(Mandatory=$true, 
                HelpMessage="Client for example OK = O client, BK = B client")]
    [string]$client,     
    [Parameter(Mandatory=$true,
                HelpMessage="Solution, for example FIN = Financial solution, HR = Humane Resource solution")]
    [string]$solution  
)
Resultset of Save-ToExcel CmdLet

Example 4 – Status Parameter with ValidateSet Attribute in Get-Printer CmdLet

Source code: Download from here
Project: Efficiency Booster PowerShell Project
Module: Common
Script Location: …\[My] Documents\WindowsPowerShell\Modules\03common

For Get-Printers CmdLet I have created a $status parameter that is string data type, it is not mandatory, has default value ‘Error’ but what is interesting with this parameter is the ValidateSet attribute with three possible values: “All”, “Offline”, “Error”.

The ValidateSet attribute specifies a set of valid values for a parameter or variable. PowerShell generates an error if a parameter or variable value doesn’t match a value in the set. It is part of PowerShell input values validation.

INFO: Get-Printers CmdLet list all the printers on the local machine or for the list of servers. It is possible to additionally filter the resultset. I will write about this fabulous CmdLet in some future posts so bookmark my blog and come back to read about it soon! For now, look at the result of this CmdLet below.

There are many other parameters in this CmdLet but I wanted to emphasize the $status parameter due to the use of the ValidateSet attribute.

param (
    [Parameter( ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                ParameterSetName="ServerNames",
                HelpMessage="List of computer names separated by commas.")]
    [Alias('hosts')] 
    [string[]]$computers = 'localhost',
    
    [Parameter( ParameterSetName="FileName",
                HelpMessage="Name of txt file with list of servers. Txt file should be in 01servers folder.")] 
    [string]$filename,
    
    [Parameter(Mandatory=$false,
                HelpMessage="Status of printer. Values (All, Offline, Error).")]
    [ValidateSet("All", "Offline", "Error")] 
    [string]$status = 'Error',
    
    [Parameter( Mandatory=$false,
                HelpMessage="Write to error log file or not.")]
    [switch]$errorlog,
    
    [Parameter(Mandatory=$true, 
                HelpMessage="Client for example OK = O client, BK = B client")]
    [string]$client,
     
    [Parameter(Mandatory=$true,
                HelpMessage="Solution, for example FIN = Financial, HR = Human Resource")]
    [string]$solution     
)
Resultset of Get-Printer CmdLet

How To Run PowerShell With Parameters

When we run PowerShell CmdLet with parameters we use the following general syntax:

CmdLet-Name -ParameterName <Parameter Value> 

Example 1 – Call To Get-Service CmdLet With Parameter Name

Here we call Get-Service CmdLet (CmdLet-Name) with parameter Name (-ParameterName) and parameter value “WSearch” ( <Parameter Value> )

Get-Service -Name "WSearch"
Get-Service CmdLet resultset

Example 2 – Call To PowerShell Script (.ps1) With Parameters

We can write a short PowerShell script ( TestParameter.ps1 ) that has one input parameter and call Get-Service CmdLet like in the previous example:

Param
     (
     [string]$WSname="*"
     )
Get-Service -Name $WSname

If we want to run the PowerShell script with parameters we use syntax like in the following example:

.\TestParameter.ps1 -WSname "WSearch"

Example 3 – Test Parameters Of Our Own PowerShell CmdLets Or Advanced Functions

We have created parameters for our own CmdLets or Functions according to certain needs and specifications. So now it is time to test each of the parameter’s features and see if they work the way we want them to work.

This is Step 9 of How To Create PowerShell Parameters section which is a test of each parameter feature with an appropriate call to CmdLet.

As the test example, I will use one of my own CmdLets Get-CPUInfo that is part of the Efficiency Booster PowerShell Project. We have already created parameters for this CmdLet so now it is a time to test them.

Just as a reminder I will list all Parameters, Attributes, Arguments created for this CmdLet and we will test each of them.

Here are Parameters of Get-CPUInfo CmdLet:

  • computers
  • filename
  • errorlog
  • client
  • solution

Here are all the Attributes of Get-CPUInfo CmdLet:

  • Alias
  • Parameter

Here are all the Arguments of Get-CPUInfo CmdLet:

  • Mandatory
  • ValueFromPipeline
  • ValueFromPipelineByPropertyName
  • ParameterSetName
  • HelpMessage

Test of CmdLet: Get-CPUInfo – Parameter: client – Argument: Mandatory

Reminder: We have set up parameter “client” with the argument Mandatory
What are we testing? – We test if PowerShell will prompt us to enter the value for the “client” parameter if we do not provide it with the call to Get-CPUInfo CmdLet.

If I just run Get-CPUInfo CmdLet without providing any parameter PowerShell will check the syntax and ask for inputs to mandatory parameters. This CmdLet has two mandatory parameters: client and computers. The first mandatory Parameter is “client” and PowerShell sees that and asks as to provide value for mandatory input parameter so our Mandatory=$true argument and argument value defined within Parameter Attribute of “client” parameter is working and we have just tested it.

Conclusion: PowerShell halted the execution of Get-CPUInfo CmdLet until we provide the value for mandatory parameter “client” so the test was successful.

Get-CPUInfo
Client parameter of Get-CPUInfo CmdLet

Test of CmdLet: Get-CPUInfo – Parameter: client – Argument: HelpMessage

Reminder: We have written a Help message for parameter “client“.
What are we testing? – We test the help message text.

Let’s pretend that we do not know what right value for client parameter is so what we can do. We have a suggestion to type !? for Help so let’s do that and see if this can provide us some useful information.

HelpMessage Argument give us help content (Hint)

As helpful tips and feedback, we got the message from the HelpMessage Argument for the “client” parameter. So we have tested HelpMessage argument and argument value with this test.

Now we can type one of the suggested values for example, “ok”.

Conclusion: We have tested the HelpMessage Argument of the “client” parameter.

REMEMBER: Help-Message Argument is not the same as Comment-Based Help for the same parameter. In order to understand the differance please read the section Difference Between Comment-Based Help And Parameter’s HelpMessage Argument

Test of CmdLet: Get-CPUInfo – Parameter: solution – Argument: Mandatory

Reminder: We have set up the parameter “solution” to be mandatory as well.
What are we testing? – We test a mandatory argument of the “solution” parameter.

We got the prompt to provide the input value for the next mandatory parameter and that is the “solution” parameter.

Conclusion: So we have tested now Mandatory=$true argument and argument value of the “solution” parameter.

We entered a suggested value for client parameter

Test of CmdLet: Get-CPUInfo – Parameter: solution – Argument: HelpMessage

Reminder: We have written a Help message for parameter “solution
What are we testing? – We test the help message text.

We already know that we can get help for an input parameter if we type “!?” so let’s do that for the “solution” parameter and check what kind of helpful message we will get.

We got the message text from the HelpMessage Argument which is part of the Parameter Attribute of the “solution” parameter.

Conclusion: So we have tested HelpMessage Argument and Argument Value for the “solution” parameter with this call.

REMEMBER: Help-Message Argument is not the same as Comment-Based Help for the same parameter. In order to understand the differance please read the section Difference Between Comment-Based Help And Parameter’s HelpMessage Argument

Help Message suggestions for the solution parameter

Let’s type one of the suggested values for example, “fin” and since in Get-CPUInfo CmdLet has no more mandatory parameters then the rest of the CmdLet code can run and we get the result of CmdLet.
As a result, we get the CPU properties of the local machine since the “computers” parameter has the default value of the ‘localhost’.

Get-CPUInfo CmdLet resultset

So far we have learned that Get-CPUInfo CmdLet has two mandatory parameters and both parameters help messages provide helpful pieces of information. Basically we have tested Mandatory and HelpMessage Arguments and Argument Values for parameters: client, and solution.

Based on this discovery let’s continue with testing other parameters and their attributes, arguments and argument values.

Test of CmdLet: Get-CPUInfo – Parameter: computers – Default Value AND Default Parameter Set “ServerNames”

Reminder: We have set up the default value for the parameter “computers” = localhost and we have defined default parameter set “ServerNames
What are we testing? – We test the default value for the parameter “computers” and the default parameter set.

If we call Get-CPUInfo with input values for mandatory parameters we get the result of CPU properties for the local machine without explicitly writing the name of the local machine. Why is that? There are three reasons:

  1. computers parameter has the Default Value of ‘localhost’
  2. The Default Parameter Set is “ServerNames” that we have defined in the CmdletBinding attribute using DefaultParametersetName argument to define the default parameter set. [CmdletBinding(DefaultParametersetName=”ServerNames”)]
  3. Finally, the parameter computers” belongs to the “ServerNamesparameter set. We have set ParameterSetName argument of the parameter “computers ” to
    ParameterSetName=”ServerNames”

Conclusion: This CmdLet call tests default value of the parameter “computers“, and default parameter set that this parameter belongs to.

Get-CPUInfo -client ok -solution fin
Get-CPUInfo CmdLet resultset

IMPORTANT: If you want to read the dedicated article for PowerShell Parameter Sets with many awesome examples please click here.

Test of CmdLet: Get-CPUInfo – Parameter: Verbose

Reminder: We have defined Get-CPUInfo as CmdLet using [CmdletBinding()] attribute and that means we can use common parameters that belong to every CmdLet like Debug, ErrorAction, Verbose, etc with this CmdLet.
What are we testing? – We will test the Verbose common parameter.

We see that beside results we get different Verbose lines since we turned on Verbose parameter Get-CPUInfo CmdLet and if you want to know why is that. The reason is that we have implemented Write-Verbose CmdLet in certain parts of Get-CPUInfo CmdLet code so we basically get a workflow of our code execution.

Conclusion: We have successfully tested the Verbose common parameter with this call.

Get-CPUInfo -client "OK" -solution "FIN" -Verbose
Test of Verbose common parameter

TIP: I highly recommend to everyone to implement Write-Verbose CmdLet in your own Function scripts since it can be very useful as part of the Debugging process and can show you which parts of your code have been executed.

IMPORTANT: If you want to know more about debugging PowerShell code please read this article where I explain everything I know about debugging. (Line, Variable, Command breakpoints, Useful keyboard shortcuts, How To Debug and much more…)

Test of CmdLet: Get-CPUInfo – Parameter: errorlog

Reminder: We have set the “errorlog” switch parameter that will turn on or off the logging of CmdLet errors into the external Error Log text file.
What are we testing? – We test switch “errorlog” parameter and in this call example, we break the code on purpose.
Conclusion: We do not get results since CmdLet experience error but we got warning lines due to implementation of Write-Warning CmdLet in our Get-CPUInfo CmdLet error handling code.

'ERROR' | Get-CPUInfo -client "OK" -solution "FIN" -errorlog
Test of errorlog parameter
Write-Warning CmdLet implemented in Get-CPUInfo CmdLet
The error is also written in the external Error Log text file

IMPORTANT: Learn more about PowerShell Error Handling with lots of examples and how to log the errors in an external Error Log text file reading this article.

Test of CmdLet: Get-CPUInfo – Parameter: computers

Reminder: We have set up computers parameter as a string of arrays type
What are we testing? – We test the “computers” parameter with a single string value.
Conclusion: We got the result from the local machine as expected

Get-CPUInfo -computers 'localhost' -client "OK" -solution "FIN" -errorlog
Test of computers parameter with a single input value

Test of CmdLet: Get-CPUInfo – Parameter: computers

Reminder: We have set up the “computers” parameter as a string of arrays data type
What are we testing? – We test the “computers” parameter with an array of values
Conclusion: We got the result for two computers as expected so data type is correct.

Get-CPUInfo -computers 'localhost','localhost'  -client "OK" -solution "FIN" -errorlog
Test of computers parameter with an array of values

Test of CmdLet: Get-CPUInfo – Parameter: computers – Attribute: Alias

Reminder: We have set up the “computers” parameter to use alias “hosts
What are we testing? – We will use alias “hosts” instead of “computers
Conclusion: We got the result as expected so alias “hosts” works.

Get-CPUInfo -hosts 'localhost' -client "OK" -solution "FIN" -errorlog
Test of computers parameter alias value as host

Test of CmdLet: Get-CPUInfo – Parameter: computers – Attribute: Parameter – Argument: ValueFromPipeline

Reminder: We have set up the “computers” parameter to accept input from the pipeline by value using the ValueFromPipeline argument of the Parameter attribute. ValueFromPipeline=$true
What are we testing? – We test whether the “computers” parameter accepts inputs by value from the pipeline.

So we send the ‘localhost’ string value in the pipeline and expect that pipeline will link this value to the “computers” parameter.

Conclusion: We got the result as expected for both single string value and an array of string values send into the pipeline.

'localhost' | Get-CPUInfo -client "OK" -solution "FIN" -errorlog

'localhost', 'localhost' | Get-CPUInfo -client "OK" -solution "FIN" -errorlog
A single value in pipeline and test of ValueFromPipeline argument
An array of values in pipeline and test of ValueFromPipeline argument

Test of CmdLet: Get-CPUInfo – Parameter: computers – Attribute: Parameter – Argument: ValueFromPipelineByPropertyName

Reminder: We have set up the “computers” parameter to accept values from the pipeline by property name using ValueFromPipelineByPropertyName argument of the Parameter attribute. ValueFromPipelineByPropertyName=$true
What are we testing? – We test the “computers” parameter whether accepts values from the pipeline by property name.

  • First, we define two string values (localhost and localhost) and send them further to the pipeline using pipeline sign “|”, as we did in the previous example.
  • Second, we label these two string input values to have the same column result name as the input parameter. Notice label computers” has the same value as the input parameter computers“. We do not want to pass just two localhost values since that would be pipeline by value. We want to pipeline values by property name.
  • Third, we send that resultset further down the pipeline “|” to our Get-CPUInfo CmdLet.
  • Next, PowerShell will see that values passed into the pipeline are labeled as “computers” and Get-CPUInfo CmdLet has a parameter called “computers” as well so it will match the label with the parameter and process the values.
  • Finally, we get the result as expected.

Conclusion: We have successfully tested ValueFromPipelineByPropertyName argument of our Get-CPUInfo CmdLet

'localhost', 'localhost' | Select-Object @{label="computers";expression={$_}}
Values from pipeline labeled as computers
 'localhost', 'localhost' | Select-Object @{label="computers";expression={$_}} | Get-CPUInfo -client "OK" -solution "FIN" -errorlog
Test of ValueFromPipelineByPropertyName argument

Test of CmdLet: Get-CPUInfo – We Test Comment-Based Help

Reminder: We have not covered in this article writing of comment-based help but if you want to know more on the subject please read this article where I have covered writing of comment-based help.
What are we testing? – This is not a test of any parameter just test of help content.
Conclusion: As you can see on the screenshot below we got the help of the Get-CPUInfo CmdLet.

Help Get-CPUInfo -Full
Test of comment-based help for Get-CPUInfo CmdLet

IMPORTANT: I have written two articles on the subject of comment-based help in PowerShell. How To Write PowerShell Function’s Or CmdLet’s Help (Fast) article explains how to use PowerShell ISE Add-on to get Help template fast and How To Write PowerShell Help (Step by Step) article has more detailed approach to writting comment-based help.

Test of CmdLet: Get-CPUInfo – Parameter: filename

Reminder: We have set up parameter “filename” which will accept the name of a text file with the list of servers.
What are we testing? – We test the “filename” parameter and Parameter Set “FileName” whom this parameter belongs to.
Conclusion: We got the result as expected so the test was successful.

Get-CPUInfo -filename "OKFINservers.txt" -errorlog -client "OK" -solution "FIN" | Out-GridView
Test of the filename parameter
Resultset of Get-CPUInfo CmdLet using the filename parameter

Difference Between Comment-Based Help And Parameter’s HelpMessage Argument

When you write a Comment-Based Help for parameters you can describe each parameter in that help using the PARAMETER keyword. However, this help content has a different purpose than help content in HelpMessage Argument when you define a parameter in the function.

If you want to know more about Comment-Based Help with Step by Step guidance on how to create it please read this article.

When a parameter has been described with (.PARAMETER help keyword) that will be shown and helpful to the user only when Get-Help (help or man) commands are called for actual CmdLet and not when you run that same CmdLet. However, Help message text is useful when you run actual CmdLet and use “!?” for the parameter description.

Let me explain with examples.

Comment-Based Help

If we run the following command we get comment-based help for that parameter of the CmdLet but comment-based help content cannot assist us when we run Get-CPUInfo CmdLet.

Get-Help Get-CPUInfo -Parameter client
Text from comment-based help

HelpMessage Argument text

If we call Get-CPUInfo CmdLet without providing any parameter and parameter value.

Get-CPUInfo

PowerShell will ask us to provide the values for mandatory parameters and gives us the opportunity to know more about this parameter if we type “!?“.

As a result, we get a text from the HelpMessage argument that should be useful information to the user of CmdLet and help the user by giving good suggestions about the correct parameter value.

Now we can type one of the suggested values and continue. So here HelpMessage argument text has been used and not the PARAMETER keyword comment-based help content.

Text from HelpMessage argument

About Splatting

The traditional method of passing parameters to CmdLet is providing CmdLet name and then add all necessary parameters as parameter and parameter value combination like in the following example:

Get-CimInstance -ComputerName 'localhost' -ClassName 'Win32_Processor' -ErrorAction Stop

This works just fine but when we have so many parameters our code gets cluttered so we can use splatting instead.

Splatting is a more convenient method to pass parameters and parameters’ values combination, especially when there are so many of them, to the CmdLet as a single unit.

Splatting can be done in two ways:

  • Splatting with hash tables
  • Splatting with arrays

TIP: Personally I prefer splatting with hash tables and this is a matter of personal preferences.

Let me first explain the steps to follow in order to implement splatting and then we can see a few examples.

Follow these steps to implement splatting

  • Define hash table or array
  • Hash table consists of parameter-name and parameter-values pairs
  • For array splatting, we provide only parameter values and this method is used positional parameters, which do not require parameter names.
  • Assign hash table or array to a variable
  • When we call CmdLet we just provide the name of variable replacing dollar sign symbol $ with the At symbol @

Example – Splatting With Hash Tables

Here is an example:

$params = @{ 'ComputerName'='localhost';
             'Class'='Win32_Processor';
             'ErrorAction'='Stop'}

Get-CimInstance @params

Let’s quickly explain this code:

  • First, we defined a hash table as pairs of parameter-name and parameter-value.

NOTE: ComputerName, Class, ErrorAction are actual parameters of Get-CimInstance CmdLet

@{ 'ComputerName'='localhost';
                         'Class'='Win32_Processor';
                         'ErrorAction'='Stop'}
  • Second, we assign a hash table to variable $params
$params = @{ 'ComputerName'='localhost';
             'Class'='Win32_Processor';
             'ErrorAction'='Stop'}
  • Finally, we use a variable as a whole one unit in CmdLet call instead of providing each parameter name and value separately as we do in “traditional” syntax.

IMPORTANT: Notice that we have $params with @params, basically we replaced dollar symbol $ with At symbol @ and that replacement is splatting.

Get-CimInstance @params

Compare (splatting) syntax:

$params = @{ 'ComputerName'='localhost';
             'Class'='Win32_Processor';
             'ErrorAction'='Stop'}

Get-CimInstance @params

with (traditional) syntax:

Get-CimInstance -ComputerName 'localhost' -ClassName 'Win32_Processor' -ErrorAction Stop

I hope we agree that splatting looks much more readable!


Example – Splatting With An Array

Here is an example:

$params = '.\servers.txt', '.\servers1.txt'  

Copy-Item @params -ErrorAction Stop

Copy-Item CmdLet has these positional parameters:

  • The Path parameter is on position 0
  • The Destination parameter is on position 1

What we have done in this example is:

  • Defined array with values for two positional parameters
  • Assign array to variable $params
  • Run Copy-Item CmdLet with splatting and added one more parameter that is not positional (ErrorAction )

Useful PowerShell Parameters Articles

Here are some useful articles and resources:

About Dejan Mladenović

Post Author Dejan MladenovicHey Everyone! I hope that this article you read today has taken you from a place of frustration to a place of joy coding! Please let me know of anything you need for Windows PowerShell in the comments below that can help you achieve your goals!
I have 18+ years of experience in IT and you can check my Microsoft credentials. Transcript ID: 750479 and Access Code: DejanMladenovic
Credentials
About Me...

My Posts | Website

Dejan Mladenović

Hey Everyone! I hope that this article you read today has taken you from a place of frustration to a place of joy coding! Please let me know of anything you need for Windows PowerShell in the comments below that can help you achieve your goals! I have 18+ years of experience in IT and you can check my Microsoft credentials. Transcript ID: 750479 and Access Code: DejanMladenovic
Credentials About Me...

Recent Posts