我正在尝试从网站上启动远程计算机上的进程。当用户按下网站上的特定按钮时,我需要在远程计算机上启动PowerShell。
我正在使用C#中的System.Management连接到远程计算机并创建一个Win32_Process对象。当我在Visual Studio中使用我自己的域帐户启动网站并单击按钮时,两个虚拟机之间的工作正常。我在两个虚拟机的管理员组中,我可以看到脚本在远程虚拟机上尽职尽责地运行。
我已将网站部署到系统测试环境,该网站现在在一个服务帐户下运行,该帐户不是我的测试PowerShell脚本所在的Web服务器或远程控制台上的管理员。
我已经为运行与网站关联的应用池的帐户提供了远程VM上的以下权限: - WMI和所有子命名空间中ROOT \ CIMV2的完全权限 - 完整的DCOM权限
远程VM上没有运行防火墙。
我基本上遵循了以下文章:
http://msdn.microsoft.com/en-us/library/aa393266.aspx
我也尝试将运行网站的帐户添加到两个虚拟机上的管理员组,但无济于事。当这不起作用时,我不知道下一步该去哪里!
有没有人有这种问题的经历?
非常感谢
克里斯
答案 0 :(得分:3)
尝试使用模拟以管理员权限连接到远程计算机。这是我为程序化模拟创建的类:
using System;
using System.Security.Principal;
using System.Diagnostics;
using System.Runtime.InteropServices;
/// <summary>
/// Leverages the Windows API (advapi32.dll) to programmatically impersonate a user.
/// </summary>
public class ImpersonationContext : IDisposable
{
#region constants
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
#endregion
#region global variables
private WindowsImpersonationContext impersonationContext;
private bool impersonating;
#endregion
#region unmanaged code
[DllImport("advapi32.dll")]
private static extern int LogonUserA(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);
#endregion
#region constructors
public ImpersonationContext()
{
impersonating = false;
}
/// <summary>
/// Overloaded constructor and begins impersonating.
/// </summary>
public ImpersonationContext(string userName, string password, string domain)
{
this.BeginImpersonationContext(userName, password, domain);
}
#endregion
#region impersonation methods
/// <summary>
/// Begins the impersonation context for the specified user.
/// </summary>
/// <remarks>Don't call this method if you used the overloaded constructor.</remarks>
public void BeginImpersonationContext(string userName, string password, string domain)
{
//initialize token and duplicate variables
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
using (WindowsIdentity tempWindowsIdentity = new WindowsIdentity(tokenDuplicate))
{
//begin the impersonation context and mark impersonating true
impersonationContext = tempWindowsIdentity.Impersonate();
impersonating = true;
}
}
}
}
//close the handle to the account token
if (token != IntPtr.Zero)
CloseHandle(token);
//close the handle to the duplicated account token
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
}
/// <summary>
/// Ends the current impersonation context.
/// </summary>
public void EndImpersonationContext()
{
//if the context exists undo it and dispose of the object
if (impersonationContext != null)
{
//end the impersonation context and dispose of the object
impersonationContext.Undo();
impersonationContext.Dispose();
}
//mark the impersonation flag false
impersonating = false;
}
#endregion
#region properties
/// <summary>
/// Gets a value indicating whether the impersonation is currently active.
/// </summary>
public bool Impersonating
{
get
{
return impersonating;
}
}
#endregion
#region IDisposable implementation
~ImpersonationContext()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (impersonationContext != null)
{
impersonationContext.Undo();
impersonationContext.Dispose();
}
}
}
#endregion
}
答案 1 :(得分:0)
非常感谢代码。现在我知道发生了什么事,我可能需要它来解决问题!
事实证明问题与Kerberos有关。我发现如果我在本地进入IIS管理器并“浏览”该网页,则远程WMI调用工作正常。该网站设置为模拟连接的用户,如果我在本地连接,则身份验证令牌将传递到远程控制台,一切正常。
如果我从Web服务器外部连接,则当前无法传递由IIS提供给网站的令牌,因为Web服务器未向Kerberos注册。 (我正在传递我最近在这里所说的内容。我需要更好地理解这一点,以便最终解决问题。)
我认为这里的解决方案不是传递连接用户的令牌,而是以编程方式为WMI调用禁用模拟,并将其作为运行应用程序池的帐户执行。我相信我可以通过快速搜索了解如何做到这一点。
感谢您的帮助