Created
November 7, 2023 14:38
-
-
Save PanosGreg/df2b8a262545fe859e621e791a6b5c35 to your computer and use it in GitHub Desktop.
Dynamically generate the PowerShell class code from a pscustomobject or hashtable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function ConvertTo-ClassDefinition { | |
<# | |
.EXAMPLE | |
$hash = @{name='aa';size=10} | |
$code = $hash | ConvertTo-ClassDefinition | |
Invoke-Expression $code | |
$h = [My_Hashtable]::new() | |
# create and load a class from a hashtable | |
.EXAMPLE | |
$obj = [pscustomobject]@{name='aa';size=10} | |
Invoke-Expression ($obj | ConvertTo-ClassDefinition) | |
$p = [My_PSCustomObject]::new() | |
# create and load a class from a ps custom object | |
.EXAMPLE | |
$obj = [pscustomobject]@{name='aa';size=10} | |
$obj | ConvertTo-ClassDefinition -Hidden size | |
# create a class definition with a hidden property | |
.EXAMPLE | |
$obj = [pscustomobject]@{name='aa';size=10} | |
$code = $obj | ConvertTo-ClassDefinition -Hidden size | |
Invoke-Expression $code | |
$p = [My_PSCustomObject]@{Name = 'aa' ; Size = 12} | |
$p | Select-Object -Property ($p | Get-Member -MemberType Property -Force).Name | |
# create a class with a hidden property, then instiate it into a new object | |
# and finally show all of its properties, even the hidden one. | |
#> | |
[OutputType([string])] # <-- the powershell class definition as plain text | |
[CmdletBinding()] | |
param( | |
[Parameter(Position=0,Mandatory,ValueFromPipeline)] | |
[ValidateNotNull()] | |
$InputObject, | |
[ValidateNotNullOrEmpty()] | |
[string]$ClassName, | |
[ValidateNotNullOrEmpty()] | |
[string[]]$IncludeProperty = '*', | |
[ValidateNotNullOrEmpty()] | |
[string[]]$ExcludeProperty, | |
[ValidateNotNullOrEmpty()] | |
[string[]]$HiddenProperty | |
) | |
# if input has many items, then get only the 1st item | |
if (([array]$InputObject).Count -ge 2) {$InputObject = $InputObject[0]} | |
# make sure the input object is either a pscustomobject or a hashtable (ordered or not) | |
$SupportedTypes = 'System.Collections.Hashtable', | |
'System.Management.Automation.PSCustomObject', | |
'System.Collections.Specialized.OrderedDictionary' | |
$ObjectType = $InputObject.psobject.TypeNames[0] | |
if ($ObjectType -notin $SupportedTypes) { | |
Write-Warning 'Please provide a supported data type of either a hashtable (ordered or not) or pscustomobject' | |
return | |
} | |
# convert hashtable into a ps custom object | |
$HashTypes = 'System.Collections.Hashtable','System.Collections.Specialized.OrderedDictionary' | |
if ($ObjectType -in $HashTypes) { | |
$InputObject = [pscustomobject]$InputObject | |
} | |
# set the name of the class | |
$ShortTypeName = $ObjectType.Split('.')[-1] | |
if ($ClassName) {$BaseClassName = $ClassName} | |
else {$BaseClassName = 'My_' + $ShortTypeName} # <-- unfortunately PS classes can't take dots in the name | |
# get properties | |
$AllProps = $InputObject.psobject.properties | |
$Filter = { | |
$_.Name -in $IncludeProperty -and | |
$_.Name -notin $ExcludeProperty | |
} | |
if ($IncludeProperty -ne '*') {$Properties = $AllProps | Where $Filter} | |
else {$Properties = $AllProps | Where Name -notin $ExcludeProperty} | |
# start building the class definition | |
$SB = [System.Text.StringBuilder]::new() | |
[void]$SB.AppendLine("class $BaseClassName {`n") | |
# add all properties | |
foreach ($Property in $Properties) { | |
$Name = $Property.Name | |
$Type = $Property.TypeNameOfValue | |
if ($Name -in $HiddenProperty) { | |
[void]$SB.AppendLine(" hidden [$Type]`$$Name") | |
} | |
else { | |
[void]$SB.AppendLine(" [$Type]`$$Name") | |
} | |
} | |
# add constructor and end the class | |
[void]$SB.AppendLine("`n $BaseClassName () {}`n") | |
[void]$SB.AppendLine('}') | |
# output the class definition | |
$SB.ToString() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment