2016-01-21 3 views
6

Erste Exception mit ... obwohl ich Administratorrechte in der entfernten MaschineSo startet oder IIS zu stoppen und auch einen Windows-Dienst in Remote-Rechner mit diesem Code C#

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); 
     } 
    } 

Ausnahme habe:

Eine nicht behandelte Ausnahme des Typs 'System.InvalidOperationException' aufgetreten in System.ServiceProcess.dll

Zusätzliche Informationen: Kann nicht öffnen Service C ontrol Manager auf dem Computer '10 .201.58.114 '. Diese Operation erfordert möglicherweise andere Berechtigungen.

+0

Ist das Zielsystem frei von Sicherheitssoftware? Sie werden feststellen, dass einige Sicherheitsprogramme diesen Effekt haben können. – Xefan

+1

würde es helfen, App "Als Administrator" zu laufen? vorausgesetzt, Sie haben Rechte an der IP-Adresse ... – vidriduch

+0

Mit der Eingabeaufforderung als Administrator: 'C: \> iisreset.exe ', Fehler wie folgt:' Zugriff verweigert, Sie müssen Administrator des Remote-Computers sein, um diesen Befehl zu verwenden. Entweder wurde Ihr Konto der lokalen Administratorgruppe des Remotecomputers oder der globalen Gruppe des Domänenadministrators hinzugefügt. Bitte beachten Sie, dass ich über Administratorrechte auf dem Remotecomputer verfüge, aber weiterhin Fehler erhalte. – venkat

Antwort

0

Klingt wie Sie den localgroup Administratoren nicht hinzugefügt werden

Aktivieren Sie diese mit

net localgroup Administratoren

auf dem entfernten Rechner

, ob der Benutzer nicht in der Liste, führen Sie

net localgroup Administratoren/Benutzer hinzufügen

+0

Mein Name ist bereits in Lokale Gruppe von Administratoren aufgeführt. Aber immer noch die gleiche Ausnahme. – venkat

1

Sind die Maschinen in der gleichen Domäne? Wenn nicht Administrator auf Maschine1 ist nicht gleich Administrator auf Maschine2, so könnte das Ihr Problem sein.

Eine Möglichkeit ist, dass Sie den Zugriff für diesen Benutzer gewähren müssen - auf dem entfernten Rechner - um den Dienst zu stoppen und starten Sie wie folgt:

SUBINACL /SERVICE \\<MACHINE>\W3SVC /GRANT=<MACHINE>\<USER>=TO 

Es ist ein Beispiel für diese in den Kommentaren des zweiten Codes Blockieren Sie unten (wie ich dies sogar mit dem Identitätswechsel Identitätswechsel benötigt).

Wenn dies das Problem nicht löst, können Sie versuchen, sich als Remotebenutzer auszugeben. Mit dem folgenden Code habe ich das geschafft.

Zuerst wird eine neue Klasse WrapperImpersonationContext.cs erstellen:

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; 
    } 
} 

Dann sollten Sie in der Lage sein, die folgenden auszuführen. Beachten Sie, dass Sie den Computernamen, den Benutzernamen und das Passwort ändern müssen, damit sie zu Ihrer Einrichtung passen. Beachten Sie auch die Kommentare, da es wichtig, die Sicherheitseinstellungen Informationen, die ich auf dem Weg entdeckt:

//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(); 

     } 
    } 

} 

Stellen Sie sicher, dass die Remote-Maschine beurteilt werden kann, die zur Verfügung gestellten Anmeldeinformationen, bevor Sie versuchen, dies in Code zu tun z.B. indem Sie diesen Benutzer über den Remote-Desktop verbinden.

+0

** Fehler **: 'Der Typ oder Namespacename 'RemoteAccessHelper' konnte nicht gefunden werden (fehlt eine using-Direktive oder eine Assemblyreferenz?)' – venkat

+0

Haben Sie sich den Code im Tutorial http: // dotnet- angesehen assembly.blogspot.com.au/2012/11/c-accessing-remote-file-by-using.html –

+0

So nur um zu klären 1) bestimmen Sie den Computer/Domain-Namen der Remote-Maschine 2) versuchen, eine Verbindung zur Fernbedienung Maschine von der Maschine, auf der Ihr Code ausgeführt wird, von der Verwendung des Computers/Domänennamens und des Benutzernamens und des Kennworts außerhalb des Codes, z Remote-Desktop verwenden 3) Wenn Sie erfolgreich sind, versuchen Sie den Identitätswechsel C# basierend auf dem Code in diesem Lernprogramm. Haben Sie auch festgestellt, ob Sie in einer Domain sind oder nicht? Wenn sich beide Maschinen in derselben Domäne befinden, könnte dies ein anderes Problem sein. –