Us humans tend to take a lot of shortcuts and assume many things and for good reason. We wouldn’t survive in this world if our brain had to pay attention to every input we receive on a daily basis. We naturally and automatically assign context to situations, conversations, and more. This is why a coworker can just begin talking about something that happened the previous day you were involved with and you can quickly pick up context. You don’t have to start a conversation like: “At 7:01 PM, you and I were in our office working late. I then rose from my chair and yelled over the cube….” Your coworker gets it already.
Although artificial intelligence (AI) is trying, computers don’t assume. They aren’t smart. They can’t automatically do things. We humans must tell them exactly what to do. Sure, you can get away with taking shortcuts here and there, but if that random edge case comes along you never coded for, the computer isn’t going to handle it; it’s going to fail miserably.
In this chapter, you’re going to learn some tips on when to be specific in your code. You will learn about opportunities you will find yourself in to choose the more defined, explicit, specific route rather than relying on that off-chance your code will not encounter an edge case you didn’t account for.
Explicitly Type All Parameters
PowerShell is called a loosely typed language. This means that you don’t have to statically assign types to variables. Statically typed languages don’t allow you to simply define a variable or parameter like $var = 2 and automatically assign the $var value as an integer or assign the $var2 variable as a string in the code $var2 = 'string'. PowerShell makes assumptions based on various “patterns” it sees in the value.
Loosely typed languages like PowerShell are handy because they take care of some extra work, but this hand-holding can sometimes backfire. When defining function or script parameters, you should always statically assign a type to each one.
I don’t advise you to define parameters like this even though you can. What happens if you pass in a string, how about a Windows service object? Are you handling for those times when someone tries to use the pipeline to pass in a Boolean somehow? You get the point. There are many different types of parameters PowerShell will accept in this situation. You’re probably not accounting for all of them in the code.
By explicitly assigning a type, you’re telling PowerShell that this function should only accept this type.
Sometimes explicitly defining the type isn’t as important as others, but it’s a great habit to get into.
Further Learning
Always Use Parameter Validation When Possible
Along the same lines as explicitly typing a parameter, you should also narrow the type of input a parameter will accept by using parameter validation. PowerShell provides many different ways you can limit values passed to parameters.
For example, maybe you have a function that is part of a larger automation routine that provisions servers. One function in that routine comes up with a random server name. The first part of that random server name is supposed to be what department owns that server.
Further Learning
Always Define a Function’s OutputType
The OutputType keyword is a relatively unknown PowerShell construct, but one not only shows, at a glance, what kind of object a function returns but also helps the function user with some handy tab-completion.
Not only is this helpful when reading the code, it’s helpful when inspecting the object that it returns. Since PowerShell knows what type of object will be returned when you run it, you don’t even have to run the function to discover the properties and methods on that object.
Write Specific Regular Expressions
If you have to match a string with a regular expression (regex), be sure that regular expression is built as specific as possible. Regex can be another book in and of itself, but for this book, just try to build that expression as specific as possible. If not, you’re bound to match strings you didn’t intend.
The difference in these two regular expressions is not only the length but the accuracy. The first string match all string patterns a GUID could possibly be represented in and only those. The second example simply matches any characters separated by dashes. The second regex is less specific and could lead to matches you do not intend.