Search code examples
powershellpowershell-remoting

Serializing PsObject for Invoke-Command


I'm looking for the best or proper way to pass a PsObject to a remote function with Invoke-Command. ConvertTo-Xml is good for serializing but there is no built-in reverse cmdlet. The solutions I've found online are all content specific.

I implemented the following functions which works with the few objects I tested but seems rather hacky. Is this going to bite me? Is there a better, yet still simple solution?

function Get-TmpFileName () {...}

function Serialize-PsObject($obj) {
    $tmpFile = Get-TmpFileName
    Export-Clixml -InputObject $obj -Path $tmpFile
    $serializedObj = Get-Content $tmpFile
    Remove-Item $tmpFile
    $serializedObj
}

function Deserialize-PsObject($obj) {
    $tmpFile = Get-TmpFileName
    $obj > $tmpFile
    $deserializedObj = Import-Clixml $tmpFile
    Remove-Item $tmpFile
    $deserializedObj
}

Solution

  • Are you aware that PowerShell already serializes objects sent through Invoke-Command?

    If for some reason that isn't enough or isn't working for you, then you can use use the built-in serialization yourself directly:

    $clixml = [System.Management.Automation.PSSerializer]::Serialize($object)
    $object = [System.Management.Automation.PSSerializer]::Deserialize($clixml)
    

    .Serialize has an overload where you can specify the depth (for objects within objects).

    These are the same methods used in implementing Export-Clixml and Import-Clixml (but those cmdlets work directly with files and not strings).