Certifications / Microsoft

How to Write Better PowerShell Scripts

by Sabrin Alexander
How to Write Better PowerShell Scripts picture: A
Follow us
Published on July 14, 2020

For most of us who have used PowerShell, we've all had the chance to write pretty complex scripts in PowerShell. And while we are treading away, we tend to write our scripts fast — without thinking of aesthetics, commenting, or writing our code in an efficient manner. Our top priority is always finishing the script under any circumstance so we can get on with our day, or night.

What most PowerShell scripters don't realize is that writing complex scripts in simple, organized ways and putting in good comments is actually a lot more time saving — than just writing it out and hoping to finish as soon as possible.

So, let's discuss how using the help command, aliases, commenting, and in general, making sure everything is structured correctly will help us create more efficient PowerShell scripts in less time.

Common Ways to Write Clean Code

There are some points that we need to take into consideration when we start writing PowerShell scripts.

The first one is to think about the script before we even write it. What type of script is it? What's the end goal of the script? Am I the only one who will ever use this script? And can I split this script into several smaller ones?

When we think about the type of script we are writing, we tend to focus on the type of deployment methodology that the script will take. Some questions that we need to ask ourselves are: is this script going to be used daily, is the script runtime important, and will this script be handed out to other systems administrators?

Those three questions will ultimately dictate how we will write our script. If the script will be deployed on hundreds of systems in an automatic deployment using some central configuration system, script runtime is very important. It will dictate how long this deployment will take.

This part goes hand in hand with the question of whether the script is going to be run daily. If so, then the script's size and complexity is very important —making it a lot easier to troubleshoot in case of an issue.

Am I the only one who will tend to this script? This question is very important, especially in Enterprise environments. For example, let's say we have several teams that manage the automation infrastructure, and all the team members need to share the scripts and troubleshoot them collectively.

This is when we really need to start thinking about commenting on the actual code to make it easier to understand by any 3rd party who may be called on to troubleshoot or improve the script.

In case we are dealing with a complex script that could ultimately turn into several hundred or even thousand lines of code, we might think of splitting the script into several more scripts. This way the script will be a lot easier to troubleshoot. We won't be looking at the big script as a whole, but we will rather treat each function or script block as a module or independent script that are part of a whole solution.

Bottom line, it's easier to write smaller scripts, with comments and using aliases to shorten the actual command or script block. It will also give us more control in regards to script deployment. It will be easier to deploy a part of a big script when it's split into several ones than deploying a large script over and over again.

Help, Aliases, and Comments

The help command is one of the most powerful commands in PowerShell because it provides information about any command that we are trying to run — and also pretty good code examples! Let's explore some examples of how we can use the help command.

The help command is accessed either by using the Get-Help cmdlet or by just typing help.

It also accepts wildcards. Even if you don't remember the exact command, you can just type a part of it and use the wildcard to retrieve the help for that specific command.

If we use "Get-Help about*" we will receive an entire list of help files that relate to PowerShell in general. For example, about_IF which shows us very detailed information about the IF conditional parameter.

Get-ChildItem which is a basic PowerShell cmdlet that contains some surprises that get-help can show us.

We will receive a detailed description of the command syntax and it will show us which arguments or values are needed or not needed, which values can be written without the actual argument and so forth. If we use Get-Help Get-ChildItem we will receive the following:

Get-ChildItem [[-Path] <String[]>] [[-Filter] ] [-Attributes {Archive | Compressed | Device | Directory | Encrypted | Hidden | IntegrityStream |
    Normal | NoScrubData | NotContentIndexed | Offline | ReadOnly | ReparsePoint | SparseFile | System | Temporary}] [-Depth ] [-Directory] [-Exclude
    <String[]>] [-File] [-FollowSymlink] [-Force] [-Hidden] [-Include <String[]>] [-Name] [-ReadOnly] [-Recurse] [-System] []

As we can see from the Syntax output most of the parameters are optional and we do not even need to provide any parameters. It also shows us a great deal of info about the actual value and if it has to be one string or an array of strings.

Let's look at the -Path argument. It's included in square brackets, which means it's optional. We don't have to type it and we can see that it accepts multiple strings of input because the value is string[].

So, let's say we needed to get the contents of multiple folders instead of writing this command three times, each time with a different path we can do the following:

Get-ChilItem C:\Users,"C:\Program Files",C:\Windows

This is just one line of code that substitutes three lines. We can do this type of optimization with virtually every command out there. It will increase every aspect of the script itself and our time spent on writing it.

When used with the -full argument, the help command will return a full list of aliases, examples and descriptions of the specific cmdlet. The help for the Get-Childitem cmdlet is so vast that it fills up an entire article page.

The next topic we are looking at is aliases. Aliases can drastically optimize the look of the scripts — and is very helpful in writing condensed scripts when the script itself should be complex.

For example, the alias for Get-ChildItem is dir. But please note that dir in PowerShell is not the dir command in cmd. The dir command is actually an alias of Get-ChildItem, so each time you type dir in PowerShell you are actually accessing the Get-ChildItem cmdlet.

Another alias that we can look at is the % one. This stands for ForEach-Object. By the way, you can access all aliases of all the commands by using the Get-Alias cmdlet. For example Get-Alias % will return:

Alias           % -&gt; ForEach-Object

Aliases coupled with correct code writing and deep knowledge of each cmdlet, by using the help command, can make the following difference.

These two script blocks have the same effect.

$Users = Get-ChildItem C:\Users
$ProgramFiles = Get-ChildItem 'C:\Program Files'
ForEach ($User in $Users)
{
Write-Output $User.LastWriteTime
}
ForEach ($ProgramFile in $ProgramFiles)
{
Write-Ouput $ProgramFile.LastWriteTime
}
dir C:\Users,'C:\Program Files' | % {echo $_.LastWriteTime}

As you can see the amount of code has been reduced drastically and what we would put in 12 lines of code, we put into one line of simple code.

We use aliases, command knowledge, and piping to achieve this. Even if we would have written this without the aliases dir, % and echo that translate to Get-ChildItem, ForEach and Write-Output we would still have a very short command.

The last topic we are going to discuss is commenting. Below is a good example of a comment:

#Category: Configuration

#Parameters: None

#Sub-Category: Microsoft Active Directory

#Synopsis: Module used to create the Key Distribution Services KDS Root Key and enable it immediately without waiting the 10 hour grace period.

This comment gives us a lot of info on the actual script. It shows which category the script is part of, configuration, operations, and reporting. It also gives us a clear view of which parameters are required in the script, which technology the script is geared toward, and the synopsis of the script.

Keeping this kind of commenting methodology will drastically improve the time needed by multiple teams to troubleshoot and read a script.

What's Next?

If you're an experienced PowerShell user, keep aliases and comments in mind when writing code. It will make your code more clean and efficient. If you're new to PowerShell, there's plenty of resources to help you get up to speed including Jacob Moran's Microsoft PowerShell 6 Foundations training.

Even if you don't plan on using PowerShell regularly, knowing how to use it can come in handy when it comes to certification. Especially if you have an eye on Microsoft certification.

Ultimately, the best thing to do is to apply this knowledge and tips to current and future scripts. You might be surprised how much it improves your PowerShell scripting experience. Good luck!


Download

By submitting this form you agree to receive marketing emails from CBT Nuggets and that you have read, understood and are able to consent to our privacy policy.


Don't miss out!Get great content
delivered to your inbox.

By submitting this form you agree to receive marketing emails from CBT Nuggets and that you have read, understood and are able to consent to our privacy policy.

Recommended Articles

Get CBT Nuggets IT training news and resources

I have read and understood the privacy policy and am able to consent to it.

© 2024 CBT Nuggets. All rights reserved.Terms | Privacy Policy | Accessibility | Sitemap | 2850 Crescent Avenue, Eugene, OR 97408 | 541-284-5522