PowerShell V2 CTP2 : making Custom Enums using add-Type
In PowerShell Enums are used a lot but you're not able to create them directly in PowerShell
I made a post about a workaround using reflection on my old blog here : /\/\o\/\/ PowerShelled: PowerShell : making Custum Enums ,as this is using reflection it is a bit hard to grasp, and we can not create enums within a namespace only global.
But in the PowerShell V2 CTP2 there is another simpler way to do this introduced the new Cmdlet : Add-Type
you might have seen in the former posts about WPF, you can use Add-Type to load an assembly or DLL instead of using the .NET framework directly as in PowerShell V1,
V1
[System.Reflection.Assembly]::LoadWithPartialName('system.windows.forms')
CTP2
Add-Type -AssemblyName system.windows.forms
but the add-Type Cmdlet can do much more (see also list of parameters above) !
The Add-Type Cmdlet gives also access to the CodeDomProvider, that enables us to compile .NET code ( for an example how to do this using raw .NET in V1 see :/\/\o\/\/ PowerShelled: getting an Inputbox in MOnad )
This combined with loading assemblies gives us an easy way to use inline C# code in PowerShell we just pass the C# code to the Add-Type cmdlet and it will be compiled and loaded on-the-fly.I made an Add-Enum function using this technique and variables in the embedded C# code, to simply create and use Custom Enums in PowerShell like this :
much simpler and the possibility to provide a namespace for the Enum what was not possible using Reflection.
The Script looks like this :
# Function Add-Enum
# requires -version 2
#
# /\/\o\/\/ 2008
# Http://thePowerShellGuy.com
Function Add-Enum ($name,[string[]]$values,$nameSpace) {
if ($nameSpace) {
$code = @"
namespace $NameSpace
{
public enum $name : int
{
$($values -join ",`n")
}
}
"@
} else {
$code = @"
public enum $name : int
{
$($values -join ",`n")
}
"@
}
Add-Type $code
}
this function makes it easy to create Enums and you can use namespaces and use the -as operator to cast int values into Enum names :
You can see above that the enum by default starts at 0 by default, but that you can overrule values on a per item base, the items following will count up from the last item. So in the Mow.OSType enum giving a start value of 1 is enough to number up from there.
The Get-EnumMembers function I used above to quickly check the Enum values and names looks like this :
Function get-EnumMembers ([type]$enum){
[enum]::GetValues($enum) |
select @{Name='Value';e={[int]($_ -as $enum)}},
@{Name='Name';e={$_ -as $enum}}
}
Enjoy,
Greetings /\/\o\/\/