2

So the question is fairly simple but I'm not sure how to word it in order to find the answer.

I'm trying to access a class i.e. [MyCustomClass] in order to check static properties but I need to do it dynamically. How do I inject the class name like [$className]?

Or are there any cmdlets or .NET class functions I can use for this purpose? I tried searching Get-Command *Class* and some similar commands but am not coming up with anything.

Efie
  • 1,430
  • 2
  • 14
  • 34

2 Answers2

4

There are 2 primary options for resolving a given type by name, each with slightly different behavior:

  1. Using a cast to [type]:
$className = 'MyCustomClass'
$myType = [type]$className

Attempting to cast a non-existing type name will throw an exception:

PS ~> [type]'Not actually a type'
Cannot convert the "Not actually a type" value of type "System.String" to type "System.Type".
At line:1 char:1
+ [type]'Not actually a type'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastFromStringToType
  1. Using the -as type conversion operator (introduced in PowerShell version 3.0):
$myType = 'MyCustomClass' -as [type]

Unlike casting, the -as operator never throws - it simply returns $null:

PS ~> $myType = 'this does not exist' -as [type]
PS ~> $null -eq $myType
True

Common for both of these is that you can now resolve the static members of [MyCucstomClass]:

$myType::MyProperty

The static member operator :: also works on instance references, so if you have an object of type [MyCustomClass], use that in place of a type literal:

class MyClass
{
  static [string] $StaticValue = 'Static string value'
}
PS ~> $instance = [MyClass]::new()
PS ~> $instance::StaticValue
Static string value
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
1

You can use Invoke-Expression to run something you still have to build:

$class = 'DateTime'
Invoke-Expression "[$class]::Now"
Cpt.Whale
  • 4,784
  • 1
  • 10
  • 16
  • 2
    The obligator warning; this is a classic example of better alternatives being available: `Invoke-Expression` (`iex`) should generally be _avoided_ and used only as a _last resort_, due to its inherent security risks. In short: Avoid it, if possible, given that superior alternatives are usually available. If there truly is no alternative, only ever use it on input you either provided yourself or fully trust - see [this answer](https://stackoverflow.com/a/51252636/45375). – mklement0 Jun 17 '21 at 20:17
  • 3
    This should probably come with a warning about passing untrusted input to `Invoke-Expression` :-) – Mathias R. Jessen Jun 17 '21 at 20:18
  • 1
    Both these comments are absolutely true - use mr. Jenssen's answer in any real use case. – Cpt.Whale Jun 17 '21 at 21:28