Private/ConvertTo-DuneClassObject.ps1

function ConvertTo-DuneClassObject {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline)]
        [object]$InputObject,
        [Parameter()]
        [string]$Class
    )
    begin{}
    process{
        if ($null -eq $InputObject) {
            return $null
        }
        else {
            $Object = New-Object -Type $Class
            $Properties = $Object | Get-Member | Select-Object *, @{L="Type";E={$_.Definition.Split(" ")[0]}} | Where-Object MemberType -like *Property | ? {$_.Name -in ($InputObject | Get-Member -MemberType NoteProperty).Name}
            foreach ($Property in $Properties) {
                if ($Property.Type -like "Dune*") {
                    if ($Property.Type -match "\w\[\]") {
                        if ($InputObject.($Property.Name) -is [Array] -and $InputObject.($Property.Name).Count -eq 0) {
                            # Declare empty arrays (otherwise it will be $null)
                            $Object.($Property.Name) = @()
                        }
                        else{
                            $Object.($Property.Name) = $InputObject.($Property.Name) | % {
                                ConvertTo-DuneClassObject -InputObject $_ -Class $Property.Type.Replace('[]','')
                            }
                        }
                    }
                    else {
                        $Object.($Property.Name) = ConvertTo-DuneClassObject -InputObject $InputObject.($Property.Name) -Class $Property.Type
                    }
                }
                else {
                    if ($null -ne $InputObject.($Property.Name)) {
                        if ($Property.type -in ("datetime","System.Nullable[datetime]") -and $Script:Config.ToLocalTime) {
                            if ($InputObject.($Property.Name) -eq "9999-12-31T23:59:59.9999999Z"){
                                $Object.($Property.Name) = "9999-12-31T23:59:59.9999999" #WORKAROUND FOR PS5 BUG: Cannot convert value "9999-12-31T23:59:59.9999999Z" to type "System.DateTime". Error: "The DateTime represented by the string is out of range."
                            }
                            else{
                                $Object.($Property.Name) = ([DateTime]($InputObject.($Property.Name))).ToLocalTime()
                            }
                        }
                        else{
                            $Object.($Property.Name) = $InputObject.($Property.Name)
                        }
                    }
                }
            }
            return $Object
        }
    }
    end{}
}