Um momento
0xA0Lesson 11 of 17

Functions and parameters

Write your own cmdlet-style functions with typed, validated parameters and pipeline input.

32 min 7-question quiz 2 code exercises
By the end of this lesson you can
  • Define functions with param() blocks, types, defaults and switches
  • Validate input with Mandatory and Validate* attributes
  • Accept pipeline input with begin/process/end, and avoid accidental output

A function is a named script block. Give it a Verb-Noun name and a param() block, and it works just like a built-in cmdlet - named parameters, tab completion and all:

1function Get-FeedingAmount {
2  param(
3    [int]$Wingspan,
4    [switch]$Hungry,
5    [string]$Food = 'goats'
6  )
7  $kg = $Wingspan * 3
8  if ($Hungry) { $kg *= 2 }
9  "$kg kg of $Food"
10}
11Get-FeedingAmount -Wingspan 12 -Hungry      # 72 kg of goats

Call it like a cmdlet - no parentheses, no commas. Get-FeedingAmount(12, $true) passes a single array to the first parameter, a classic mistake.

functions.ps1
1function Get-FeedingAmount {
2  param(
3    [int]$Wingspan,
4    [switch]$Hungry,
5    [string]$Food = 'goats'
6  )
7  $kg = $Wingspan * 3
8  if ($Hungry) { $kg *= 2 }
9  "$kg kg of $Food"
10}
11Get-FeedingAmount -Wingspan 12
12Get-FeedingAmount -Wingspan 12 -Hungry
13Get-FeedingAmount 2 -Food 'lantern moths'
Output
36 kg of goats
72 kg of goats
6 kg of lantern moths

Everything is output

Here’s the most surprising thing about PowerShell functions: every value that isn’t captured becomes part of the result, not just what follows return. return simply exits early (optionally outputting one more value).

So a stray method call that returns something - $list.Add('x') returns the new index, for example - leaks into your output. Silence it with $null = ..., [void](...) or | Out-Null.

output-leak.ps1
1function Get-Names {
2  $list = [System.Collections.ArrayList]::new()
3  $list.Add('Ember')
4  $list.Add('Glim')
5  return $list
6}
7function Get-NamesQuietly {
8  $list = [System.Collections.ArrayList]::new()
9  $null = $list.Add('Ember')
10  [void]$list.Add('Glim')
11  $list
12}
13(Get-Names) -join ','
14(Get-NamesQuietly) -join ','
Output
0,1,Ember,Glim
Ember,Glim

Advanced functions

Add [CmdletBinding()] above param() and your function becomes an advanced function: it gains the common parameters (-Verbose, -ErrorAction, ...) and can use parameter attributes:

AttributeEffect
[Parameter(Mandatory)]PowerShell asks for (or errors without) the value
[Parameter(ValueFromPipeline)]the parameter receives pipeline objects
[ValidateSet('Wyrm', 'Wisp')]only these values (and tab completion offers them!)
[ValidateRange(1, 30)]numbers must be in range
[ValidateNotNullOrEmpty()]rejects $null and ''
[ValidatePattern('^DRG-\d{4}$')]must match a regex

To take pipeline input, mark a parameter ValueFromPipeline and put the work in a process {} block, which runs once per incoming object. begin {} runs once before the first, and end {} once after the last.

advanced.ps1
1function New-DragonTag {
2  [CmdletBinding()]
3  param(
4    [Parameter(Mandatory, ValueFromPipeline)]
5    [ValidateNotNullOrEmpty()]
6    [string]$Name,
7    [ValidateRange(1, 9999)]
8    [int]$Start = 1
9  )
10  begin   { $number = $Start }
11  process {
12    'DRG-{0:D4} {1}' -f $number, $Name
13    $number++
14  }
15  end     { Write-Verbose "Tagged up to $number" }
16}
17'Ember', 'Glim', 'Skyla' | New-DragonTag -Start 40
18try { New-DragonTag -Name 'Pebble' -Start 0 } catch { 'Rejected: Start must be 1 to 9999' }
Output
DRG-0040 Ember
DRG-0041 Glim
DRG-0042 Skyla
Rejected: Start must be 1 to 9999

Key takeaways

  • Functions take a param() block with types, defaults and [switch] parameters; call them like cmdlets.

  • Every uncaptured value is output - silence noisy calls with $null = or [void].

  • [CmdletBinding()] plus [Parameter()] and [Validate*()] attributes give you robust, cmdlet-grade input.

  • ValueFromPipeline with begin/process/end makes a function work in pipelines.

Lesson quiz

7 questions · pass with 5 correct · up to 50 XP

Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.

Practice: write PowerShell scripts

Write a script in the editor and run it for real against sample input, which is piped into your script as $input. Scripts run on PowerShell 6.2 through Try It Online (tio.run), a free public service, so these exercises avoid PowerShell 7-only syntax; your script and test input are sent there.

Exercise 1

Feeding calculator

+25 XP

Write Get-FeedingAmount with parameters -Wingspan (an [int], which must be from 1 to 30 - use [ValidateRange]) and a -Hungry switch. A dragon eats 3 kg per metre of wingspan, doubled when hungry. It returns just the number.

Each input line is a wingspan, optionally followed by hungry. The starter splits the line for you; call your function and print 12 m: 36 kg or 12 m (hungry): 72 kg.

  • Three dragons
  • A big one
script.ps1
Loading editor…

Lessons teach PowerShell 7; your script runs on PowerShell 6.2 via Try It Online (tio.run), a free public service, so stick to syntax that works there. Test input is piped into your script as $input. Your script and test input are sent to that service.

Exercise 2

Tag them through the pipeline

+25 XP

Write an advanced function New-DragonTag that takes dragon names from the pipeline and outputs DRG-0001 Ember, DRG-0002 Glim, ... numbering from 1 with four digits. When the pipeline is finished, it outputs tagged 2 dragons. The starter pipes the input into it.

Use begin, process and end, and the format {0:D4}.

  • Two dragons
  • Four dragons
script.ps1
Loading editor…

Lessons teach PowerShell 7; your script runs on PowerShell 6.2 via Try It Online (tio.run), a free public service, so stick to syntax that works there. Test input is piped into your script as $input. Your script and test input are sent to that service.

Questions about this lesson

Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.

Loading posts…

Gostou da aula? 😆👍
Apoie nosso trabalho com uma doação: