当我在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
但是当我尝试通过
在本地计算机上使用Remote PowerShell时$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri ("http://" + $Server + "/PowerShell/") -Authentication Kerberos
Import-PSSession $Session
并运行它只显示的相同代码:
PS> Get-Mailbox Testeria | select -ExpandProperty EmailAddresses smtp:Tester_IA@contoso.com SMTP:TesterIA@contoso.com smtp:TesterIA@outlook.contoso.com
如何理解这种行为?如何通过Remote PowerShell获取所有属性?
本地计算机上的PSVersion是5.1.14409.1005
Exchange Server上的PSVersion是4.0
答案 0 :(得分:3)
这可能是因为当您通过PSRemoting访问对象时,结果被反序列化。您可以通过将结果对象的TypeName查询到Get-Member
来查看这种情况。您将看到反序列化的前缀为Type:
具有"反序列化的对象。"其类型名称中的前缀是属性包,其中包含反序列化的public表示形式 相应的远程,活动对象的属性。如你看到的 在Get-Member的输出中,这些属性包不会暴露任何 除ToString()之外的方法,因为通常无法调用方法 在远程会话中(例如,System.Diagnostics.Process.Kill() 无法对远程进程采取行动)。同样设置和获取属性 属性包的值不执行任何代码(例如 的WorkingSet属性 Deserialized.System.Diagnostics.Process.WorkingSet只是一个快照 并且当远程进程使用更多内存时不会更新。
我的假设是EmailAddresses
属性是一个脚本属性,这意味着它在被调用以获取其子属性时执行脚本。通过远程处理检索对象时,您将无法执行此脚本。
不幸的是,我现在没有Exchange系统来验证这一点。
答案 1 :(得分:0)
Mark Wragg's answer 提供了有用的提示,但让我详细说明一下:
通过 PowerShell 的 remoting 基础架构传输的对象在远程源进行基于 XML 的序列化,并在远程源进行反序列化来电者收到。
除了少数几个知名类型之外,类型保真度在序列化/反序列化过程中会丢失,并且反序列化对象是原始对象的模拟,如其类型名称中的 Deserialized.
前缀所示(正如您可以通过访问 .pstypenames[0]
通过管道将其反序列化的实例 Get-Member
);具体来说,这些模拟的限制——除了没有与原版相同的类型标识——是:
有关作为 PowerShell 远程处理基础结构一部分的序列化的更全面概述,请参阅 this answer。
适用于您的案例:
通过远程处理,最初包含在 Get-MailBox
cmdlet 返回的对象的 1
属性中的丰富电子邮件对象实例的集合被转换为 字符串 的集合,通过在每个电子邮件对象实例上调用 .ToString()
,它似乎返回 .EmailAddresses
属性值。
示例:
为简单起见,以下通过使用 Start-Job
调用创建的本地后台作业(后台作业也使用 PowerShell 的远程处理基础设施)演示了递归深度(字符串化)问题:
.ToString()
如您所见,存储在属性 .ProxyAddressString
中的 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
实例已被其 [regex]
表示替换。