2011-09-02 67 views
2

我試圖從網站啓動遠程計算機上的進程。當用戶按下網站上的特定按鈕時,我需要在遠程計算機上啓動PowerShell。使用WMI和Win32_Process創建遠程進程

我使用System.Management從C#連接到遠程計算機並創建一個Win32_Process對象。當我在Visual Studio中使用我自己的域帳戶啓動網站並單擊按鈕時,它在兩臺虛擬機之間運行正常。我在兩個虛擬機的管理員組中,我可以看到這個腳本盡職地在遠程虛擬機上運行。

我已經將該網站部署到系統測試環境,並且該網站現在正在服務帳戶下運行,該服務帳戶不是Web服務器或我的測試PowerShell腳本所在的遠程框中的管理員。

我給運行與網站相關的應用程序池的帳戶上的遠程VM以下權限: - 在WMI上ROOT \ CIMV2完全權限,所有子命名空間 - 全DCOM權限

遠程虛擬機上沒有運行防火牆。

我基本上遵循下面的文章:

http://msdn.microsoft.com/en-us/library/aa393266.aspx

我也嘗試添加運行網站上的兩個VM管理員組的帳戶,但無濟於事。當這不起作用時,我不知道下一步該去哪裏!

有沒有人有這類問題的經驗?

非常感謝

克里斯

+0

真的想說「旋轉起來」吧? –

回答

3

嘗試使用模擬連接與管理priveleges遠程計算機。以下是我爲編程模擬創建的課程:

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  
} 
0

非常感謝代碼。現在我可能需要它來解決這個問題,我知道發生了什麼!

事實證明,問題在於Kerberos。我發現如果我在本地進入IIS管理器並「瀏覽」網頁,遠程WMI調用就可以工作。該網站設置爲模擬連接的用戶,如果我在本地連接,則將身份驗證令牌傳遞給遠程盒並且一切正常。

如果我從Web服務器外部進行連接,IIS提供給網站的令牌當前無法傳遞,因爲Web服務器未註冊到Kerberos。 (我傳遞了我最近在這裏所說的,爲了最終解決問題,我需要更好地理解這一點。)

我認爲這裏的解決方案不是傳遞連接的用戶令牌,而是而是以編程方式禁用WMI調用的模擬,並將其作爲運行應用程序池的帳戶執行。我確信我可以通過快速搜索找到如何做到這一點。

感謝您的幫助

+0

如果您覺得有幫助,您應該投票選出答案。 – havardhu

+0

看來你可能不得不[爲遠程監控啓用WMI](http://www.poweradmin.com/help/enableWMI。aspx)以及讓事情工作。啓用遠程監控和[保護遠程WMI連接](http://msdn.microsoft.com/en-us/library/aa393266.aspx)的組合似乎對我而言效果不錯。儘管如此,仍在研究安全性問題。 – jerhewet