在 Powershell 中执行几乎相同的命令但远程不会产生任何结果。
这会产生空行:
$certificates = Invoke-Command -ComputerName $computername -ScriptBlock {
Get-ChildItem Cert:\LocalMachine\My
}
foreach ($certificate in $certificates)
{
$certificate.FriendlyName
}
同时远程计算机上的本地脚本可提供所需的结果:
$certificates = Get-ChildItem Cert:\LocalMachine\My
foreach ($certificate in $certificates)
{
$certificate.FriendlyName
}
我在另一个带有证书的脚本中使用 Invoke-Command,并且工作得很好。除了FriendlyName 之外的所有其他属性都工作得很好。我今天在证书上添加了所有友好名称,也许我运行调用命令的计算机还没有流行起来?
找到解决方案。无论出于何种原因都必须做这个管道事情
$certificates = Invoke-Command -ComputerName $computername -ScriptBlock {
Get-ChildItem Cert:\LocalMachine\My | Select FriendlyName
}
foreach ($certificate in $certificates)
{
$certificate.FriendlyName
}
你的自己的解决方案是有效的;让我添加一个解释:
在跨进程通信中,例如在 PowerShell 远程处理期间,必须涉及序列化。
PowerShell 使用专门的 XML 格式 CLIXML 进行序列化。
仅将选定的少数众所周知类型的实例反序列化作为其原始类型。所有其他都使用包含原始实例属性值的静态副本的无方法
[psobject]
实例反序列化为原始实例的仿真。
看起来您遇到了bug:
[System.Security.Cryptography.X509Certificates.X509Certificate2]
Get-ChildItem Cert:...
实例 do 反序列化为其原始类型。
但是 - 这就是错误 -
.FriendlyName
属性值在过程中没有保留。
解决方法:
在远程源
查询
.FriendlyName
属性确实是解决方案,就像您的解决方案一样。
如果您不仅想返回该属性,还想返回证书的所有属性,请通过管道传输到Select-Object
-Property *
,这本质上模拟了远程处理序列化对非众所周知的类型的作用,即它使用其属性值的静态副本创建原始对象的无方法模拟:
Invoke-Command -ComputerName $computername -ScriptBlock {
Get-ChildItem Cert:\LocalMachine\My | Select-Object -Property *
} |
Select-Object Issuer, FriendlyName |
Format-List
上面作为示例,(也)使用 Select-Object
客户端 来提取多个感兴趣的属性。