2010-08-27 26 views
1

在Exchange 2007中的命令命令管理單元:什麼是這行代碼是用來加載Exchange Poweshell從C#代碼中訪問Exchange管理工具在Exchange 2010中

PSSnapInInfo info = rsConfig.AddPSSnapIn(
    "Microsoft.Exchange.Management.PowerShell.Admin", 
    out snapInException); 

然而,這並不在Exchange存在2010年,我正試圖找出如何從C#代碼訪問Exchange Powershell命令。 Microsoft.Exchange.Management.PowerShell.Admin在Exchange Server的任何位置都不存在,我無法在Google上找到有關等效代碼行的任何內容。

如何從Exchange 2010中的C#代碼訪問Exchange管理工具?

下面是我參考完整的代碼,所有的工作,直到我添加的代碼行:

   //Creating and Opening a Runspace 
      RunspaceConfiguration rsConfig = RunspaceConfiguration.Create(); 
      PSSnapInException snapInException = null; 
      PSSnapInInfo info = rsConfig.AddPSSnapIn(
       "Microsoft.Exchange.Management.PowerShell.Admin", 
       out snapInException); 
      Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig); 
      myRunSpace.Open(); 

      //How Do I Run a Cmdlet? 
      //create a new instance of the Pipeline class 
      Pipeline pipeLine = myRunSpace.CreatePipeline(); 

      //create an instance of the Command class 
      // by using the name of the cmdlet that you want to run 
      Command myCommand = new Command(txtCommand.Text); 

      //add the command to the Commands collection of the pipeline 
      pipeLine.Commands.Add(myCommand); 

      Collection<PSObject> commandResults = pipeLine.Invoke(); 

      // iterate through the commandResults collection 
      // and get the name of each cmdlet 
      txtResult.Text = "start ...."; 
      foreach (PSObject cmdlet in commandResults) 
      { 
       string cmdletName = cmdlet.Properties["Name"].Value.ToString(); 
       System.Diagnostics.Debug.Print(cmdletName); 
       txtResult.Text += "cmdletName: " + cmdletName; 
      } 
      txtResult.Text += ".... end"; 

回答

1

我不知道肯定,但Exchange 2010中的PowerShell可以實現爲一個PowerShell 2.0模塊,它以不同的方式加載。爲了找到答案,去一個帶有Exchange管理外殼的系統,然後啓動它。接下來,運行:

ps> get-module 

這將列出加載的v2模塊。如果你已經啓動了專用的Exchange管理外殼,我希望交易所會出現。如果您加載了常規的powershell控制檯,請嘗試:

ps> get-module -list 

這將列出所有可加載的模塊。如果您發現了正確的,那麼您需要針對v2 system.management.automation dll構建您的代碼。由於本答覆範圍以外的原因,v2 powershell的程序集與v1的名稱相同,因此不能輕易在同一臺機器上同時安裝兩個版本的powershell。從V2 PowerShell中安裝一臺機器建立這樣的:

InitialSessionState initial = InitialSessionState.CreateDefault(); 
initialSession.ImportPSModule(new[] { *modulePathOrModuleName* }); 
Runspace runspace = RunspaceFactory.CreateRunspace(initial); 
runspace.Open(); 
RunspaceInvoke invoker = new RunspaceInvoke(runspace); 
Collection<PSObject> results = invoker.Invoke(*myScript*); 

希望這有助於

-Oisin

1

大量的試驗和錯誤之後,我終於想通了這一點。上面的代碼的問題是,在針對Exchange 2007運行時效果很好,但Exchange 2010中的內容已更改。替代名爲「Microsoft.Exchange.Management.PowerShell.Admin」的管理單元,請使用此管理單元「Microsoft.Exchange.Management .PowerShell.E2010" 。

從C#運行Powershell命令的完整代碼如下所示。希望這可以幫助別人試圖做到這一點。

您還需要對System.Management.Automation.Runspaces,System.Collections.ObjectModel和System.Management.Automation的引用。

我發現對System.Management的引用。自動化不得不使用記事本這樣可以手動添加到的csproj文件本身中的ItemGroup節:下面

<Reference Include="System.Management.Automation" /> 

代碼:

private class z_test 
{ 
    //set up 
    private RunspaceConfiguration rsConfig = RunspaceConfiguration.Create(); 
    private PSSnapInException snapInException = null; 
    private Runspace runSpace; 

    private void RunPowerShell() 
    { 
     //create the runspace 
     runSpace = RunspaceFactory.CreateRunspace(rsConfig); 
     runSpace.Open(); 
     rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out snapInException); 

     //set up the pipeline to run the powershell command 
     Pipeline pipeLine = runSpace.CreatePipeline(); 

     //create the script to run 
     String sScript = "get-mailbox -identity 'rj'"; 

