Collecting Name and Integer values from enum types in PowerShell

Introduction:

We encounter enum types frequently when using PowerShell cmdlets. For anyone who isn’t familiar, an enum is an enumeration of named constants; essentially, a static list of options or choices. A good example of this is when you run Get-VM in Hyper-V to examine a Virtual Machine. The State property of the Virtual Machine object displays whether the VM is Running, Stopped, Saved, etc.

  1. PS C:\> $virtualmachine = get-vm -ComputerName TestServer -name TestVM
  2. PS C:\> $virtualmachine | fl Name, State
  3.  
  4. Name  : TestVM
  5. State : Running

Instead of storing this data in a text/string field, this object is stored as an enum type. This means there are limited and defined possible choices this value can be – and it will never fall outside of these possible values. This becomes really helpful in scripts for the consumer of the cmdlet to make logic decisions based on the value (such as the leveraging the switch statement).

How do we know the property is an enum type?

Utilize the GetType() method found on any object inside PowerShell (or, the .NET Framework). In the example below we have run GetType() against both the Name and State properties of the VM object. As seen in the output the base type for State is System.Enum. This means we have an enum type.

  1. PS C:\> $virtualmachine.Name.GetType()
  2.  
  3. IsPublic IsSerial Name                                     BaseType
  4. -------- -------- ----                                     --------
  5. True     True     String                                   System.Object
  6.  
  7. PS C:\> $virtualmachine.State.GetType()
  8.  
  9. IsPublic IsSerial Name                                     BaseType
  10. -------- -------- ----                                     --------
  11. True     True     VMState                                  System.Enum

How do we find the other possible enumeration values?

If the VM is currently in Running state, what other possible states exist? This is a very common question that arises when working with enums. The answer is usually found in the cmdlet documentation, but this is not always the case. Follow these steps to retrieve the answer on your own:

First, locate the full name of the enumeration type. Extract the FullName property from the enum, as depicted below.

  1. PS C:\> $virtualmachine.State.GetType().FullName
  2. Microsoft.HyperV.PowerShell.VMState

Second, call the GetValues() static method on the enum type. Be sure to enclose the full type name inside square brackets. Example with desired output is below.

Note 1: If you attempt to use GetValues() on the partial type name (VMState) instead of the full type name (Microsoft.HyperV.PowerShell.VMState), PowerShell is likely going to complain that it can’t find the type. Ensure you use the full type name.

Note 2: A newer PSv3 only method to accomplish this same task is to call [Microsoft.HyperV.PowerShell.VMState].GetEnumValues().

  1. PS C:\> [enum]::GetValues([Microsoft.HyperV.PowerShell.VMState])
  2. Other
  3. Running
  4. Off
  5. Stopping
  6. Saved
  7. Paused
  8. Starting
  9. Reset
  10. Saving
  11. Pausing
  12. Resuming
  13. RunningCritical
  14. OffCritical
  15. StoppingCritical
  16. SavedCritical
  17. PausedCritical
  18. StartingCritical
  19. ResetCritical
  20. SavingCritical
  21. PausingCritical
  22. ResumingCritical

Capturing enumeration Integer values:

To take it one step further, you can also find the associated integer values of the enumeration. This can be useful in certain programming scenarios.

Here is a one-liner to accomplish that. All we do is cast the enumeration value to int and print it to the screen along with the text value.

  1. PS C:\> foreach ($v in [enum]::GetValues([Microsoft.HyperV.PowerShell.VMState])) { write-host ([int]$v): $v }
  2. 1 : Other
  3. 2 : Running
  4. 3 : Off
  5. 4 : Stopping
  6. 6 : Saved
  7. 9 : Paused
  8. 10 : Starting
  9. 11 : Reset
  10. 32773 : Saving
  11. 32776 : Pausing
  12. 32777 : Resuming
  13. 32778 : RunningCritical
  14. 32779 : OffCritical
  15. 32780 : StoppingCritical
  16. 32781 : SavedCritical
  17. 32782 : PausedCritical
  18. 32783 : StartingCritical
  19. 32784 : ResetCritical
  20. 32785 : SavingCritical
  21. 32786 : PausingCritical
  22. 32787 : ResumingCritical