我们如何在Powershell中模拟Active Directory用户?
时间:2020-03-05 18:39:47 来源:igfitidea点击:
我试图通过Web界面(ASP.NET/C#)运行powershell命令,以便在Exchange 2007上创建邮箱/等。当我使用Visual Studio(Cassini)运行页面时,页面正确加载。但是,当我在IIS(v5.1)上运行它时,出现错误"未知的用户名或者密码错误"。我注意到的最大问题是Powershell以ASPNET而不是Active Directory帐户的身份登录。如何强制我的Powershell会话通过另一个Active Directory帐户进行身份验证?
基本上,到目前为止,我拥有的脚本如下所示:
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;
解决方案
回答
在ASP.NET应用程序中,我们需要使用正确的权限模拟有效的AD帐户:
http://support.microsoft.com/kb/306158
回答
这是我用来模拟用户的类。
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 } }
回答
Exchange 2007出于安全原因不允许我们模拟用户。这意味着(目前)不可能通过模拟用户来创建邮箱。为了解决该问题,我创建了一个Web服务,该服务在具有创建电子邮件帐户等权限的AD用户下运行。然后,我们可以访问此Web服务以访问Powershell。请记住添加必要的安全性,因为这可能是一个巨大的安全漏洞。
回答
MSDN博客上的这篇文章似乎显示了一种实现方法,我还没有尝试过,但是当我这样做时会告诉我们。
http://blogs.msdn.com/webdav_101/archive/2008/09/25/howto-calling-exchange-powershell-from-an-impersonated-thead.aspx
回答
我们可能需要一个补丁。
来自:http://support.microsoft.com/kb/943937
An application cannot impersonate a user and then run Windows PowerShell commands in an Exchange Server 2007 environment To resolve this problem, install Update Rollup 1 for Exchange Server 2007 Service Pack 1.