Ironman Software Forums
Continue the conversion on the Ironman Software forums. Chat with over 1000 users about PowerShell, PowerShell Universal, and PowerShell Pro Tools.
Reflection allows you to inspect, invoke and access .NET type data which includes both public and private members. By default, PowerShell provides access to publicly accessible properties and methods but using the reflection APIs, you can access the internals of types in .NET.
You can easily invoke .NET methods in PowerShell with standard syntax. For example, you can call IsDaylightSavingTime()
on a DateTime
object directly in PowerShell.
$DateTime = Get-Date
$DateTime.IsDaylightSavingTime()
You can also invoke the same method using the reflection APIs.
$DateTime = Get-Date
[System.DateTime].GetMethod('IsDaylightSavingTime').Invoke($DateTime, @())
Below, you will find how to call access members of objects using reflection.
The GetType()
method can be called on an object to retrieve the System.Type
for that object.
$DateTime = Get-Date
$Type = $DateTime.GetType()
$Type
You can also get a type by referencing the type directly.
[System.DateTime]
Members are the variables features of a type. This includes fields, properties and methods. You can locate members by using various reflection APIs.
The GetMethod()
and GetMethods()
methods can be used to list methods of a type.
The following will list public methods of the System.DateTime
type.
[System.DateTime].GetMethods() | Select-Object Name
If you wish to locate non-public methods (like internal and private), you can using binding flags.
The following example will return non-public, instance methods.
[System.DateTime].GetMethods([Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::Instance) | Select-Object Name
You can also return non-public, static methods by changing the binding flags.
[System.DateTime].GetMethods([Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::Static) | Select-Object Name
Similar to locating methods, you can also locate properties by using the GetProperty()
and GetProperties()
methods.
For example, you can locate non-public, instance properties with the following.
[System.DateTime].GetProperties([Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::Instance) | Select-Object Name
Finally, you can also locate fields by using the GetField()
and GetFields()
methods. Typically, fields are not public facing and will contain the internals of a type.
[System.DateTime].GetFields([Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::Instance) | Select-Object Name
Once you have access to the type and member you wish to access, you can use the information to access those members.
Invoking a method involves retrieving a reference to the MethodInfo
object through the GetMethod
or GetMethods
methods. Then, you can use the Invoke
method of that class to invoke the method directly. This means you can invoke non-public methods.
$DateTime = Get-Date
$MethodInfo = [System.DateTime].GetMethods([Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::Instance) | Where-Object Name -eq 'IsAmbiguousDaylightSavingTime'
$MethodInfo.Invoke($DateTime, @())
If you were to attempt to execute that method directly, you would get an error.
$DateTime = Get-Date
$DateTime.IsAmbiguousDaylightSavingTime()
To get a property value, you need to look up the property with GetProperty
or GetProperties
. Once you have a reference to the PropertyInfo
object, you can then invoke the getter or setter for that property.
$DateTime = Get-Date
$PropertyInfo = [System.DateTime].GetProperties([Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::Instance) | Where-Object Name -eq 'InternalTicks'
$PropertyInfo.GetGetMethod($true).Invoke($DateTime, @())
You’ll notice that the InternalTicks
property does not exist on a regular DateTime object.
To get a field value, you need to look up a field with GetField
or GetFields
. Once you have a reference to the FieldInfo
object, you can then retrieve the value of the field.
$DateTime = Get-Date
$FieldInfo = [System.DateTime].GetFields([Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::Instance) | Where-Object Name -eq '_dateData'
$FieldInfo.GetValue($DateTime)
Static methods do not require an instance of an object to be present. You can invoke them on the type themselves.
Rather than passing in a value to the Invoke
method, you can pass in $null
.
$MethodInfo = [System.DateTime].GetMethods([Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::Static) | Where-Object Name -eq 'SystemSupportsLeapSeconds'
$MethodInfo.Invoke($null, @())
Sometimes, .NET code is open source and you can look at the source code directly on GitHub. You can also use the .NET reflection APIs to enumerate members within a .NET type. A quicker way to access .NET type information is to decompile to assemblies to view the source code.
PowerShell Pro Tools provides a decompiler to view source code for assemblies loaded into your PowerShell environment.
Find this useful? Please consider sharing this article. Have a question about PowerShell? Contact us and we'll write a post about it.
Continue the conversion on the Ironman Software forums. Chat with over 1000 users about PowerShell, PowerShell Universal, and PowerShell Pro Tools.
Receive once-a-month updates about Ironman Software. You'll learn about our product updates and blogs related to PowerShell.