C# 如何在Powershell中模拟Active Directory用户?
我正在尝试通过web界面(ASP.NET/C#)运行powershell命令,以便在Exchange 2007上创建邮箱/etc。当我使用VisualStudio(Cassini)运行页面时,页面会正确加载。但是,当我在IIS(v5.1)上运行它时,会出现错误“未知用户名或错误密码”。我注意到的最大问题是Powershell以ASPNET而不是我的Active Directory帐户登录。如何强制使用另一个Active Directory帐户验证我的Powershell会话 基本上,我到目前为止的脚本是这样的:C# 如何在Powershell中模拟Active Directory用户?,c#,asp.net,powershell,active-directory,C#,Asp.net,Powershell,Active Directory,我正在尝试通过web界面(ASP.NET/C#)运行powershell命令,以便在Exchange 2007上创建邮箱/etc。当我使用VisualStudio(Cassini)运行页面时,页面会正确加载。但是,当我在IIS(v5.1)上运行它时,会出现错误“未知用户名或错误密码”。我注意到的最大问题是Powershell以ASPNET而不是我的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;
RunspaceConfiguration rc=RunspaceConfiguration.Create();
PSSnapInException snapEx=null;
rc.AddPSSnapIn(“Microsoft.Exchange.Management.PowerShell.Admin”,out snapEx);
Runspace Runspace=RunspaceFactory.CreateRunspace(rc);
Open();
Pipeline Pipeline=runspace.CreatePipeline();
使用(管道)
{
pipeline.Commands.AddScript(“获取邮箱标识'user.name'”);
pipeline.Commands.Add(“输出字符串”);
收集结果=pipeline.Invoke();
if(pipeline.Error!=null&&pipeline.Error.Count>0)
{
foreach(管道中的对象项。错误。ReadToEnd())
resultString+=“错误:”+item.ToString()+“\n”;
}
runspace.Close();
foreach(结果中的PSObject对象)
resultString+=obj.ToString();
}
返回结果字符串;
在您的ASP.NET应用程序中,您需要模拟具有正确权限的有效广告帐户:
这里有一个我用来模拟用户的类
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:uwe.keim@zeta-software.de)
/// 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
}
}
使用系统;
使用系统数据;
使用系统配置;
使用System.Web;
使用System.Web.Security;
使用System.Web.UI;
使用System.Web.UI.WebControl;
使用System.Web.UI.WebControl.WebParts;
使用System.Web.UI.HTMLControl;
名称空间或工具
{
#区域使用指令。
使用System.Security.Principal;
使用System.Runtime.InteropServices;
使用系统组件模型;
#端区
///
///模拟用户。允许在另一个用户下执行代码
///用户上下文。
///请注意,实例化模拟程序类的帐户
///需要设置“作为操作系统的一部分”权限。
///
///
///本课程基于Microsoft知识库中的信息
///文章http://support.microsoft.com/default.aspx?scid=kb;美国;Q306158
///
///将实例封装到using指令中,例如:
///
/// ...
///使用(新的模拟程序(“myUsername”、“myDomainname”、“myPassword”))
/// {
/// ...
///[在新上下文下执行的代码]
/// ...
/// }
/// ...
///
///请联系作者Uwe Keim(mailto:Uwe。keim@zeta-软件(de)
///关于这门课的问题。
///
公共类模拟程序:
可识别
{
#区域公共方法。
///
///构造函数。使用给定的凭据启动模拟。
///请注意,实例化模拟程序类的帐户
///需要设置“作为操作系统的一部分”权限。
///
///要充当的用户的名称。
///要充当的用户的域名。
///要充当的用户的密码。
公众模仿者(
字符串用户名,
字符串域名,
字符串(密码)
{
ImpersonateValidUser(用户名、域名、密码);
}
// ------------------------------------------------------------------
#端区
#区域IDisposable成员。
公共空间处置()
{
取消模拟();
}
// ------------------------------------------------------------------
#端区
#区域P/调用。
[DllImport(“advapi32.dll”,SetLastError=true)]
私有静态外部int LogonUser(
字符串lpszUserName,
字符串lpszDomain,
字符串lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport(“advapi32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
私有静态外部重复标记(
IntPtr hToken,
int模拟级别,
参考IntPtr hNewToken);
[DllImport(“advapi32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
私有静态外部bool retertoself();
[DllImport(“kernel32.dll”,CharSet=CharSet.Auto)]
私有静态外部布尔闭合句柄(
IntPtr手柄);
private const int LOGON32\u LOGON\u INTERACTIVE=2;
private const int LOGON32_PROVIDER_DEFAULT=0;
// ------------------------------------------------------------------
#端区
#区域私人成员。
// ------------------------------------------------------------------
///
///进行实际模拟。
///
///要充当的用户的名称。
///要充当的用户的域名。
///要充当的用户的密码。
私有无效模拟ValidUser(
字符串用户名,
字符串域,
字符串(密码)
{
WindowsIdentity tempWindowsIdentity=null;
IntPtr令牌=IntPtr.Zero;
IntPtr-tokenDuplicate=IntPtr.Zero;
尝试
{
if(restortoself())
{
如果(登录用户)(
用户名,
领域,
密码,
LOGON32\u LOGON\u INTERACTIVE,
LOGON32\u提供程序\u默认值,
参考标记)!=0)
{
如果(重复)