ConvertTo-PSTypeFormat.ps1

#Inspired by: https://seeminglyscience.github.io/powershell/2017/04/20/formatting-objects-without-xml

using namespace System.Management.Automation
using namespace System.Collections.Generic
using namespace Microsoft.PowerShell.Commands.Internal.Format
function ConvertTo-PSTypeFormat {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,ValueFromPipeline)]$InputObject,
        [Parameter(Mandatory)]$TypeName,
        [Parameter(ParameterSetName='Path')][String]$Path,
        [Parameter(ParameterSetName='Path')][Switch]$Force,
        [Parameter(ParameterSetName='Path')][Switch]$NoClobber,
        [Parameter(ParameterSetName='Path')][Switch]$IncludeScriptBlock,
        [Switch]$Wrap,
        [Switch]$OutOfBand
    )
    #We want all the objects together that were passed on the pipeline, so we coalesce them into a list.
    begin {
        $FormatData = [List[Object]]@()
    }
    process {
        $FormatData.Add($InputObject)
    }

    end {
        $FormatStartData = $FormatData[0]
        #This type must be internal, can't do a -is compare
        if ($FormatStartData.gettype().fullname -ne 'Microsoft.PowerShell.Commands.Internal.Format.FormatStartData') {
            throw "The object on the pipeline was not Format-Table output. You must pass Format-Table output to this command."
        }
        $tableControl = [TableControl]::Create(
            $OutOfBand, 
            [bool]$FormatStartData.autoSizeInfo, 
            $formatStartData.hideHeader
        )
        $rowDefinition = $tablecontrol.startrowdefinition($Wrap)
        $Columns = $formatStartData.shapeinfo.tablecolumninfolist | Select-Object alignment,label,propertyname,width

        $Columns.Foreach{
            if (-not $PSItem.propertyName) {$PSItem.propertyName = $PSItem.label}
            [void]$tableControl.AddHeader($PSItem.alignment, $PSItem.width, $PSItem.label)
            [void]$rowDefinition.AddPropertyColumn($PSItem.propertyname, $PSItem.alignment)
        }
        [void]$rowDefinition.EndRowDefinition()
        $tableControl = $tableControl.EndTable()

        [ExtendedTypeDefinition[]]$extendedTypeDefinition = [ExtendedTypeDefinition]::new(
            $TypeName,
            [FormatViewDefinition]::new('TableCustom', $TableControl) -as [List[FormatViewDefinition]]
        )

        if ($Path) {
            Export-FormatData -InputObject $extendedTypeDefinition -Path $path -Force:$Force -NoClobber:$NoClobber -IncludeScriptBlock:$IncludeScriptBlock
        } else {
            return $extendedTypeDefinition
        }
    }

}