是在同一個域中的機器?如果不是機器1上的Administrator
與機器2上的Administrator
不等效,則可能是您的問題。
一種可能性是,你需要授予該用戶訪問 - 在遠程機器上 - 像這樣停止和啓動服務:
SUBINACL /SERVICE \\<MACHINE>\W3SVC /GRANT=<MACHINE>\<USER>=TO
有一個這樣的例子在第二個代碼的註釋在下面的塊(因爲我需要這個,即使是在代碼身份模仿)。
如果這樣不能解決問題,您可以嘗試模擬遠程用戶。我設法使用下面的代碼得到這個工作。
首先,創建一個新的類WrapperImpersonationContext.cs:
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.ComponentModel;
//Version from http://michiel.vanotegem.nl/2006/07/windowsimpersonationcontext-made-easy/
public class WrapperImpersonationContext
{
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain,
String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
private const int LOGON32_PROVIDER_DEFAULT = 0;
private const int LOGON32_LOGON_INTERACTIVE = 2;
private string m_Domain;
private string m_Password;
private string m_Username;
private IntPtr m_Token;
private WindowsImpersonationContext m_Context = null;
protected bool IsInContext
{
get { return m_Context != null; }
}
public WrapperImpersonationContext(string domain, string username, string password)
{
m_Domain = domain;
m_Username = username;
m_Password = password;
}
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Enter()
{
if (this.IsInContext) return;
m_Token = new IntPtr(0);
try
{
m_Token = IntPtr.Zero;
bool logonSuccessfull = LogonUser(
m_Username,
m_Domain,
m_Password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref m_Token);
if (logonSuccessfull == false)
{
int error = Marshal.GetLastWin32Error();
throw new Win32Exception(error);
}
WindowsIdentity identity = new WindowsIdentity(m_Token);
m_Context = identity.Impersonate();
}
catch (Exception exception)
{
// Catch exceptions here
}
}
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Leave()
{
if (this.IsInContext == false) return;
m_Context.Undo();
if (m_Token != IntPtr.Zero) CloseHandle(m_Token);
m_Context = null;
}
}
那麼你應該能夠運行以下。請注意,您需要更改計算機名稱,用戶名和密碼以符合您的設置。另外要注意的批示有重要的安全設置的信息,我一路上發現:
//Code for Program.cs demonstrating the identity impersonation for a ServiceController.
using System;
using System.Security.Principal;
using System.ServiceProcess;
namespace RemoteConnectionTest
{
class MainClass
{
public static void Main (string[] args)
{
try {
//Based on the code from http://michiel.vanotegem.nl/2006/07/windowsimpersonationcontext-made-easy/
Console.WriteLine("Current user: " + WindowsIdentity.GetCurrent().Name);
//Also worked with the IP address of GARNET (which was the machine name).
WrapperImpersonationContext context = new WrapperImpersonationContext("GARNET", "TestAdmin1", "password123");
context.Enter();
// Execute code under other uses context
Console.WriteLine("Current user: " + WindowsIdentity.GetCurrent().Name);
// Code to execute.
//Try running the following command on the remote server first to ensure
//the user has the appropriate access (obviously substitute the
//username and machine name).
// runas /user:TestAdmin "sc \\GARNET stop W3SVC"
//Also, make sure the user on the remote server has access for
//services granted as described here: http://stackoverflow.com/a/5084563/201648
//Otherwise you may see an error along the lines of:
//Cannot open W3SVC service on computer '<SERVER>'. ---> System.ComponentModel.Win32Exception: Access is denied
//For my configuration I had to run the command:
// SUBINACL /SERVICE \\GARNET\W3SVC /GRANT=GARNET\TestAdmin=TO
//It's entirely possible that running this command will allow your existing code to work without using impersonation.
//You may need to install SUBINACL https://www.microsoft.com/en-au/download/details.aspx?id=23510
//By default SUBINACL will install to C:\Program Files (x86)\Windows Resource Kits\Tools
//so CD to that directory and then run the SUBINACL command above.
//Also worked with the IP address of GARNET (which was the machine name).
var sc = new ServiceController("W3SVC", "GARNET");
sc.Start();
sc.WaitForStatus(ServiceControllerStatus.Running);
sc.Stop();
sc.WaitForStatus(ServiceControllerStatus.Stopped);
//END - code to execute.
context.Leave();
Console.WriteLine("Your code ran successfully. Current user: " + WindowsIdentity.GetCurrent().Name);
} catch (Exception ex) {
Console.WriteLine("An exception occured - details as follows: {0}", ex.Message);
Console.WriteLine("The full stack trace is: {0}", ex);
}
Console.WriteLine ("Press any key to exit...");
Console.ReadLine();
}
}
}
確保遠程機器可以使用評估提供的憑據嘗試做到這一點的代碼如前通過遠程桌面連接成這個用戶。
目標系統是否沒有安全軟件?你會發現一些安全軟件可以產生這種效果。 – Xefan
它會幫助運行應用程序「作爲管理員」?還假設你有權提供IP ... – vidriduch
使用以管理員身份使用命令提示符:'C:\> iisreset。exe <遠程計算機的IP地址>,錯誤信息爲:'訪問被拒絕,您必須是遠程計算機的管理員才能使用此命令。您的帳戶可以添加到管理員本地組 遠程計算機或域管理員全局組。「請注意,我擁有遠程計算機的管理員權限,但仍然出現錯誤。 – venkat