Different results with invoke-command vs local command

87 Views Asked by At

Executing practically the same command but remotely delivers no results in Powershell.

This delivers empty lines:

$certificates = Invoke-Command -ComputerName $computername -ScriptBlock { 
    Get-ChildItem Cert:\LocalMachine\My 
}

foreach ($certificate in $certificates)
{
    $certificate.FriendlyName
}

meanwhile this script locally on the remote computer delivers the desired results:

$certificates = Get-ChildItem Cert:\LocalMachine\My 

foreach ($certificate in $certificates)
{
    $certificate.FriendlyName
}

I use the Invoke-Command in another script with certificates and works perfectly fine. All the other properties except FriendlyName work perfectly fine. I added all the friendly names on the certificates today, maybe the computer I run invoke-command from hasn't caught on yet?

2

There are 2 best solutions below

2
brettkanker On BEST ANSWER

Found the solution. Had to do this pipeline thingy for whatever reason

$certificates = Invoke-Command -ComputerName $computername -ScriptBlock { 
    Get-ChildItem Cert:\LocalMachine\My | Select FriendlyName
}

foreach ($certificate in $certificates)
{
    $certificate.FriendlyName
}
0
mklement0 On

Your own solution is effective; let me add an explanation:

Background information:
  • In cross-process communication such as in PowerShell remoting, serialization is of necessity involved.

  • PowerShell uses a specialized XML format, CLIXML, for serialization.

  • Only instances of a select few, well-known types are deserialized as their original type. All others are deserialized as emulations of the original instances, using method-less [psobject] instances that contain static copies of the property values of the original instances.


It looks like you've run into a bug:


Workarounds:

Querying the .FriendlyName property at the remote source is indeed the solution, as in your solution.

If you want to return not just that property, but all of the certificates' properties, pipe to Select-Object -Property *, which in essence emulates what the remoting serialization does for non-well-known types, i.e. it creates method-less emulations of the original objects with static copies of their property values:

Invoke-Command -ComputerName $computername -ScriptBlock { 
    Get-ChildItem Cert:\LocalMachine\My | Select-Object -Property *
} | 
  Select-Object Issuer, FriendlyName  |
  Format-List

The above, as an example, (also) uses Select-Object client-side to extract multiple properties of interest.