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

C# 通过WMI问题从ASP.NET重新启动应用程序池,c#,wmi,iis-6,restart,application-pool,C#,Wmi,Iis 6,Restart,Application Pool,我一直在尝试创建一个C#ASP.NET页面,它位于Windows Server 2003 IIS 6服务器上,当被远程调用时,会重新启动/回收服务器上的特定应用程序池 我运气不太好,有人知道我哪里出了问题吗?我尝试了许多组合,并尝试直接从服务器上运行,但没有效果 当我没有传递凭据时,我会得到错误 访问被拒绝 …当我通过它们时,我得到了错误 用户凭据不能用于本地连接 我也尝试过提升anon帐户的权限,只是为了测试,但还是不起作用。这可能是我想要实现的吗 试试看 { ManagementScope=

我一直在尝试创建一个C#ASP.NET页面,它位于Windows Server 2003 IIS 6服务器上,当被远程调用时,会重新启动/回收服务器上的特定应用程序池

我运气不太好,有人知道我哪里出了问题吗?我尝试了许多组合,并尝试直接从服务器上运行,但没有效果

当我没有传递凭据时,我会得到错误

访问被拒绝

…当我通过它们时,我得到了错误

用户凭据不能用于本地连接

我也尝试过提升anon帐户的权限,只是为了测试,但还是不起作用。这可能是我想要实现的吗

试试看
{
ManagementScope=新的ManagementScope(“根\\MicrosoftiSV2”);
scope.Path.Server=“servername”;
scope.Path.Path=“\\\\servername\\root\\MicrosoftIISv2”;
scope.Path.NamespacePath=“root\\MicrosoftIISv2”;
scope.Options.Username=“域\\user”;
scope.Options.Password=“Password”;
scope.Options.Authentication=AuthenticationLevel.Default;
scope.Options.Impersonation=ImpersonationLevel.Impersonate;
scope.Options.EnablePrivileges=true;
scope.Connect();
ManagementObject appPool=新的ManagementObject(范围,新的管理路径(“IIsApplicationPool.Name='W3SVC/AppPools/AppPoolName'),null);
InvokeMethod(“循环”,null,null);
}
catch(System.Exception-ex)
{
}

您不能对本地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);
    }                 
  }
}    

希望有帮助。

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

,使用,这是围绕的包装器。文件上说

连接到本地命名空间时,不要指定strUser、strPassword或strAuthority。有关详细信息,请参阅

如果你点击那个链接,你会发现上面写着

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


因此,根本没有办法通过WMI API做到这一点。我成功地解决了一个问题,那就是使用模仿,正如公认的答案一样。提供了一个很好的、健壮的例子。

忘了提到,我传递的域帐户确实具有执行应用程序池重启所需的权限(dom admin)