-ExpandProperty没有';无法通过远程PowerShell显示所有属性

-ExpandProperty没有';无法通过远程PowerShell显示所有属性,powershell,exchange-server,Powershell,Exchange Server,在Exchange服务器上的Exchange PowerShell中运行以下代码时,它会显示所有属性: PS> Get-Mailbox Testeria | select -ExpandProperty EmailAddresses SmtpAddress : Tester_IA@contoso.com AddressString : Tester_IA@contoso.com ProxyAddressString : smtp:Tester_IA@contoso.co

在Exchange服务器上的Exchange PowerShell中运行以下代码时,它会显示所有属性:

PS> Get-Mailbox Testeria | select -ExpandProperty EmailAddresses SmtpAddress : Tester_IA@contoso.com AddressString : Tester_IA@contoso.com ProxyAddressString : smtp:Tester_IA@contoso.com Prefix : SMTP IsPrimaryAddress : False PrefixString : smtp SmtpAddress : TesterIA@contoso.com AddressString : TesterIA@contoso.com ProxyAddressString : SMTP:TesterIA@contoso.com Prefix : SMTP IsPrimaryAddress : True PrefixString : SMTP SmtpAddress : TesterIA@outlook.contoso.com AddressString : TesterIA@outlook.contoso.com ProxyAddressString : smtp:TesterIA@outlook.contoso.com Prefix : SMTP IsPrimaryAddress : False PrefixString : smtp 并运行相同的代码,仅显示以下内容:

PS> Get-Mailbox Testeria | select -ExpandProperty EmailAddresses smtp:Tester_IA@contoso.com SMTP:TesterIA@contoso.com smtp:TesterIA@outlook.contoso.com PS>Get Mailbox Testeria |选择-ExpandProperty EmailAddresses smtp:测试仪_IA@contoso.com SMTP:TesterIA@contoso.com smtp:TesterIA@outlook.contoso.com 如何理解这种行为?如何通过远程PowerShell获取所有属性

本地计算机上的PSV版本为5.1.14409.1005


Exchange服务器上的PSVersion为4.0

这可能是因为通过PSRemoting访问对象时,结果会反序列化。您可以通过将结果对象的TypeName通过管道连接到
Get Member
来查看它,从而看到这种情况。您将看到类型的前缀为反序列化:

在其类型名称中具有“反序列化”前缀的对象是属性包,其中包含公共数据的反序列化表示 相应远程活动对象的属性。如你所见 在Get成员的输出中,这些属性包不公开任何 方法,因为通常无法调用方法 在远程会话中(例如,System.Diagnostics.Process.Kill()中) 无法对远程进程执行操作)。类似地设置和获取属性 属性包的值不执行任何代码(例如 的工作集属性 反序列化的.System.Diagnostics.Process.WorkingSet只是一个快照 并且在远程进程使用更多内存时不会得到更新)

我的假设是,
EmailAddresses
属性是一个脚本属性,这意味着它在被调用以获取其子属性时执行脚本。通过远程处理检索对象时,将失去执行此脚本的能力

不幸的是,我目前没有一个Exchange系统来验证这一点。

提供了有用的指针,但让我详细说明一下:

  • 通过PowerShell的基础结构传输的对象在远程源进行基于XML的序列化,并在调用者收到时进行反序列化

  • 除少数几个已知类型外,序列化/反序列化过程中会丢失类型保真度反序列化的对象是原始对象的模拟,如反序列化的
    所示。
    其类型名称中的前缀(如访问
    .pstypenames[0]所示)
    在的反序列化实例上,通过管道将其传输到);具体而言,这些仿真的局限性(除了与原始仿真没有相同的类型标识外)是:

    • 反序列化对象缺少原始对象的方法
    • 对于嵌套(标量)对象(由多个属性组成的对象,其值也是由多个属性组成的对象,…),对象图的深度限制为
      1
      • 在实践中,这意味着非已知(标量)类型的实例序列化后,本身不是已知类型实例的属性值将替换为它们的
        .ToString()
        表示形式
有关作为PowerShell远程处理基础架构一部分的序列化的更全面概述,请参见


适用于您的案例

通过远程处理,最初包含在cmdlet返回的对象的
.EmailAddresses
属性中的丰富电子邮件对象实例集合将通过对每个电子邮件对象实例调用
.ToString()
转换为字符串集合,它似乎返回
.ProxyAddressString
属性值


示例

为简单起见,下面通过使用call创建的本地后台作业(后台作业也使用PowerShell的远程处理基础设施)演示递归深度(字符串化)问题:


如您所见,存储在属性
.Bar
中的
[regex]
实例已被其
.ToString()
表示形式所取代。

良好的指针,但我认为
EmailAddresses
对象变成字符串的真正原因是远程处理基础结构应用于非已知(标量)对象的隐式递归深度限制,它用
.ToString()
值替换本身不是已知类型实例的属性值。 PS> Get-Mailbox Testeria | select -ExpandProperty EmailAddresses smtp:Tester_IA@contoso.com SMTP:TesterIA@contoso.com smtp:TesterIA@outlook.contoso.com
PS> Start-Job { 
      # Define a custom class, which is by definition not a well-known type.
      # Give it a property of another non-well-known type, [regex].
      class Foo { $Bar = [regex] 'hi' }
      # Output an instance of the custom class.
      [Foo]::new() 
    } | Receive-Job -Wait -AutoRemove | 
        ForEach-Object {
          $_.Bar                     # Output the .Bar property value...
          $_.Bar.GetType().FullName  # ... and its data type.
        }

hi
System.String