Cum impersonați un utilizator Active Directory în Powershell?

Încerc să rulez comenzi powerhell printr-o interfață web (ASP.NET/C#) pentru a crea cutiile poștale/etc pe Exchange 2007. Când rulez pagina utilizând Visual Studio (Cassini), pagina se încarcă corect. Cu toate acestea, când îl rulez pe IIS (v5.1), obțin eroarea "nume de utilizator necunoscut sau parolă defectă". Cea mai mare problemă pe care am observat-o a fost că Powershell a fost conectat ca ASPNET în loc de Contul meu Active Directory. Cum pot forța sesiunea mea Powershell să fie autentificată cu un alt cont Active Directory?

Practic, scenariul pe care îl am până acum arată cam așa:

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 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;
0
fr hi bn

4 răspunsuri

Iată o clasă pe care o folosesc pentru a impersona un utilizator.

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

    /// 
    /// 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.
    /// 
    ///    
    /// 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.
    /// 
    public class Impersonator :
        IDisposable
    {
        #region Public methods.
        /// 
        /// 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.
        /// 
        /// The name of the user to act as.
        /// The domain name of the user to act as.
        /// The password of the user to act as.
        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.
       //------------------------------------------------------------------

        /// 
        /// Does the actual impersonation.
        /// 
        /// The name of the user to act as.
        /// The domain name of the user to act as.
        /// The password of the user to act as.
        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);
                }
            }
        }

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

        private WindowsImpersonationContext impersonationContext = null;

       //------------------------------------------------------------------
        #endregion
    }
}
0
adăugat

Exchange 2007 nu vă permite să vă impersonați un utilizator din motive de securitate. Aceasta înseamnă că este imposibil (în prezent) să creați cutii poștale prin impersonarea unui utilizator. Pentru a rezolva această problemă, am creat un serviciu web care rulează sub un utilizator AD care are permisiuni de a crea conturi de e-mail etc. Puteți apoi accesa această pagină Web pentru a avea acces la PowerShell. Nu uitați să adăugați securitatea necesară deoarece aceasta ar putea fi o gaură de securitate imensă.

0
adăugat

În aplicația dvs. ASP.NET, va trebui să vă impersonați un cont AD valid cu permisiunile corecte:

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

0
adăugat

Acest articol pe blogurile MSDN pare să arate o modalitate de a face acest lucru, nu am reușit încă să încerc, dar vă va spune când o fac.

http://blogs.msdn.com/webdav_101/archive/2008/09/25/howto-calling-exchange-powershell-from-an-impersonated-thead.aspx

0
adăugat