Converting PsCustomObject To/From Hashtables

PsCustomObjects are effectively a superset of Hashtables.  Hashtables have name-value pairs.  The names and values don’t have to be strings, but there’s nothing that comes close to a ScriptProperty, etc.  Still, there are some cmdlets and constructs that are available only to Hashtables, but to PsCustomObjects, and vice versa.  Here’s a quick and dirty way to convert between the two, catching only properties and letting methods go by the wayside.

 

function ConvertTo-PsCustomObjectFromHashtable {
     param (
         [Parameter( 
             Position = 0,  
             Mandatory = $true,  
             ValueFromPipeline = $true, 
             ValueFromPipelineByPropertyName = $true 
         )] [object[]]$hashtable
     );
    
     begin { $i = 0; }
    
     process {
         foreach ($myHashtable in $hashtable) {
             if ($myHashtable.GetType().Name -eq 'hashtable') {
                 $output = New-Object -TypeName PsObject;
                 Add-Member -InputObject $output -MemberType ScriptMethod -Name AddNote -Value { 
                     Add-Member -InputObject $this -MemberType NoteProperty -Name $args[0] -Value $args[1];
                 };
                 $myHashtable.Keys | Sort-Object | % { 
                     $output.AddNote($_, $myHashtable.$_); 
                 }
                 $output;
             } else {
                 Write-Warning "Index $i is not of type [hashtable]";
             }
             $i += 1; 
         }
     }
}

function ConvertTo-HashtableFromPsCustomObject {
     param (
         [Parameter( 
             Position = 0,  
             Mandatory = $true,  
             ValueFromPipeline = $true, 
             ValueFromPipelineByPropertyName = $true 
         )] [object[]]$psCustomObject
     );
    
     process {
         foreach ($myPsObject in $psObject) {
             $output = @{};
             $myPsObject | Get-Member -MemberType *Property | % {
                 $output.($_.name) = $myPsObject.($_.name);
             }
             $output;
         }
     }
}