Checking Input: Validation Attributes

Validation attributes check a parameter's value before any line of the function runs: [ValidateSet()] allows only a list of choices and makes Tab fill them in, [ValidateRange()] keeps a number between two limits, [ValidateNotNullOrEmpty()] turns away an empty value, and Mandatory asks for one that's missing.

Journeyman · PowerShell · Updated

After this lesson you can

  • Limit a parameter to a list of values with [ValidateSet()], and use the Tab completion it gives
  • Check a parameter's value with [ValidateRange()], [ValidateNotNullOrEmpty()] and Mandatory before the function runs

Key takeaways

  • Validation attributes go on the lines above a parameter and check its value before any line of the function runs, so bad input never reaches your file.
  • [ValidateSet('Chill', 'Upbeat', 'Focus')] allows only those values, and Tab and Ctrl+Space offer them as choices.
  • [ValidateRange(1, 15)] keeps a number between two limits, both included.
  • [ValidateNotNullOrEmpty()] turns away an empty value, such as a misspelled variable. [Parameter(Mandatory)] asks for a value that's missing.

Online forms check what you type before they let you press Send: an email needs an @, a birthday can't be in the future, and "state" is a list you pick from rather than a box you type in. They check at the door because bad data is far harder to fix once it's stored. Your playlist needs the same. If someone adds a song with the mood Chil, Get-Song -Mood Chill never finds it; if they type 45 minutes when they meant 4, every playlist built from the file comes out wrong. PowerShell's cmdlets check their input before they start, and your tools can too.

This lesson adds Add-Song to the playlist tools from Advanced Functions: [CmdletBinding()]. Add this function to PlaylistTools.ps1, below Get-Song, save, and load the file with . .\PlaylistTools.ps1 in the practice folder:

function Add-Song {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$Title,

        [ValidateNotNullOrEmpty()]
        [string]$Artist = 'Unknown',

        [Parameter(Mandatory)]
        [ValidateRange(1, 15)]
        [int]$Minutes,

        [Parameter(Mandatory)]
        [ValidateSet('Chill', 'Upbeat', 'Focus')]
        [string]$Mood,

        [string]$Path = 'road-trip.csv'
    )
    Add-Content -Path $Path -Value "$Title,$Artist,$Minutes,$Mood"
    Get-Song -Path $Path | Select-Object -Last 1
}

Add-Content adds the song as a new line at the end of the CSV file (Writing to Files: Set-Content, Add-Content and >), and the last line outputs the song it added, as an object. The lines in square brackets above each parameter are validation attributes: checks PowerShell makes on that parameter's value before the function's first line runs. Add a song that passes them all:

Add-Song -Title 'Tunnel Echo' -Artist 'The Night Owls' -Minutes 4 -Mood Chill
Title       Artist         Minutes Mood
-----       ------         ------- ----
Tunnel Echo The Night Owls 4       Chill

A list of choices: [ValidateSet()]

[ValidateSet('Chill', 'Upbeat', 'Focus')] (read "validate set") allows only the values in its list, like a form's drop-down:

Add-Song -Title 'Toll Booth Blues' -Minutes 4 -Mood Chil
Add-Song: Cannot validate argument on parameter 'Mood'. The argument "Chil" does not belong to the set "Chill,Upbeat,Focus" specified by the ValidateSet attribute. Supply an argument that is in the set and then try the command again.

The message names the parameter, the value and every allowed choice, so the person can fix it at once. Capital letters don't matter to the check: -Mood chill passes, and goes into the file the way it was typed.

A set also tells PowerShell what to offer when you press Tab. Type Add-Song -Title 'Toll Booth Blues' -Minutes 4 -Mood, then a space, and press Tab:

Add-Song -Title 'Toll Booth Blues' -Minutes 4 -Mood Chill

Press Tab again for Focus, and again for Upbeat, or Ctrl+Space to see all three at once (Keyboard Shortcuts at the Prompt). Tab writes each one with the set's own capital letters, so the file stays tidy.

A range: [ValidateRange()]

[ValidateRange(1, 15)] keeps a number between two limits, and both limits are allowed. A song of 0 minutes is a typo, and so is one of 45:

Add-Song -Title 'Toll Booth Blues' -Minutes 45 -Mood Upbeat
Add-Song: Cannot validate argument on parameter 'Minutes'. The 45 argument is greater than the maximum allowed range of 15. Supply an argument that is less than or equal to 15 and then try the command again.

The [int] type turns away a word such as four first, as in Parameters: param(); the range then checks the number.

Not empty, and not missing

[Parameter(Mandatory)] you've met: when a value is missing, PowerShell asks for it. It also turns away an empty one, so a song can't have the title ''. -Artist isn't mandatory, because many songs in a playlist come from somewhere you don't know, so it has a default. But when someone does give an artist, it shouldn't be empty. That happens more than you'd think, from a misspelled variable:

$band = 'Maple Street'
Add-Song -Title 'Toll Booth Blues' -Artist $bnad -Minutes 4 -Mood Upbeat
Add-Song: Cannot validate argument on parameter 'Artist'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

$bnad was never set, so it holds nothing, which PowerShell calls null. [ValidateNotNullOrEmpty()] turns away both nothing and an empty ''. Without it, the song would have gone into the file with no artist at all.

None of the three failures reached the file. Only Tunnel Echo was added:

(Get-Song).Count
8

Put the checks where a mistake costs something: a value that goes into a file, picks a folder, or decides what gets removed. Everything here works the same in Windows PowerShell 5.1 and on a Mac or Linux.

Try it. Give Get-Song's -Mood the same [ValidateSet()], load the file again, and type Get-Song -Mood, a space and Tab. What happens to Get-Song -Mood Happy now?

Check yourself

2 questions to try on the lesson page.

So what

A tool that checks its input at the door keeps your data clean and tells people exactly what it wanted, and Tab completion means they rarely get it wrong in the first place.

Key terms

Cheat sheets

Related