2008-08-15 1 views
11

Я пытаюсь запустить команды powershell через веб-интерфейс (ASP.NET/C#), чтобы создавать почтовые ящики/etc в Exchange 2007. Когда я запускаю страницу с помощью Visual Studio (Cassini), страница загружается правильно. Однако, когда я запускаю его в IIS (v5.1), я получаю сообщение об ошибке «неизвестное имя пользователя или неверный пароль». Самая большая проблема, которую я заметил, заключалась в том, что Powershell был зарегистрирован как ASPNET вместо моей учетной записи Active Directory. Как заставить мою сессию Powershell пройти проверку подлинности с другой учетной записью Active Directory?Как вы олицетворяете пользователя Active Directory в Powershell?

В принципе, сценарий, который я до сих пор выглядит примерно так:

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; 

ответ

1

Exchange 2007 не позволяет вам олицетворять пользователя по соображениям безопасности. Это означает, что невозможно (на данный момент) создавать почтовые ящики, олицетворяя пользователя. Чтобы обойти эту проблему, я создал веб-службу, которая работает под пользователем AD, которая имеет разрешения на создание учетных записей электронной почты и т. Д. Затем вы можете получить доступ к этому веб-сервису, чтобы получить доступ к powershell. Не забудьте добавить необходимую безопасность, потому что это потенциально может быть огромной дырой в безопасности.

2

В приложении ASP.NET, вам нужно будет выдавать себя за действительную учетную запись AD с правильными разрешениями:

http://support.microsoft.com/kb/306158

7

Вот класс, который я использую для олицетворения пользователя.

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

Вам может понадобиться патч.

От: http://support.microsoft.com/kb/943937

Приложение не может олицетворять пользователя, а затем запустить Windows PowerShell команды в Exchange Server 2007, среды

Чтобы решить эту проблему, установите Update Rollup 1 для Exchange Server 2007 с пакетом обновления 1.

Смежные вопросы