# Using Assertions

Code often needs to assert certain things, i.e. make sure that a folder really exists. Reusable assertions can produce much cleaner code.

Frequently, your code needs to ensure that certain prerequisites exist. For example, if you plan to download files to a local folder, you want to make sure this folder exists, and if it is still missing, create it.

This of course is not a problem, so you often encounter code like this:

$OutPath = "$env:temp\SampleData"

$exists = Test-Path -Path$OutPath -PathType Container

# no, create it:
if (!$exists) {$null = New-Item -Path $OutPath -ItemType Directory } There are two issues with this approach, though: • Reusability: Since this task is a routine task that you’ll often need, you’ll find yourself repeating to code this test over and over again. Of course you could copy & paste the code snippet but would still have to adjust variable names. • Clean Code: With each routine test, your code grows and becomes increasingly harder to read. Wouldn’t it be much better to exclude standard code that you know is ok, and focus entirely on the specific code that is really new? Here is an alternative that is so much easier to read and use: ($OutPath = "$env:temp\SampleData") | Assert-FolderExists ## Reusing Assertions Assertions are just a special breed of PowerShell functions: Assert-FolderExists takes any number of paths and makes sure the folders exist. If not, they are created. Clean, simple and reusable. Placing a variable assignment in parenthesis is key for this: when an assignment is placed in parenthesis, the value is assigned to the variable and the value is also emitted, so a down-stream command can pick it up. Compare these two lines: # simple assignment:$Path1 = "$env:windir\explorer.exe" # assignment PLUS output: ($Path2 = "$env:windir\explorer.exe") The first line silently assigns the value. The second line also emits the assignment: C:\Windows\explorer.exe ### Filters Are Perfect Assertions Filters are perfectly suited for assertions because with very little code, you get a fast pipeline-aware function that processes one or many input values. Assert-FolderExists can be implemented like this: filter Assert-FolderExists {$exists = Test-Path -Path $_ -PathType Container if (!$exists) {
Write-Warning "$_ did not exist. Folder created."$null = New-Item -Path $_ -ItemType Directory } } Now it’s trivial to create one or more folders: simply pipe the paths to Assert-FolderExists. You can pipe strings directly or use the parenthesis trick to take them from assignments: # making sure a bunch of folders exist: 'C:\test1', 'C:\test2' | Assert-FolderExists # making sure the path assigned to a variable exists: ($Path = 'c:\test3') | Assert-FolderExists

### Using Functions

Filters are great when you want to exclusively process pipeline input. If you’d rather use named parameters, use pipeline-aware functions instead:

function Assert-FolderExists
{
param
(
[Parameter(Mandatory,ValueFromPipeline)]
[string[]]
$Path ) process { foreach($_ in $Path) {$exists = Test-Path -Path $_ -PathType Container if (!$exists) {
Write-Warning "$_ did not exist. Folder created."$null = New-Item -Path $_ -ItemType Directory } } } } Now you can use Assert-FolderExists both via pipeline and via parameters: # making sure the path assigned to a variable exists: ($Path = 'c:\test3') | Assert-FolderExists

# making sure a bunch of paths exist:
Assert-FolderExists -Path 'c:\test4', 'c:\test5'