2017-04-25 85 views
0

由於各種原因,我需要使用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 
      } 
     } 
    } 
} 

回答

0

這正是問題:反序列化破壞了原有的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

相關問題