PowerShell: How to Define and Use Functions — Part 1

Bruce Wen
Code.Art
Published in
5 min readMay 21, 2023

--

Code reuse is always the number one priority for developers.

PowerShell — Function Part 1 — Created with PowerPoint by Author

1. Function Basic Definition

To define a function in PowerShell could be simple. For example, we can define one function to say “Hello, World!” as following in PowerShell prompt:

> function hello_world(){
Write-Output "Hello, World!"
}

And run it:

> hello_world
Hello, World!

2. Function Name

The valid function name could be consists of characters “_, — ,[a-zA-Z], [0–9]”. So, “hello-world, _1, Hello-World, _HelloWorld” are also valid function names. The function name should not be the same as those known reserved keywords or commands or numbers only. For example, pure numbers cannot be used as function name — We cannot name a function as “1” or “-1”, but we can name it as “_1” if we want. Another example, afunction with the keyword “for” as name can be defined but won’t be never used.

> function for(){
>> Write-Output "Hello, World!"
>> }
> for
>>

You are not allowed to break the PowerShell language by customized functions. 😃

And don’t do any extremely thing like the below one to make big trouble for yourself. But nobody can stop you to try.

> function Write-Output() {
>> Write-Output "Hello, World!"
}
> Write-Output

Gods know what will happen after typing Enter key. Trust me, you have to use “Ctrl-C” for many times to get back to the prompt.

Well, the recommended function name should follow the naming rule: PascalCasing and “<ApprovedVerb>-<Prefix><SingularNoun>”.

There is a list of “Approved Verbs for PowerShell Commands” and they are suggested to use in function name.

As a coder, we should always use follow the general conventions to write code. Therefore, in PowerShell world, the function name hello_world is not more popular than Write-HelloWorld which follows the naming rule <ApprovedVerb>-<Prefix><SingularNoun>.

3. Function Parameters

To reuse the static logic, parameters are often used in function definition to handle variants.

There are several different ways to define function with parameters:

syntax 1:

function <name> [([type]$parameter1[,[type]$parameter2])] {       
<statement list>
}

In this syntax, [type] is optional.

Example:

> function Write-Hello([String] $name){
Write-Output "Hello, $name"
}
> hello "Bruce"
Hello, Bruce

# without [String] also works
> function Write-Hello($name){
Write-Output "Hello, $name"
}
> hello "Bruce"
Hello, Bruce

syntax 2:

function <name> {
param ([type]$parameter1 [,[type]$parameter2])
<statement list>
}

In this syntax, the keyword param is required to tell the variable $parameter is a param rather than a local variable or global variable.[type] is optional.

Example:

> function Write-Hello{
>> param ([String] $name)
>> Write-Output "Hello, $name"
>> }
> hello "Bruce"
Hello, Bruce

# without [String] also works
> function Write-Hello{
>> param ($name)
>> Write-Output "Hello, $name"
>> }
> hello "Bruce"
Hello, Bruce

# without param and [String] will work in unexpected way
> function Write-Hello{
>> ($name)
>> Write-Output "Hello, $name"
>> }
# when $name is not defined before function definition
> Write-Hello "Bruce"
Hello,
# when $name is defined before function definition
> $name = "Bruce"
> Write-Hello "Bruce"
Bruce
Hello, Bruce

As you see, if the keyword param is not provided, the function behavior will not the same as expected — the passed parameter is not handled and recognized at all. Instead, the global variable, if exists, will be used. That should not the intention of the function definition.

📓Note: type in [type] could be any supported type in PowerShell. For example, to accept multiple values as value of the parameter, we can set type as String[] — — — an array of String.

> function Write-Hello([String[]] $names) {
>> foreach ($name in $names) {
>> Write-Output "Hello, $name"
>> }
>> }
> Write-Hello "Bruce", "Alice"
Hello, Bruce
Hello, Alice

3. Advanced Function Parameter

Sometimes, not all parameters have be specified, some of them could have default values. Meanwhile, some parameters must be specified by the caller if it’s not possible to set default value.

So, how to set default value of the parameters, and how to tell which parameters are mandatory?

This is the advanced function parameter scope.

To set default value of parameter, use format [type] $paramName = defaultValue .

> function Write-Hello($name="Bruce"){
>> Write-Output "Hello, $name"
>> }
> Write-Hello
Hello, Bruce
> Write-Hello "Alice"
Hello, Alice

To make the parameter mandatory, set paramter in function body and use Parameter attribute Mandatory = $true :

> function Write-Hello(){
>> Param(
>> [Parameter (Mandatory=$True)]
>> [String] $name
>> )
>> Write-Output "Hello, $name"
>> }
> Write-Hello "Bruce"
Hello, Bruce

# if the mandatory parameter is not provided in command line,
# then it will forcely ask you to provide
> Write-Hello

cmdlet Write-Hello at command pipeline position 1
Supply values for the following parameters:
name: Bruce
Hello, Bruce

# if the mandatory parameter is empty (click Enter directly when asked),
# then it will fail with error
> Write-Hello

cmdlet Write-Hello at command pipeline position 1
Supply values for the following parameters:
name:
Write-Hello : Cannot bind argument to parameter 'name' because it is an empty string.
At line:1 char:1
+ Write-Hello
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Write-Hello], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Write-Hello

Conclusion

  • In this article, we learnt how to define a simple PowerShell function, how to define and use function parameter in basic and advance level.
  • PowerShell function and variables naming rule were explained. We’d better to follow the general naming rule to make it more redable for PowerShell users.
  • It’s not recommended to use build-in function name as new created function name. It will result in unexpected and big trouble.

--

--