Write Functions, Not Scripts – Part V

I like how my assumption that Part IV of Write Functions, Not Scripts wouldn’t be a worthy contender to the previous three parts (P1, P2, P3). Seriously, I didn’t think it compared, and if I’m not mistaken, it’s been the most popular post in this series thus far.

It’s a simple concept though: short, simple, single-purposed is sufficient for writing functions. Think small, easier to troubleshoot code. Say you have five functions that run in succession — one right after the other. The point at which things break will likely remove 4 of the 5 functions as areas you even need to review. That means you’re troubleshooting a fifth of the code the scriptwriter would have to review. Functions are a no-brainer. Well, they ought to be, anyway.

Time for some more thoughts on why functions over scripts. Hey, ever see one of these in a script?

$UserCount = 10
# When using in production, please comment out the above line.
# Then, uncomment the below line.
# $UserCount = 20

This is why we have a Read-Host. This, would be better.

$UserCount = Read-Host -Prompt 'Enter the preferred User Count'

Before blogging was my main gig, you might find me scouring various forums more often and helping others (and secretly learning more, too). A good number of people were getting their input via the Read-Host cmdlet. It’s nice and all, but by itself, there’s a bit of mystery as to what a user might enter. While I’m expecting 10, or 20, I could end up with all kinds of obnoxious values.

$UserCount = Read-Host -Prompt 'Enter the preferred User Count'
Enter the preferred User Count: DogCatMom5
# Huh!?

Inside a Do loop construct, we can better control the acceptable input.

Do {
    $UserCount = Read-Host -Prompt 'Enter the preferred User Count'
} Until ($UserCount -eq 10 -or $UserCount -eq 20)
Enter the preferred User Count: 1
Enter the preferred User Count: 2
Enter the preferred User Count: 3
Enter the preferred User Count: 4
Enter the preferred User Count: 5
Enter the preferred User Count: 6
Enter the preferred User Count: DogCatMom5
Enter the preferred User Count: 10

But there’s still a better way. Function’s allow for parameters and so, as absolutely as best as we can, we need to separate our lives — and our function writing — from Read-Host. If it’s ever in a function, and I’ll agree that it can happen, there ought to be really great reason as to why. We’ll close out today’s post with a simple function example that uses parameters. This is such a huge benefit.

Function Test-ParamsInAFunction {
    Param (
        $Number,
        $Letter
    )
 
    If ($Number -and $Letter) {
        Write-Output -InputObject "You have entered the number $Number, and the letter $Letter."
    } ElseIf ($Number) {
        Write-Output -InputObject "You have entered the number $Number."
    } ElseIf ($Letter) {
        Write-Output -InputObject "You have entered the letter $Letter."
    } Else {
        Write-Output -InputObject "You have not entered a number or letter."
    }
}
Test-ParamsInAFunction
Test-ParamsInAFunction -Number 5
Test-ParamsInAFunction -Letter X
Test-ParamsInAFunction -Number 10 -Letter D

You have not entered a number or letter.
You have entered the number 5.
You have entered the letter X.
You have entered the number 10, and the letter D.

Functions can handle run time delivered values. There’s no more opening up scripts and adding and removing static comments and variable assignments. There’s no using Read-Host inside our scripts and functions (unless, again, you’ve got a really great reason), even if, you’re using a language construct to protect the acceptable values. Before we full on wrap up, let me show you how to make a parameter only accept the 10 and 20 values.

Function Test-ParamsInAFunction {
    Param (
        [ValidateSet(10,20)]
        $Number
    )
    ...
}

See you again next time.

Leave a Reply

Your email address will not be published. Required fields are marked *