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