2010-08-27 5 views
1

Dans Exchange 2007, cette ligne de code est utilisé pour charger les commandes Poweshell Echange snapin:Quelle est la commande pour accéder aux outils de gestion Exchange à partir du code C# dans Exchange 2010

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

Cependant, cela n'existe pas dans Exchange 2010 et je tire mes cheveux en essayant de trouver comment accéder aux commandes Exchange Powershell à partir du code C#. Microsoft.Exchange.Management.PowerShell.Admin n'existe nulle part sur le serveur Exchange et je ne trouve rien sur Google qui parle d'une ligne de code équivalente.

Comment puis-je accéder aux outils de gestion Exchange à partir du code C# dans Exchange 2010?

Ci-dessous est mon code complet pour référence, tout cela fonctionne jusqu'à ce que j'ajouter la ligne de code:

   //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"; 

Répondre

1

Je ne sais pas pour vous, mais Powershell Exchange 2010 peut être implémentée en tant que module 2.0 powershell , qui est chargé d'une manière différente. Pour le savoir, accédez à un système avec le shell de gestion des échanges et lancez-le. Ensuite, exécutez:

ps> get-module 

Ceci liste les modules v2 chargés. Je m'attendrais à ce que l'échange apparaisse si vous avez démarré le shell de gestion des échanges dédié. Si vous avez chargé la console powershell régulière, essayez:

ps> get-module -list 

Cela liste tous les modules disponibles pour charger. Si vous trouvez le bon, alors vous aurez besoin de construire votre code contre la v2 system.management.automation dll. Pour des raisons indépendantes de la portée de cette réponse, l'assembly v2 powershell a le même nom fort que celui de v1, donc vous ne pouvez pas facilement avoir les deux versions de powershell sur la même machine. Construire cette d'une machine avec v2 Powershell installé:

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*); 

Hope this helps,

-Oisin

1

Après beaucoup d'essais et d'erreurs, j'ai finalement compris cela. Le problème avec le code ci-dessus est qu'il fonctionne très bien lorsqu'il est exécuté sur Exchange 2007 mais que les choses ont changé dans Exchange 2010. Au lieu du snapin appelé "Microsoft.Exchange.Management.PowerShell.Admin", utilisez ce snapin, "Microsoft.Exchange.Management .PowerShell.E2010 ".

Le code complet pour exécuter une commande Powershell à partir de C# ressemble à ceci. J'espère que cela aidera quelqu'un d'autre à essayer de le faire.

Vous aurez également besoin de références à System.Management.Automation.Runspaces, System.Collections.ObjectModel et System.Management.Automation.

J'ai trouvé que la référence à System.Management.L'automatisation a dû être ajoutée manuellement dans le fichier csproj lui-même dans la section ItemGroup en utilisant le bloc-notes comme ceci:

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

ci-dessous:

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

rappeler que runspace et pipeline met en œuvre IDisposable et par conséquent doivent être éliminés après utilisation. –

0

C'est ce que je fais:

$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

EncryptionRequired  AutoDatabaseMountDial  DatabaseCopyAutoActivationPo 
                 licy 
------------------  ---------------------  ---------------------------- 
e       GoodAvailability    Unrestricted 
e       GoodAvailability    Unrestricted 

Maintenant, la conversion ci-dessus pour .net (C#) devrait être facile ...

essentiellement un Exerpt de: "C: \ Program Files \ Microsoft \ Exchange Server \ V14 \ Bin \ ConnectFunctions.ps1"

S'il vous plaît se référer à la fonction suivante:

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 
} 
Questions connexes