ConvertToClass.psm1
function Test-String { param($p) $testResult = $false if($p -is [System.ValueType] -Or $p -is [string]) { $testResult=$p -is [string] } [PSCustomObject]@{ Test=$testResult DataType = "string" } } function Test-Date { param($p) $testResult = $false if($p -is [System.ValueType] -Or $p -is [string]) { [datetime]$result = [datetime]::MinValue $testResult=[datetime]::TryParse($p, [ref]$result) } [PSCustomObject]@{ Test=$testResult DataType = "datetime" } } function Test-Boolean { param($p) $testResult = $false if($p -is [System.ValueType]) { [bool]$result=$false $testResult = [bool]::TryParse($p, [ref]$result) } [PSCustomObject]@{ Test=$testResult DataType = "bool" } } function Test-Number { param($p) $testResult = $false if($p -is [System.ValueType] -Or $p -is [string]) { [double]$result = [double]::MinValue $testResult=[double]::TryParse($p, [ref]$result) } [PSCustomObject]@{ Test=$testResult DataType = "double" } } function Test-Integer { param($p) $testResult = $false if($p -is [System.ValueType] -Or $p -is [string]) { [int]$result = [int]::MinValue $testResult=[int]::TryParse($p, [ref]$result) } [PSCustomObject]@{ Test=$testResult DataType = "int" } } function Test-PSCustomObject { param($p) $testResult=$p -is [System.Management.Automation.PSCustomObject] [PSCustomObject]@{ Test=$testResult DataType = "PSCustomObject" } } function Test-Array { param($p) $testResult=$p -is [array] [PSCustomObject]@{ Test=$testResult DataType = "Array" } } $tests = [ordered]@{ TestBoolean = Get-Command Test-Boolean TestInteger = Get-Command Test-Integer TestNumber = Get-Command Test-Number TestDate = Get-Command Test-Date TestString = Get-Command Test-String TestPSCustomObject = Get-Command Test-PSCustomObject TestArray = Get-Command Test-Array } function Invoke-AllTests { param( $target, [Switch]$OnlyPassing, [Switch]$FirstOne ) $resultCount=0 $tests.GetEnumerator() | ForEach { $result=& $_.Value $target $testResult = [PSCustomObject]@{ Test = $_.Key Target = $target Result = $result.Test DataType = $result.DataType } if(!$OnlyPassing) { $testResult } elseif ($result.Test -eq $true) { if($FirstOne) { if($resultCount -ne 1) { $testResult $resultCount+=1 } } else { $testResult } } } } function Get-DataType { param($record) $p=@($record.psobject.properties.name) for ($idx = 0; $idx -lt $p.Count; $idx++) { $name = $p[$idx] $value = $record.$name if($value -eq $null) { $dataType = "object" } else { $result=Invoke-AllTests $value -OnlyPassing -FirstOne $dataType = $result.DataType } [PSCustomObject]@{ Name = $name Value = $value DataType = $dataType } } } $PowerShellConverter = @' function NewClass ([string]$name) {"class $name {`r`n"} function NewProperty ([string]$DataType, [string]$Name) { return " [$DataType]`$$Name"} function NewArray ([string]$Name) { return " [$Name[]]`$$Name"} function NewObjectArray ([string]$Name) { return " [object[]]`$$Name"} function EndClass () {"`r`n}`r`n"} '@ $CSharpConverter = @' function NewClass ([string]$name) {"class $name `r`n{"} function NewProperty ([string]$DataType, [string]$Name) { return "`t$DataType $Name {get; set;}"} function NewArray ([string]$Name) { return "`t$Name[] $Name {get; set;}"} function NewObjectArray ([string]$Name) { return "`tobject[] $Name {get; set;}"} function EndClass ($name) {"}`r`n"} '@ $classes = @{} function Get-ClassName ($className) { $classes.$className+=1 if($classes.$className -eq 1) { $className } else { "$className$($classes.$className-1)" } } function ConvertTo-Class { [CmdletBinding()] param( $Target, $ClassName, [ValidateSet('PowerShell','CSharp')] $CodeGen="PowerShell", $Converter ) if(!$Converter) { switch ($CodeGen) { 'PowerShell' {$Converter=$PowerShellConverter} 'CSharp' {$Converter=$CSharpConverter} } } #if($Converter) { $Converter | Invoke-Expression } $Converter | Invoke-Expression if($target -is [string]) { try { $cvt = $target | ConvertFrom-Json if(!$className) { $className = Get-ClassName "RootObject" } ConvertTo-Class $cvt $className -CodeGen $CodeGen } catch { try { $cvt = $target | ConvertFrom-Csv | select -First 1 if(!$className) { $className = Get-ClassName "RootObject" } ConvertTo-Class $cvt $className -CodeGen $CodeGen } catch { throw "bad data" } } return } $infered = Get-DataType $target $otherClasses=@() $xport = switch ($infered) { {$_.DataType -eq 'Array'} { if($_.Value[0] -is [string] -or $_.Value[0] -is [System.ValueType]) { Write-Verbose "Object Array $($_.name)" NewObjectArray $_.Name } else { Write-Verbose "Array $($_.name)" if($_.Value.Count -eq 0) { NewObjectArray $_.Name } else { NewArray $_.Name $_.Name $otherClasses+=ConvertTo-Class ($_.Value | select -First 1) (Get-ClassName $_.name) -CodeGen $CodeGen } } } {$_.DataType -eq 'PSCustomObject'} { NewProperty $_.Name $_.Name $otherClasses+=ConvertTo-Class $_.Value (Get-ClassName $_.name) -CodeGen $CodeGen } default { Write-Verbose "Property $($_.DataType) $($_.name)" NewProperty $_.DataType ($_.name -replace "/","") } } NewClass $ClassName @" $($xport -join "`r`n") "@ EndClass $otherClasses } function DoConvert { param($ctx) $target = (Get-ClipBoard) -join "`n" $r=ConvertTo-Class $target $ctx.CurrentFile.InsertText($r, $ctx.SelectedRange) } if ($psEditor) { Register-EditorCommand ` -Name "ConvertToClass.MyEditorCommand" ` -DisplayName "Convert To PowerShell Class" ` -Function DoConvert ` -SuppressOutput } |