5 tips to help you explore the world of PowerShell scripting
In 2006 Windows Administrators got their first glimpse into what the world of PowerShell scripting might look like when PowerShell, which was then known as Monad was released under beta conditions to the world. 10 years later we are now into our 5th iteration of the scripting language and have seen a thriving ecosystem form around the Verb-Noun style of automation. PowerShell is a powerful tool and can be an amazing time-saver to for any Windows administrator to know. That said, as with any scripting/programming languages getting started can be a little daunting, especially if you have had no scripting experience to fall back on. Below we will take a look at 5 tips that can save you both time and energy when writing your PowerShell scripts.
There have been numerous times where I have found myself staring blankly at the glowing blue PowerShell console and grinding my brain. Not trying to figure out how to use a specific cmdlet, but trying to figure out what cmdlet to use. There are over 1000 cmdlets built in to my default install of PowerShell 4.0 alone, without loading any external modules and snap ins at all. Trying to tab complete to find the proper one to do the job can be a time consuming, enraging experience. This is where the Get-Command cmdlet comes in handy. Get-Command allows us to list out all of the available PowerShell cmdlets within our current console, showing us various tidbits of information about that command such as version, source and name. Simply running Get-Command by itself (shown below) is not very useful as it will simply list out every single cmdlet available within the console session.
That said if you have a hunch or an inkling of what exactly you are looking for you can pass that information along with the –name flag. Say you were looking for cmdlets to parse XML files – below is how we can simply filter our output by passing wildcards and xml to our –name flag
Certainly if you are struggling to find a cmdlet to meet your needs, or can’t quite remember the proper VERB-NOUN abbreviations, Get-Command can definitely point you in the right direction.
So we now know what cmdlet we want to run but how do we get the exact syntax of how to run it. This is where Get-Help comes into play. The Get-Help cmdlet will retrieve whatever help content it can find in regards to a specific cmdlet, including its’ synopsis, syntax, any input parameters, return types, etc. Shown below we can see the help documentation for the cmdlet Mount-DiskImage…
Aside from this basic information we can also pass flags to our Get-Help cmdlet to obtain more details around the cmdlet such as ‘-examples’ for example syntax, ‘-detailed’ for more detailed help, and ‘-full’ for everything. As we can see below, passing ‘-examples’ to our previous Get-Help call gives us some example syntax we can use to reference when constructing our own commands.
When we pass –Full to Get-Help we usually end up with endless amounts of printed lines on our console window which can be a little difficult to navigate around. To help alleviate this we could pipe our command to more (IE Get-Help Mount-DiskImage | more) to have pagination occur. A better alternative though is the –ShowWindow flag. When we use the –ShowWindow flag the –Full flag is assumed, and the resulting help text is shown on a separate scrollable, searchable window as shown below…
Having our help text shown in a separate window can be very beneficial, allowing administrators to both work within the console window and follow along with examples and details within the help content.
So now that we have used Get-Command to get our proper cmdlet and Get-Help to determine the proper syntax to run it, what do we do with these object things that are returned? If you haven’t had any dealings with an object-oriented language before using PowerShell then one of the biggest learning curves you will have to overcome is that of “Everything within PowerShell is an object”. Sure, when we are using cmdlets like “Get-Item” we expect them to return an object which is a file, but even things such as a string variable are treated as an object within PowerShell – and each and every object within PowerShell contains various methods and properties that can be useful to administrators trying to automate a task. The problem is we don’t necessarily know what those methods are! Thankfully we can pipe the “Get-Member” cmdlet to an object and retrieve all of these methods and properties, allowing us to explore and figure out just what we can and cannot do with that specific object. Let’s take a look at our two previous examples below…
As you can see the Get-Item cmdlet has a lot more functionality built in to it other than just returning a file. We can see methods to accomplish such things as deletion, moving, etc. Meaning we could essentially wrap our cmdlet within brackets and call a delete() function as follows…
You may have also noticed a bunch of properties which are available yet are not shown by default in the output. For example, we can retrieve the parent directory of our file as follows
So, if you are struggling trying to find a way to manipulate or find out more about a specific object simply pipe the Get-Member cmdlet to find out all of the available methods and properties you can use.
WhatIf and Confirm
Command line can sometimes be a daunting and unforgiving place. Once that ‘Enter’ key is pressed PowerShell more often than not goes out and does what it was instructed to do, and as careful as we are we all make mistakes which are often unrecoverable. To help alleviate this we have a couple of parameters which are available on a lot of cmdlets we run. The first being –WhatIf. By passing a –WhatIf to our cmdlet we are able to preview any changes that may take place without actually applying those changes. We can think of it as somewhat of a dry run that tests our syntax and displays the estimated results. Our previous example of Mount-DiskImage doesn’t really have the disastrous, unrecoverable results that we are looking for so let’s switch to a more permanent cmdlet, Remove-Item, which essentially deletes a file. Below, by passing a –WhatIf parameter we can see that the cmdlet would indeed delete the file specified…
Although –WhatIf helps with our dry run it doesn’t do anything in terms of getting confirmation from the user that they indeed want those results. For this we need to use the –Confirm flag. By default, our Remove-Item cmdlet (without the –WhatIf) would simply delete the file without confirmation. By passing the ‘-Confirm’ parameter we can change this behavior and instruct our cmdlet to prompt the user for input. Below we can see the same Remove-Item cmdlet, but this time asking for permission to continue…
It should be noted that some cmdlets will confirm by default, which is great while you are sitting inside a console but not so useful when an unattended script is running. For these cmdlets we can pass false value to our –Confirm parameter (IE –Confirm:$false) to “auto confirm” these changes.
As we seen within the Get-Member section of the post some PowerShell objects can have many different properties associated with them – however when these objects are returned only a select few are shown by default. In order to gain access to the “hidden” properties we can utilize the ‘Select-Object’ cmdlet, or it’s alias, select. Shown below is the output of our Get-Item cmdlet with its default selections…
We can see that we retrieved Mode, LastWriteTime, Length and Name – but we know for a fact that there is a DirectoryName property as well. What if we just wanted to see Name, LastWriteTime, and DirectoryName? We could simply pipe our cmdlet to select and specify just those properties we want (IE Get-Item .\test.txt | Select Name, LastWriteTime, DirectoryName) as shown below…
But what if we wanted to see the values of all of the properties available? To do so we can simply say ‘Select *’ rather than specifying property names. That said this could make for a pretty crammed table view as there are a lot of properties available. To help alleviate this we can change the way PowerShell displays the output by either piping a ‘Format-Table’ or ‘Format-List’ cmdlet to the end of our command. Shown below we select all of the properties of our file, but change the output to show in a list view which is a little more readable…
One final useful way of displaying results within PowerShell is with a GridView. Our previous example only returned one item, but if it had returned an array of objects, like the Get-Process cmdlet things can get messy pretty quick when trying to sort filter the results. There are ways to do it via PowerShell cmdlets such as Sort-Object, however it’s much easier sometimes to simply break out our return text into a gui-based window that we can manipulate. Shown below we pipe the Out-GridView to our Get-Process cmdlet which in turn places our results in a separate window.
As you can see, we now have all of our familiar sorting and filtering functionality available to us, making it easier to get at the data we were initially looking for.
In this tips article we have barely scraped the surface as to what PowerShell can do, but we have given you the tools and cmdlets you can use to help you gain more information about the what certain cmdlets do, how to use them and how to work with the objects they return. Automation is quickly becoming a key player in datacenters and businesses around the world, and PowerShell is one of the key players in that space so I urge everyone – get to know PowerShell and see what it can do for you.
- Deploy Hyper-V VM Switches and vNIC consistency with PowerShell
- Automate the Hyper-V Virtual Machine deployment with PowerShell