Enum Week: Auto-Conversion for Enums

by Sep 26, 2016

This week we are looking at enumerations: what they are, and how you can benefit from them.

When a cmdlet or method requires an enumeration value, PowerShell happily accepts incomplete enumeration names. This is a little-known fact. This code, for example, changes the console foreground color to gray:

 
PS> $host.UI.RawUI.ForegroundColor = 'Gray'
 

And this would restore a white foreground color:

 
PS> $host.UI.RawUI.ForegroundColor = 'White'
 

The property ForegroundColor appears to accept strings but that is not true. It only accepts *some* strings. The type of this property therefore is not string. It is an enumeration type that lists the acceptable string names:

 
PS> $host.UI.RawUI | Get-Member -Name ForegroundColor


   TypeName: System.Management.Automation.Internal.Host.InternalHostRawUserInterface

Name            MemberType Definition                                    
----            ---------- ----------                                    
ForegroundColor Property   System.ConsoleColor ForegroundColor {get;set;} 
 

The property expects a value of type “System.ConsoleColor”. When you submit a string like “Gray” or “White”, PowerShell behind the scenes looks up the available enumeration values in System.ConsoleColor and converts the string you submitted.

A little known fact is: no exact match is needed. You could get away with this:

 
PS>  $host.UI.RawUI.ForegroundColor = 'R'
PS> $host.UI.RawUI.ForegroundColor = 'W'

This would switch console foreground color to red, then back to white. All that PowerShell cares about is that the value you specify is not ambiguous. If you submit “G”, the exception message tells you the conflicting names. For a gray color, you would have to at least specify “Gra” because anything shorter would conflict with “Green”.

Why is this important? You should try and use complete enumeration values for better readability. Just keep in mind that this conversion exists. It helps you understand why statements like this work:

 
Get-Service | Where-Object { $_.Status -eq 'R' }
 

Twitter This Tip! ReTweet this tip