Powershell 管道类型的差异

Powershell 管道类型的差异,powershell,Powershell,为什么: Invoke-Command -ScriptBlock { Get-Service } -ComputerName SERVER01 | Get-Member 返回TypeName:Deserialized.System.ServiceProcess.ServiceController 但是: 返回PSObject的类型Name和System.Object的BaseType Edit:我知道从Invoke命令返回的对象是反序列化的。同样的对象被GetType()和getmember报

为什么:

Invoke-Command -ScriptBlock { Get-Service } -ComputerName SERVER01 | Get-Member
返回TypeName:Deserialized.System.ServiceProcess.ServiceController

但是:

返回
PSObject
的类型
Name
System.Object的
BaseType

Edit:我知道从
Invoke命令返回的对象是反序列化的。同样的对象被
GetType()
getmember
报告为不同的类型,这似乎很奇怪

PS C:\src\t> $gss = Invoke-Command -ScriptBlock { Get-Service } -ComputerName SERVER01

PS C:\src\t> $gss[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSObject                                 System.Object

PS C:\src\t> $gss[0] | Get-Member

   TypeName: Deserialized.System.ServiceProcess.ServiceController

在远程会话上运行返回对象的命令时(这意味着使用
-ComputerName
参数,即使它是针对运行该命令的同一台计算机执行的)PowerShell将对象转换为包含原始对象的所有属性但不包含其任何方法的
PSObject
。由于
Get Member
返回的反序列化前缀,您可以验证何时发生这种情况。发生这种情况的原因是PowerShell无法在远程对象上运行方法。但是,您将看到可以在本地运行的方法,例如
ToString()

只有少数基本类型和几乎基本类型被真正引入,并且不会得到这种转换。下面不是一个广泛的列表,而是已经给出的示例

  • 字节,SByte,字节[]
  • Int16、Int32、Int64、UInt16、UInt32、UInt64
  • 十进制、单精度、双精度
  • TimeSpan、DateTime、ProgressRecord
  • Char、String、XmlDocument、SecureString
  • 布尔值、Guid、Uri、版本
  • 列举

可以找到有关此行为的更多信息。

可能值得注意的是,
Get Member
不使用反射来提取类型名,而是显示
$\pstypenames[0]
我选择此作为答案,因为它似乎就是这样工作的。PowerShell在返回的类型上似乎不一致。它由
Get Member
报告为一种类型,由GetType()报告为另一种类型。Get-Member和GetType()有不同的用例,因此使用不同的方法返回对象类型。GetType()是一个.NET方法,将在.NET中如何查看该类型的上下文中返回该类型,Get成员是PowerShell cmdlet,并将在PowerShell中如何查看该类型的上下文中返回该类型。
PS C:\src\t> $gss = Invoke-Command -ScriptBlock { Get-Service } -ComputerName SERVER01

PS C:\src\t> $gss[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSObject                                 System.Object

PS C:\src\t> $gss[0] | Get-Member

   TypeName: Deserialized.System.ServiceProcess.ServiceController