使用C#运行远程PowerShell代码通过序列化丢失信息?

问题描述:

由于各种原因,我需要使用C#代码中的远程PowerShell命令而不是使用EWS API来查询用户的邮箱自动回复配置。使用C#运行远程PowerShell代码通过序列化丢失信息?

我几乎使用this article作为模板如何做到这一点,我遇到了一个问题,我不能包裹我的头。具体来说,它看起来像是通过远程PowerShell命令的序列化/反序列化过程丢失了一些信息。所以我不能将它转换为另一种类型并将其用于C#代码中。有谁会有一个想法如何找到解决方法或避免这种情况?

向下可以看到运行PowerShell代码的代码,并返回对象并尝试使用它。问题是BaseObject类型是PSCustomObject,因此铸造/检查不起作用。我不知道如何访问自定义对象公开的属性。使用VS中的调试工具,我可以看到它实际上拥有所有数据。如果我直接在PowerShell中运行代码,则可以看到$configuration的数据类型为Deserialized.Microsoft.Exchange.Data.Storage.Management.MailboxAutoReplyConfiguration。所以我猜它实际上在序列化过程中会丢失该对象的一些信息?

另一个问题我还没有检查(因为我真的想避免它)会是我运行此代码的系统没有安装Exchange程序集。这也是为什么我使用笨重的BaseObject.GetType().ToString()方法来检查类型,因为我无法引用该类型并使用is。但我实际上期待从PowerShell对象获得一个自给自足的数据结构。我错了,这将如何工作?

using (PowerShell PowerShellInstance = PowerShell.Create()) 
{ 
    // add a script that creates a new instance of an object from the caller's namespace 
    PowerShellInstance.AddScript(@" 
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI <URI> 
Import-PSSession $session 
$configuration = Get-MailboxAutoReplyConifguration -identity <E-Mail> 

# Put it on the output stream 
$configuration 
    "); 

    // invoke execution on the pipeline (collecting output) 
    Collection<PSObject> PSOutput = PowerShellInstance.Invoke(); 

    // loop through each output object item 
    foreach (PSObject outputItem in PSOutput) 
    { 
     if (outputItem != null) 
     { 
      if(outputItem.BaseObject.GetType().ToString() == "Microsoft.Exchange.Data.Storage.Management.MailboxAutoReplyConfiguration"){ 
       # We have a decrepancy here as the above is the Exchange API class and 
       # below would be the EWS API class. As they expose the same attributes I'd expect it to work. 
       OofSettings settings = outputItem.BaseObject as OofSettings 
      } 
     } 
    } 
} 

这正是问题:反序列化破坏了原有的PowerShell的对象生成脚本,并创建一个新的,与源对象的数据,而不是方法,据我所知(类型PSObject)。

解决方法是在PowerShell脚本中执行任务,或者直接在第一个脚本中完成任务(任何更适合您的需求)。

对于你的榜样,我的意思是这样的:

using (PowerShell PowerShellInstance = PowerShell.Create()) 
{ 
    // add a script that creates a new instance of an object from the caller's namespace 
    PowerShellInstance.AddScript(@" 
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI <URI> 
Import-PSSession $session 
$configuration = Get-MailboxAutoReplyConifguration -identity <E-Mail> 
***INSERT HERE Powershell-Cmdlets to do the things you need*** 

# Put it on the output stream 
$configuration 
    "); 

    // invoke execution on the pipeline (collecting output) 
    Collection<PSObject> PSOutput = PowerShellInstance.Invoke(); 

    // loop through each output object item 
    foreach (PSObject outputItem in PSOutput) 
    { 
     if (outputItem != null) 
     { 
      if(outputItem.BaseObject.GetType().ToString() == "Microsoft.Exchange.Data.Storage.Management.MailboxAutoReplyConfiguration"){ 
       # We have a decrepancy here as the above is the Exchange API class and 
       # below would be the EWS API class. As they expose the same attributes I'd expect it to work. 
       OofSettings settings = outputItem.BaseObject as OofSettings 
      } 
     } 
    } 
} 
+0

我其实需要,因为它是一个ASP.NET MVC应用程序中的C#一部分的对象,我需要显示的信息。我的解决方案是检查类型(只使用'outputItem.ToString()',因为它具有原始类型)并使用'outputItem.Properties ['key'] .value'来访问属性。 – Seth