     //invoke the command 
     pipeLine.Commands.AddScript(sScript); 

     Collection<PSObject> commandResults = pipeLine.Invoke(); 

     //loop through the results of the command and load the SamAccountName into the list 
     foreach (PSObject results in commandResults) 
     { 
      Console.WriteLine(results.Properties["SamAccountName"].Value.ToString()); 
     } 

     pipeLine.Dispose(); 

     runSpace.Close(); 
    } 
} 
+0

請記住Runspace和Pipeline實現了IDisposable,因此應該在使用後丟棄。 – 2010-12-03 09:55:26

0

這是我在做什麼:

$sessionOptionsTimeout=180000 

$sessionOptionsTimeout=180000 

$so = New-PSSessionOption -OperationTimeout $sessionOptionsTimeout -IdleTimeout $sessionOptionsTimeout -OpenTimeout $sessionOptionsTimeout 

$connectionUri="http://$fqdn/powershell?serializationLevel=Full;ExchClientVer=14.3.91.1" 


$s = New-PSSession -ConnectionURI "$connectionUri" -ConfigurationName Microsoft.Exchange -SessionOption $so 

$s | Enter-PSSession 

PS> get-mailboxserver

​​

現在,上述轉換到.NET(C#)應該很容易......

本質的exerpt從: 「C:\ Program Files文件\微軟\ Exchange服務器\ V14 \ BIN \ ConnectFunctions.ps1」

請參閱以下功能:

function _NewExchangeRunspace([String]$fqdn, 
       [System.Management.Automation.PSCredential] 
$credential=$null, 

       [bool]$UseWIA=$true, 

       [bool]$SuppressError=$false, 

       $ClientApplication=$null, 

       $AllowRedirection=$false) 

{ 
    $hostFQDN = _GetHostFqdn 

    if (($fqdn -ne $null) -and ($hostFQDN -ne $null) -and ($hostFQDN.ToLower() -eq $fqdn.ToLower())) 

    { 
     $ServicesRunning = _CheckServicesStarted 

     if ($ServicesRunning -eq $false) 
     { 
      return 
     } 
    } 

    Write-Verbose ($ConnectFunctions_LocalizedStrings.res_0005 -f $fqdn) 

    $so = New-PSSessionOption -OperationTimeout $sessionOptionsTimeout -IdleTimeout $sessionOptionsTimeout -OpenTimeout $sessionOptionsTimeout; 
    $setupRegistryEntry = get-itemproperty HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\Setup -erroraction:silentlycontinue 
    if ($setupRegistryEntry -ne $null) 
    { 
     $clientVersion = "{0}.{1}.{2}.{3}" -f $setupRegistryEntry.MsiProductMajor, $setupRegistryEntry.MsiProductMinor, $setupRegistryEntry.MsiBuildMajor, $setupRegistryEntry.MsiBuildMinor 
     $connectionUri = "http://$fqdn/powershell?serializationLevel=Full;ExchClientVer=$clientVersion" 
    } 
    else 
    { 
     $connectionUri = "http://$fqdn/powershell?serializationLevel=Full" 
    } 

    if ($ClientApplication -ne $null) 
    { 
     $connectionUri = $connectionUri + ";clientApplication=$ClientApplication" 
    } 

    write-host -fore Yellow ("connectionUri: " + $connectionUri) 

    $contents = 'New-PSSession -ConnectionURI "$connectionUri" -ConfigurationName Microsoft.Exchange -SessionOption $so' 

    if (-not $UseWIA) 
    { 
     $contents = $contents + ' -Authentication Kerberos -Credential $credential' 
    } 
    if ($SuppressError) 
    { 
     $contents = $contents + ' -erroraction silentlycontinue' 
    } 
    if ($AllowRedirection) 
    { 
     $contents = $contents + ' -AllowRedirection' 
    } 

    write-host -fore Yellow ("contents: " + $contents) 
    write-host -fore Yellow ("join n contents: " + [string]::join("`n", $contents)) 


    [ScriptBlock] $command = $executioncontext.InvokeCommand.NewScriptBlock([string]::join("`n", $contents)) 
    $session=invoke-command -Scriptblock $command 

    if (!$?) 
    { 
     # ERROR_ACCESS_DENIED = 5 
     # ERROR_LOGON_FAILURE = 1326 
     if (!(5 -eq $error[0].exception.errorcode) -and 
      !(1326 -eq $error[0].exception.errorcode)) 
     { 
      #Write-Verbose ($ConnectFunctions_LocalizedStrings.res_0006 -f $fqdn) 
      return 
     } 
     else 
     { 
     # no retries if we get 5 (access denied) or 1326 (logon failure) 
     #$REVIEW$ connectedFqdn is not set. Is it okay? 
     break connectScope 
     } 
    } 
    $session 
} 
相關問題