Prof. Powershell
Label Me Perfect
The power of properties allow you to use it as a, well, a PowerShell labelmaker.
- By Jeffery Hicks
- 04/14/2009
Last time I showed you how to extend PowerShell's reach by adding custom properties to an object with Select-Object. I demonstrated how to use an associative array, sometimes known as a hash table, to create new properties.
The reason to do this with Select-Object is that the new property becomes part of the pipeline:
PS C:\files> dir -recurse | select FullName,LastWriteTime,`
@{name="Size";Expression={$_.Length}},`
@{name="Owner";Expression={(Get-ACL $_).Owner}} | Sort Owner,Size -desc |
ConvertTo-HTML | out-file FileOwners.html
In this example I've used hash tables to rename the "Length" property to the more meaningful "Size" and created a new property called "Owner" that returns the file owner using the Get-ACL cmdlet. The resulting expression is then sorted by "Owner" and "Size" in descending order, converted to HTML and saved to a file.
If you only need to produce nicely formatted reports for the console or perhaps to save to a file, you could pipe the Select-Object expression to Format-Table. However, you can save a step and use hash tables with Format-Table to define the custom properties. The only change is that instead of defining a name, we are defining a label. Here's an example:
PS C:\> get-wmiobject Win32_logicaldisk -filter "drivetype=3" `
-computer "mycompany-dc01" | Format-table DeviceID,VolumeName,`
@{label="Size(MB)";Expression={$_.Size/1mb -as [int]}},`
@{label="Free(MB)";Expression={$_.FreeSpace/1MB -as [int]}},`
@{label="PercentFree";Expression={
"{0:P2}" -f (($_.FreeSpace/1MB)/($_.Size/1MB))}} -autosize
This example takes output from a Get-WMIObject expression querying logical drives on computer MYCOMPANY-DC01 and creates a more user friendly report. The values for "Size" and "FreeSpace" are in bytes. Using a hash table, they have been reformatted to return values in MB. The label has also been modified to reflect the change:
@{label="Size(MB)";Expression={$_.Size/1mb -as [int]}}
The expression also creates a new value called "PercentFree" that is calculated from dividing the "FreeSpace" by "Size":
@{label="PercentFree";Expression={"{0:P2}" -f (($_.FreeSpace/1MB)/($_.Size/1MB))}}
I had to add a step to convert these values to MB to get around a limitation in PowerShell 1.0. When you run this expression, you should get output like this:
DeviceID VolumeName Size(MB) Free(MB) PercentFree
-------- ---------- -------- -------- -----------
C: OS_C 8182 1410 17.24 %
E: pagetemp 2046 1215 59.39 %
F: Backups 4094 3141 76.72 %
You can also use custom labels with the Format-List cmdlet. There's practically no limit to what you can do with custom properties and labels and it's all possible because of PowerShell objects.
About the Author
Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.