How to start or stop IIS and also a Windows Service in remote machine using C# -
getting exception code... eventhough i've administrator privileges in remote machine
class program { static void main(string[] args) { var sc = new system.serviceprocess.servicecontroller("w3svc", "10.201.58.114"); sc.start(); sc.waitforstatus(system.serviceprocess.servicecontrollerstatus.running); sc.stop(); sc.waitforstatus(system.serviceprocess.servicecontrollerstatus.stopped); } }
exception:
an unhandled exception of type 'system.invalidoperationexception' occurred in system.serviceprocess.dll
additional information: cannot open service control manager on computer '10.201.58.114'. operation might require other privileges.
are machines in same domain? if not administrator
on machine1 not equivalent administrator
on machine2, problem.
one possibility need grant access user - on remote machine - stop , start service so:
subinacl /service \\<machine>\w3svc /grant=<machine>\<user>=to
there's example of in comments of second code block below (as needed in-code identity impersonation).
if doesn't solve problem, try impersonating remote user. managed working using following code.
first, create new class wrapperimpersonationcontext.cs:
using system; using system.runtime.interopservices; using system.security.principal; using system.security.permissions; using system.componentmodel; //version 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 { { 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; } }
then should able run following. note you'll need change machine-name, user-name , password match setup. pay attention comments there's important security settings information discovered along way:
//code program.cs demonstrating identity impersonation servicecontroller. using system; using system.security.principal; using system.serviceprocess; namespace remoteconnectiontest { class mainclass { public static void main (string[] args) { try { //based on code http://michiel.vanotegem.nl/2006/07/windowsimpersonationcontext-made-easy/ console.writeline("current user: " + windowsidentity.getcurrent().name); //also worked ip address of garnet (which 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 execute. //try running following command on remote server first ensure //the user has appropriate access (obviously substitute //username , machine name). // runas /user:testadmin "sc \\garnet stop w3svc" //also, make sure user on remote server has access //services granted described here: http://stackoverflow.com/a/5084563/201648 //otherwise may see error along lines of: //cannot open w3svc service on computer '<server>'. ---> system.componentmodel.win32exception: access denied //for configuration had run command: // subinacl /service \\garnet\w3svc /grant=garnet\testadmin=to //it's entirely possible running command allow existing code work without using impersonation. //you may need install subinacl https://www.microsoft.com/en-au/download/details.aspx?id=23510 //by default subinacl install c:\program files (x86)\windows resource kits\tools //so cd directory , run subinacl command above. //also worked ip address of garnet (which machine name). var sc = new servicecontroller("w3svc", "garnet"); sc.start(); sc.waitforstatus(servicecontrollerstatus.running); sc.stop(); sc.waitforstatus(servicecontrollerstatus.stopped); //end - code execute. context.leave(); console.writeline("your code ran successfully. current user: " + windowsidentity.getcurrent().name); } catch (exception ex) { console.writeline("an exception occured - details follows: {0}", ex.message); console.writeline("the full stack trace is: {0}", ex); } console.writeline ("press key exit..."); console.readline(); } } }
ensure remote machine can assessed using provided credentials before try in code e.g. connecting user through remote desktop.
Comments
Post a Comment