通过WMI问题从ASP.NET重新启动应用程序池

时间:2011-08-26 11:40:49

标签: asp.net wmi restart pool

我一直在尝试创建一个位于win2k3 IIS 6服务器上的c#asp.net页面,当被调用(远程)时,重新启动/回收服务器上的特定应用程序池。

我一直没看多少,有谁知道我哪里出错了?我尝试了很多组合,尝试直接从服务器运行,但没有用。

当我没有通过凭据时,我一直收到“访问被拒绝”或“win32:访问被拒绝错误”。当我通过它们时,我得到“用户凭据不能用于本地连接”。

我也试过用anon帐户提升权限只是为了测试但是再次它不会工作......这可能是我想要实现的吗?

        try
        {

        ManagementScope scope = new ManagementScope("root\\MicrosoftIISv2");
        scope.Path.Server = "servername";
        scope.Path.Path = "\\\\servername\\root\\MicrosoftIISv2";
        scope.Path.NamespacePath = "root\\MicrosoftIISv2";
        scope.Options.Username = "domain\\user";
        scope.Options.Password = "password";
        scope.Options.Authentication = AuthenticationLevel.Default;
        scope.Options.Impersonation = ImpersonationLevel.Impersonate;
        scope.Options.EnablePrivileges = true;
        scope.Connect();

        ManagementObject appPool = new ManagementObject(scope, new ManagementPath("IIsApplicationPool.Name='W3SVC/AppPools/AppPoolName'"), null);
        appPool.InvokeMethod("Recycle", null, null);

        }
        catch (System.Exception ex)
        {
        }

2 个答案:

答案 0 :(得分:2)

您无法使用用户名/密码选项进行本地WMI连接。默认情况下,对于本地WMI连接,将使用登录用户的凭据(在您的情况下,使用您网站的应用程序池的标识)。我认为您有两种选择使用您网站上的WMI:

  • 第一个选项:为应用程序池的身份授予足够的权限以使用WMI(回收应用程序池)。

  • 第二个选项:使用模拟。

以下是一个例子:

public class _Default : Page
{
  [DllImport("advapi32.dll", SetLastError = true)]
  static extern bool LogonUser(string principal, string authority,string password, uint logonType, uint logonProvider, out IntPtr token);

  [DllImport("kernel32.dll", SetLastError = true)]
  static extern bool CloseHandle(IntPtr handle); 

  protected void OnClick(object sender, EventArgs e)
  {
    IntPtr token = IntPtr.Zero;
    WindowsImpersonationContext impUser = null;

    try
    {        
      bool result = LogonUser("administrator", "contoso",
                            "P@$$W0rd", 3, 0, out token);
      if (result)
      {
        WindowsIdentity wid = new WindowsIdentity(token);
        impUser = wid.Impersonate();

        try
        {
          ManagementScope scope = new ManagementScope("root\\MicrosoftIISv2");
          scope.Path.Server = "srvcontoso";
          scope.Path.Path = "\\\\srvcontoso\\root\\MicrosoftIISv2";
          scope.Path.NamespacePath = "root\\MicrosoftIISv2";

          scope.Connect();

          ManagementObject appPool = new ManagementObject(scope, new ManagementPath("IIsApplicationPool.Name='W3SVC/AppPools/DefaultAppPool'"), null);
          appPool.InvokeMethod("Recycle", null, null);
         }
         catch (System.Exception ex)
         {
         } 
       }
    }
    catch
    {        
    }
    finally
    {         
      if (impUser  != null)
        impUser .Undo();

      if (token != IntPtr.Zero)
        CloseHandle(token);
    }                 
  }
}    

希望,这有帮助。

答案 1 :(得分:0)

连接到本地WMI服务时,无法指定备用凭据。

InternallyManagementScope.Connect() method使用ConnectServerWmi function,它是IWbemLocator::ConnectServer method的包装。该文档指出...

在与本地名称空间建立连接时,请不要指定 strUser strPassword strAuthority 。有关更多信息,请参见Connecting to WMI on a Remote Computer

如果您点击该链接,您会发现它说...

如果您尝试访问其他帐户,则需要提供其他凭据。 (请注意,不允许尝试使用与当前帐户不同的凭据在本地访问WMI。)

因此,根本没有办法通过WMI API来执行此操作。我成功的解决方法是使用模拟,如公认的答案所示。 documentation for the WindowsIdentity.Impersonate() method提供了一个很好的示例。