Defining Custom Powershell Objects

There are many different ways to create objects in Powershell. I place this as a call to create objects exclusively in Powerhell. I am looking for a way to create objects using Add-Type that pass these requirements:

  • Strongly typed object properties
  • Initiated using: New-Object , [My.Object]::New() , [My.Object]@{'Property'='Value'}
  • Part of the user namespace (ie [My.Object])
  • You can check the type. Example: $myVar -is [My.Object]

I know that a dll can be created in Visual Studio that will do this, but I'm looking for a pure Powershell way to create objects.

Here is the closest example that complies with the above rules:

 PS C:\> $memberDef = @" public String myString { get; set; } public int myInt { get; set; } "@ PS C:\> Add-Type -Namespace "My.Namespace" -Name "Object" -MemberDefinition $memberDef PS C:\> $myObj = [My.Namespace.Object]@{'myString'='Foo'; 'myInt'=42} PS C:\> $myObj myString myInt -------- ----- Foo 42 

With that in mind, are there other (possibly better) ways to create objects that look, feel and act like native Powershell objects?

Examples that do not satisfy all the rules

Weakly typed object properties:

 PS C:\> $myObj = "" | Select-Object -Property myString, myInt PS C:\> $myObj = New-Object -TypeName PSObject -Property @{'myString'='foo'; 'myInt'=42} PS C:\> $myObj = @{}; $myObj.myString = 'foo'; $myObj.myInt = 42 PS C:\> $myObj.myInt = "This should result in an error." 

Objects without namespaces:

 PS C:\> $typeDef = @" public class myObject { public string myString { get; set; } public int myInt { get; set; } } "@ PS C:\> Add-Type -TypeDefinition $typeDef PS C:\> $myObj = [myObject]::new() PS C:\> $myObj = New-Object -TypeName PSObject -Property @{'myString'='foo'; 'myInt'=42} PS C:\> $myObj.PSObject.TypeNames.Insert(0, "myObject") 
+5
source share
2 answers

This is the best way to find an object in Powershell that is part of the namespace and covers all of the above rules.

 PS C:\> $memberDef = @" public String myString { get; set; } public int myInt { get; set; } "@ PS C:\> Add-Type -Namespace "My.Namespace" -Name "Object" -MemberDefinition $memberDef PS C:\> $myObj = [My.Namespace.Object]@{'myString'='Foo'; 'myInt'=42} PS C:\> $myObj myString myInt -------- ----- Foo 42 
0
source
  • Strongly typed object

The closest you are going to get is an explicitly typed variable. This can be done by casting the variable itself during the assignment:

 PS C:\> [My.Namespace.Object]$myObj = [My.Namespace.Object]@{'myString'='Foo'; 'myInt'=42} PS C:\> $myObj = 123 Cannot convert the "123" value of type "System.Int32" to type "My.Namespace.Object". At line:1 char:1 + $myObj = 123 + ~~~~~~~~~~~~ + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException + FullyQualifiedErrorId : RuntimeException 

As you can see, this leads to the fact that $myObj accepts only new assignments that can be implicitly converted to type.

+1
source

All Articles