How to dynamically define a class in C # PowerShell Cmdlet

I have some data that I get from a data source, which is a group of name / value pairs that I store in the <string, object> dictionary.

I want to define a class on the fly with properties that map to key / value pairs from the dictionary and methods based on the type of data it represents. This would allow the cmdlet user to access the values ​​as properties of the object and also call methods on it.

I see an example of this with Get-WmiObject. It returns instances of ManagementObject (which is basically the total amount of properties), but the user can access the properties and call methods on it directly (i.e., without calling GetPropertyValue / InvokeMethod methods in ManagementObject).

PS C:\temp> $comp = Get-WmiObject Win32_ComputerSystem PS C:\temp> $comp | Get-Member TypeName: System.Management.ManagementObject#root\cimv2\Win32_ComputerSystem Name MemberType Definition ---- ---------- ---------- JoinDomainOrWorkgroup Method System.Management.ManagementBaseObject JoinDomainO Rename Method System.Management.ManagementBaseObject Rename(Syst SetPowerState Method System.Management.ManagementBaseObject SetPowerSta UnjoinDomainOrWorkgroup Method System.Management.ManagementBaseObject UnjoinDomai AdminPasswordStatus Property System.UInt16 AdminPasswordStatus {get;set;} AutomaticManagedPagefile Property System.Boolean AutomaticManagedPagefile {get;set;} AutomaticResetBootOption Property System.Boolean AutomaticResetBootOption {get;set;} ... etc ... 

How to do this with my own objects?

UPDATE

Accepting Keith's answer, which is a common .NET Framework approach for dynamically generating code. This should work for my scenario, although I think it might be redundant.

I was hoping someone would provide a vivid example of this using the tools provided by PowerShell. There seems to be a way to dynamically create a class by extending the PSObject , PSProperty, and PSMethod described in the Powershell SDK .

Unfortunately, the documentation around this seems rather poor with a lot of ridiculous statements like "Although this class can be derived from this class, there is no established script for this, and any attempt to do this may lead to unexpected behavior."

What's even worse is that all the MSDN links explaining the PowerShell extended type system seem bad! And the only examples I've seen on the Internet is to do this from a PowerShell script, and not for people developing cmdlets using the C # and SDK.

Hi, is anyone on the PowerShell team listening?

+7
source share
3 answers

Take a look at the System.Reflection.Emit namespace . This will allow you to generate code at runtime. System.AppDomain has several overloads called DefineDynamicAssembly , which usually start with you. This returns an AssemblyBuilder , and from there you use types like TypeBuilder , PropertyBuilder , MethodBuilder , etc. This CodeProject article is a worthy primer for creating dynamic types with reflection.

+3
source

The ability to define your own new classes is something new that they added to PowerShell v2. Here is an example:

 PS C:\> $def = @" public class MyClass { public string MyProperty; } "@ PS C:\> Add-Type -TypeDefinition $def PS C:\> $obj = New-Object MyClass PS C:\> $obj.MyProperty = "Hello" PS C:\> $obj MyProperty ---------- Hello 

If you don’t need something too complicated, you can use "splatting" - usually this is to create name / value pairs for passing to cmdlets or functions, but it can work as a general object too:

 PS C:\> $splat = @{ Name = "goyuix" Site = "stackoverflow.com" Tag = "powershell" } PS H:\> $splat Name Value ---- ----- Name Goyuix Site stackoverflow.com Tag powershell 
+6
source

I am working on improving the implementation of PSClass.

Source of implementation: https://github.com/ghostsquad/AetherClass/blob/master/functions/New-PSClass.ps1

Tests using: https://github.com/ghostsquad/AetherClass/blob/master/test/New-PSClass.Tests.ps1

There is also functionality for mock psclasses, i.e. you get all the excellent Moq functionality with dynamic psobject.

0
source

All Articles