Prof. Powershell
Perfect PowerShell Properties Part 1: Management Info
Here's how to pull up PowerShell reports for your own use and for others.
- By Jeffery Hicks
- 04/29/2014
One of the most compelling reasons I find to use PowerShell is that I can get at all sorts of management information that used to require arcane or complicated VBScripts and command line tools. Now with a simple command I can easily get the information I need and even better I can also put it in the format I need.
For example, it is pretty easy to get a directory listing using the dir alias for Get-ChildItem.
PS C:\> dir c:\work -file
Directory: C:\work
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 3/5/2014 2:14 PM 449 admins.csv
-a--- 1/23/2014 10:01 AM 131029 chi-hvr2-health-full.htm
-a--- 1/22/2014 4:21 PM 32951 chi-hvr2-health.htm
-a--- 12/5/2013 4:19 PM 228 ComputerData.xml
…
But perhaps I'm building a report for someone else to read. The Length property may not be very clear. Instead I want it to be Size. The standard approach is to use a hashtable with Select-Object to create a new property.
PS C:\> dir c:\work -file | Format-Table -Group DirectoryName -property Mode,LastWriteTime,@{Name="Size";Expression={$_.Length}},Name
DirectoryName: C:\work
Mode LastWriteTime Size Name
---- ------------- ---- ----
-a--- 3/5/2014 2:14:43 PM 449 admins.csv
-a--- 1/23/2014 10:01:27 AM 131029 chi-hvr2-health-full.htm
-a--- 1/22/2014 4:21:37 PM 32951 chi-hvr2-health.htm
-a--- 12/5/2013 4:19:42 PM 228 ComputerData.xml
...
I used Format-Table to recreate the output, but usually I would use Select-Object. But let's say you always want to have Size as a property, without going through the extra steps to define it. This is easy to do in PowerShell 3.0 and later.
You can take advantage of PowerShell's extensible type system and easily add a custom property. First, let's see what is currently defined for the file object you get with Get-ChildItem. Use the Get-TypeData cmdlet.
PS C:\> Get-TypeData -TypeName system.io.fileinfo | select -ExpandProperty Members
Key Value
--- -----
VersionInfo System.Management.Automation.Runspaces.ScriptP...
BaseName System.Management.Automation.Runspaces.ScriptP...
Mode System.Management.Automation.Runspaces.CodePro...
These properties were added by PowerShell. It turns out you can easily add your own with Update-TypeData. Let's create an alias property for Length and call it Size.
PS C:\> Update-TypeData -MemberType AliasProperty -MemberName Size -Value Length -TypeName system.io.fileinfo
This command must be run in an elevated PowerShell session. Checking the type data again, we can see the new property.
PS C:\> (Get-TypeData -TypeName system.io.fileinfo | select -ExpandProperty Members).Size
ReferencedMemberName MemberType IsHidden Name
-------------------- ---------- -------- ----
Length False Size
I won't see the property in the default display, although I'll show you how to remedy that in another article. But as long as the property is defined, I can use it.
PS C:\> dir c:\work -file | Select Name,Size,LastWriteTime | Out-Gridview -title "Work Files"
You can see the result in Figure 1.
But wait, it gets better. Maybe sometimes I want to see the size in KB and sometimes in MB. I can create additional properties that will return these calculated properties.
PS C:\> Update-TypeData -MemberType ScriptProperty -MemberName SizeKB -Value {$this.Length/1KB} -TypeName system.io.fileinfo
PS C:\> Update-TypeData -MemberType ScriptProperty -MemberName SizeMB -Value {$this.Length/1MB} -TypeName system.io.fileinfo
Again, once the members are defined you can see them when you pipe a file to Get-Member.
PS C:\> dir c:\work -file | get-member size*
TypeName: System.IO.FileInfo
Name MemberType Definition
---- ---------- ----------
Size AliasProperty Size = Length
SizeKB ScriptProperty System.Object SizeKB {get=$this.Length/1KB;}
SizeMB ScriptProperty System.Object SizeMB {get=$this.Length/1MB;}
Now I can put them to use.
PS C:\> dir c:\work -file | Select Name,SizeKB,LastWriteTime | Out-Gridview -title "Work Files"
Figure 2 displays the revised output.
These properties will apply to any file and will last for as long as my PowerShell session is running. To make them always available you would need to add the Update-TypeData commands into your PowerShell profile script.
Right now, I always have to ask for the new property. Next time I'll show you how to change that.
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.