Tag Archives: Flow

Some advice on creating Powershell scripts

Creating a Powershell script CAN be quite difficult. How to get the output you want? Where to start? Let me try to get you started by providing a structure you can follow. I’m not saying this is THE way, but it’s MY way. Hope it helps you and please do comment if you have additions or another way!

First: Scripts for gathering information.

1. What should my OUTPUT be?
It’s easier to start with the end. Start by determining what you would like your output to look like.

1.1 OBJECTS representing what?
It’s good practise generating objects as output. It allows you to use the full power of Powershell to further manipulate your output. So don’t use any Format-… cmdlets in your scripts! That being said, what should the output objects represent?
Let’s take a simple example, like generating an overview of server OS versions or free disk space or something similar. The output objects should represent the servers.

You all know objects have properties. If not, read Get-Help About_Object. What properties of the server objects are we interested in? In the example it could be Server Name (obviously), OS Version, Service Pack, Free Disk Space on C-partition, and so on.

2. WHERE to get the information?
Now that we know what objects to create and what properties to fill, let’s examine where to get all this info.

2.1 The EASY ones.
When the properties can all be found in one place, the script is simple. For example, the OS Version and Service Pack of a server, can all be found in Active Directory. The Quest AD cmdlet Get-QADComputer returns objects representing servers, which have properties including the ones we seek. All we have to do is FILTER the properties, like so:
Get-QADComputer | Select-Object Name, OSName, OSServicePack

And we’re all done!

2.2 Getting HARDER:
What if most properties can be found in this way, but some require additional calculations or “get-”ting? Then we can use CALCULATED PROPERTIES. The syntax is as follows:
Get-Something | Select-Object Name, @{N=”CalculatedPropertyName”;E={EXPRESSION THAT RETURNS THE DESIRED VALUE}}
For example, you want to get several properties of a harddisk, but one value should be converted from bytes to GB:
Get-WmiObject Win32_LogicalDisk | Select-Object DeviceID, @{N=”GBFreeSpace”;E={$_.FreeSpace/1GB}}

The most difficult scripts gather information from all over the place. But you’d still like to present it in a simple and convenient manner. This is when you should build your own output objects and create the properties yourself. In order to get this done for multiple objects in a collection, it is vital you loop through a collection of objects representing the same thing as your output objects. Consider the following example:
Let’s say you want to get some exotic characteristics for all your vm’s. For instance which server it is running on, the last 5 events that occurred and the average memory usage. These aren’t properties of any vm object you can get. So start by looping through all the vm objects you can get, but not before you create an empty collection to old your output objects:
$myCol = @()
$VC = Connect-VIServer MYVCSERVER
$vms = Get-VM
ForEach ($vm in $vms)
Then, inside the loop, create a custom output object along with the properties you’d like to see:
$myObj = “” | Select Name, Host, LatestEvents, AvgMemUsage
Then you can start calculating or “get-”ting the proper values for each of these properties. For example:
$myObj.Name = $vm.Name
$myObj.Host = ($vm | Get-VMHost).Name
$myObj.LatestEvents = ($vm | Get-Event | Select-Object -Last 5)
$myObj.AvgMemUsage = ($vm | Get-Stat -Memory -MaxSamples 1).Value
(These examples are off the top of my head and untested.)
Finally, add your output object to the collection and close the loop:
$myCol += $myObj

Next time: Scripts that actually change values or perform some other action. Stay tuned.