我一直试图在Windows Server 2003 IIS 6服务器上创建一个C#ASP.NET页面,并在(远程)调用时重新启动/回收服务器上的特定应用程序池。
我运气不太好,有人知道我要去哪里错吗?我尝试了许多组合,并尝试直接从服务器运行,但无济于事。
[当我不通过凭据时,我得到了错误...
拒绝访问
...并且当我通过它们时,我得到了错误...
用户凭据不能用于本地连接
我还尝试使用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)
{
}
您不能将用户名/密码选项用于本地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服务时无法指定备用凭据。
Internally,ManagementScope.Connect()
method使用ManagementScope.Connect()
,它是ConnectServerWmi
function的包装。该文档指出...
与本地名称空间建立连接时,不要指定strUser,strPassword或strAuthority。有关更多信息,请参见
ConnectServerWmi
。
如果您点击该链接,您会发现它说...
如果您尝试访问其他帐户,则需要提供其他凭据。 (请注意,不允许尝试使用不同于当前帐户的凭据在本地访问WMI。)
因此,根本没有办法通过WMI API来执行此操作。我成功的一种解决方法是使用模拟,如公认的答案所示。 IWbemLocator::ConnectServer
method提供了一个很好的示例。