2008-08-15 5 views
11

J'essaie d'exécuter des commandes powershell via une interface Web (ASP.NET/C#) afin de créer des boîtes aux lettres/etc sur Exchange 2007. Lorsque je lance la page en utilisant Visual Studio (Cassini), la page se charge correctement. Toutefois, lorsque je l'exécute sur IIS (v5.1), j'obtiens l'erreur "nom d'utilisateur inconnu ou mot de passe incorrect". Le plus gros problème que j'ai remarqué était que Powershell était connecté en ASPNET au lieu de mon compte Active Directory. Comment forcer ma session Powershell à être authentifiée avec un autre compte Active Directory?Comment emprunter l'identité d'un utilisateur Active Directory dans Powershell?

Fondamentalement, le script que j'ai tellement ressemble beaucoup quelque chose comme ceci:

RunspaceConfiguration rc = RunspaceConfiguration.Create(); 
PSSnapInException snapEx = null; 
rc.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", out snapEx); 

Runspace runspace = RunspaceFactory.CreateRunspace(rc); 
runspace.Open(); 

Pipeline pipeline = runspace.CreatePipeline(); 
using (pipeline) 
{ 
    pipeline.Commands.AddScript("Get-Mailbox -identity 'user.name'"); 
    pipeline.Commands.Add("Out-String"); 

    Collection<PSObject> results = pipeline.Invoke(); 

    if (pipeline.Error != null && pipeline.Error.Count > 0) 
    { 
     foreach (object item in pipeline.Error.ReadToEnd()) 
      resultString += "Error: " + item.ToString() + "\n"; 
    } 

    runspace.Close(); 

    foreach (PSObject obj in results) 
     resultString += obj.ToString(); 
} 

return resultString; 

Répondre

1

Exchange 2007 ne vous permet pas d'usurper l'identité d'un utilisateur pour des raisons de sécurité. Cela signifie qu'il est impossible (pour le moment) de créer des boîtes aux lettres en usurpant l'identité d'un utilisateur. Afin de contourner ce problème, j'ai créé un service Web qui fonctionne sous un utilisateur AD qui a des autorisations pour créer des comptes email, etc. Vous pouvez alors accéder à ce service web pour avoir accès à PowerShell. S'il vous plaît n'oubliez pas d'ajouter la sécurité nécessaire, car cela pourrait potentiellement être un trou de sécurité énorme.

7

Voici une classe que j'utilise pour usurper l'identité d'un utilisateur.

using System; 
using System.Data; 
using System.Configuration; 
using System.Web; 
using System.Web.Security; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.HtmlControls; 

namespace orr.Tools 
{ 

    #region Using directives. 
    using System.Security.Principal; 
    using System.Runtime.InteropServices; 
    using System.ComponentModel; 
    #endregion 

    /// <summary> 
    /// Impersonation of a user. Allows to execute code under another 
    /// user context. 
    /// Please note that the account that instantiates the Impersonator class 
    /// needs to have the 'Act as part of operating system' privilege set. 
    /// </summary> 
    /// <remarks> 
    /// This class is based on the information in the Microsoft knowledge base 
    /// article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158 
    /// 
    /// Encapsulate an instance into a using-directive like e.g.: 
    /// 
    ///  ... 
    ///  using (new Impersonator("myUsername", "myDomainname", "myPassword")) 
    ///  { 
    ///   ... 
    ///   [code that executes under the new context] 
    ///   ... 
    ///  } 
    ///  ... 
    /// 
    /// Please contact the author Uwe Keim (mailto:[email protected]) 
    /// for questions regarding this class. 
    /// </remarks> 
    public class Impersonator : 
     IDisposable 
    { 
     #region Public methods. 
     /// <summary> 
     /// Constructor. Starts the impersonation with the given credentials. 
     /// Please note that the account that instantiates the Impersonator class 
     /// needs to have the 'Act as part of operating system' privilege set. 
     /// </summary> 
     /// <param name="userName">The name of the user to act as.</param> 
     /// <param name="domainName">The domain name of the user to act as.</param> 
     /// <param name="password">The password of the user to act as.</param> 
     public Impersonator(
      string userName, 
      string domainName, 
      string password) 
     { 
      ImpersonateValidUser(userName, domainName, password); 
     } 

     // ------------------------------------------------------------------ 
     #endregion 

     #region IDisposable member. 

     public void Dispose() 
     { 
      UndoImpersonation(); 
     } 

     // ------------------------------------------------------------------ 
     #endregion 

     #region P/Invoke. 

     [DllImport("advapi32.dll", SetLastError = true)] 
     private static extern int LogonUser(
      string lpszUserName, 
      string lpszDomain, 
      string lpszPassword, 
      int dwLogonType, 
      int dwLogonProvider, 
      ref IntPtr phToken); 

     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern int DuplicateToken(
      IntPtr hToken, 
      int impersonationLevel, 
      ref IntPtr hNewToken); 

     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern bool RevertToSelf(); 

     [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
     private static extern bool CloseHandle(
      IntPtr handle); 

     private const int LOGON32_LOGON_INTERACTIVE = 2; 
     private const int LOGON32_PROVIDER_DEFAULT = 0; 

     // ------------------------------------------------------------------ 
     #endregion 

     #region Private member. 
     // ------------------------------------------------------------------ 

     /// <summary> 
     /// Does the actual impersonation. 
     /// </summary> 
     /// <param name="userName">The name of the user to act as.</param> 
     /// <param name="domainName">The domain name of the user to act as.</param> 
     /// <param name="password">The password of the user to act as.</param> 
     private void ImpersonateValidUser(
      string userName, 
      string domain, 
      string password) 
     { 
      WindowsIdentity tempWindowsIdentity = null; 
      IntPtr token = IntPtr.Zero; 
      IntPtr tokenDuplicate = IntPtr.Zero; 

      try 
      { 
       if (RevertToSelf()) 
       { 
        if (LogonUser(
         userName, 
         domain, 
         password, 
         LOGON32_LOGON_INTERACTIVE, 
         LOGON32_PROVIDER_DEFAULT, 
         ref token) != 0) 
        { 
         if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) 
         { 
          tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); 
          impersonationContext = tempWindowsIdentity.Impersonate(); 
         } 
         else 
         { 
          throw new Win32Exception(Marshal.GetLastWin32Error()); 
         } 
        } 
        else 
        { 
         throw new Win32Exception(Marshal.GetLastWin32Error()); 
        } 
       } 
       else 
       { 
        throw new Win32Exception(Marshal.GetLastWin32Error()); 
       } 
      } 
      finally 
      { 
       if (token != IntPtr.Zero) 
       { 
        CloseHandle(token); 
       } 
       if (tokenDuplicate != IntPtr.Zero) 
       { 
        CloseHandle(tokenDuplicate); 
       } 
      } 
     } 

     /// <summary> 
     /// Reverts the impersonation. 
     /// </summary> 
     private void UndoImpersonation() 
     { 
      if (impersonationContext != null) 
      { 
       impersonationContext.Undo(); 
      } 
     } 

     private WindowsImpersonationContext impersonationContext = null; 

     // ------------------------------------------------------------------ 
     #endregion 
    } 
} 
1

Vous pourriez avoir besoin d'un patch.

De: http://support.microsoft.com/kb/943937

Une application ne peut pas usurper l'identité d'un utilisateur et exécuter Windows PowerShell commandes dans un serveur Exchange 2007 environnement

Pour résoudre ce problème, installez Update Rollup 1 pour Exchange Server 2007 Service Pack 1.

Questions connexes