Frage

Innerhalb von c# muss ich dazu in der Lage sein

  • Stellen Sie eine Verbindung zu einem Remote-System her und geben Sie ggf. Benutzernamen/Passwort an
  • Listen Sie die Mitglieder einer lokalen Gruppe auf diesem System auf
  • Holen Sie sich die Ergebnisse zurück zum ausführenden Computer

So würde ich zum Beispiel mit den entsprechenden Creds eine Verbindung zu \SOMESYSTEM herstellen und eine Liste lokaler Administratoren abrufen, einschließlich SOMESYSTEM\Administrator, SOMESYSTEM\Bob, DOMAIN\AlanH, „DOMAIN\Domänenadministratoren“.

Ich habe dies mit system.directoryservices.accountmanagement versucht, habe aber Probleme mit der Authentifizierung.Manchmal bekomme ich:

Mehrere Verbindungen zu einem Server oder einer freigegebenen Ressource durch denselben Benutzer unter Verwendung von mehr als einem Benutzernamen sind nicht zulässig.Trennen Sie alle vorherigen Verbindungen zum Server oder zur freigegebenen Ressource und versuchen Sie es erneut.(Ausnahme von HRESULT:0x800704C3)

Das oben Genannte ist ein Versuch, da es Situationen geben wird, in denen ich die Zuordnung vorhandener Laufwerke oder UNC-Verbindungen einfach nicht aufheben kann.

In anderen Fällen erhält mein Programm einen UNBEKANNTEN FEHLER und das Sicherheitsprotokoll auf dem Remote-System meldet einen Fehler 675, Code 0x19, der KDC_ERR_PREAUTH_REQUIRED ist.

Ich brauche eine einfachere und weniger fehleranfällige Möglichkeit, dies zu tun!

War es hilfreich?

Lösung

Dies sollte mit WMI einfach zu bewerkstelligen sein.Hier haben Sie einen Verweis auf einige Dokumente:

WMI-Dokumentation für Win32_UserAccount

Auch wenn Sie noch keine Erfahrung mit WMI haben, sollte es ganz einfach sein, den VB-Script-Code unten auf der Seite in .NET-Code umzuwandeln.

Hoffe das hat geholfen!

Andere Tipps

Davidg war auf dem richtigen Weg, und ich verdanke ihm die Antwort.

Die erforderliche WMI-Abfrage war jedoch etwas kompliziert, da ich nicht nur eine Benutzerliste für die gesamte Maschine, sondern eine Teilmenge der Benutzer benötigte und Gruppen, egal ob lokal oder Domäne, die Mitglieder der lokalen Administratorengruppe waren.Fürs Protokoll: Diese WMI-Abfrage lautete:

SELECT PartComponent FROM Win32_GroupUser WHERE GroupComponent = "Win32_Group.Domain='thehostname',Name='thegroupname'"

Hier ist der vollständige Codeausschnitt:

public string GroupMembers(string targethost, string groupname, string targetusername, string targetpassword)
        {
            StringBuilder result = new StringBuilder(); 
            try
            {
                ConnectionOptions Conn = new ConnectionOptions();
                if (targethost != Environment.MachineName) //WMI errors if creds given for localhost
                {
                    Conn.Username = targetusername; //can be null
                    Conn.Password = targetpassword; //can be null
                }
                Conn.Timeout = TimeSpan.FromSeconds(2);
                ManagementScope scope = new ManagementScope("\\\\" + targethost + "\\root\\cimv2", Conn);
                scope.Connect();
                StringBuilder qs = new StringBuilder();
                qs.Append("SELECT PartComponent FROM Win32_GroupUser WHERE GroupComponent = \"Win32_Group.Domain='");
                qs.Append(targethost);
                qs.Append("',Name='");
                qs.Append(groupname);
                qs.AppendLine("'\"");
                ObjectQuery query = new ObjectQuery(qs.ToString());
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
                ManagementObjectCollection queryCollection = searcher.Get();
                foreach (ManagementObject m in queryCollection)
                {
                    ManagementPath path = new ManagementPath(m["PartComponent"].ToString());                                        
                    { 
                        String[] names = path.RelativePath.Split(',');
                        result.Append(names[0].Substring(names[0].IndexOf("=") + 1).Replace("\"", " ").Trim() + "\\"); 
                        result.AppendLine(names[1].Substring(names[1].IndexOf("=") + 1).Replace("\"", " ").Trim());                    
                    }
                }
                return result.ToString();
            }
            catch (Exception e)
            {
                Console.WriteLine("Error. Message: " + e.Message);
                return "fail";
            }
        }

Wenn ich also Groupmembers("Server1", "Administrators", "myusername", "mypassword");Ich erhalte eine einzelne Zeichenfolge zurückgegeben mit:

SERVER1\Administrator
MEINE DOMÄNE\Domänenadministratoren

Die tatsächliche WMI-Rückgabe sieht eher so aus:

\\SERVER1 oot\cimv2:Win32_UserAccount.Domain="SERVER1",Name="Administrator"

...Wie Sie sehen können, musste ich die Zeichenfolgen ein wenig manipulieren, um sie aufzupeppen.

Ich würde die Verwendung der Win32-API-Funktion empfehlen NetLocalGroupGetMembers.Es ist viel einfacher als der Versuch, die verrückte LDAP-Syntax herauszufinden, die für einige der anderen hier empfohlenen Lösungen erforderlich ist.Solange Sie sich als der Benutzer ausgeben, für den Sie die Prüfung durchführen möchten, indem Sie „LoginUser“ aufrufen, sollten keine Sicherheitsprobleme auftreten.

Sie finden Beispielcode für die Durchführung des Identitätswechsels Hier.

Wenn Sie Hilfe beim Aufrufen von „NetLocalGroupGetMembers“ in C# benötigen, empfehle ich Ihnen, den PInvoke-Assistenten von Jared Parson auszuprobieren herunterladen von Codeplex.

Wenn Sie den Code in einer ASP.NET-App ausführen, die in IIS ausgeführt wird, und sich für den Aufruf als Benutzer ausgeben möchten, der auf die Website zugreift, müssen Sie dem Produktionswebserver möglicherweise die Berechtigung „Zur Delegation vertrauenswürdig“ erteilen.

Wenn Sie auf dem Desktop arbeiten, sollte die Verwendung der Sicherheitsanmeldeinformationen des aktiven Benutzers kein Problem darstellen.

Es ist möglich, dass Ihr Netzwerkadministrator den Zugriff auf das „Sicherbare Objekt“ für den bestimmten Computer, auf den Sie zugreifen möchten, widerrufen hat.Leider ist dieser Zugriff für alle erforderlich Netzwerkverwaltungs-API Funktionen funktionieren.Wenn dies der Fall ist, müssen Sie allen Benutzern, als die Sie ausführen möchten, Zugriff auf das „Sicherbare Objekt“ gewähren.Mit den standardmäßigen Windows-Sicherheitseinstellungen sollten jedoch alle authentifizierten Benutzer Zugriff haben.

Ich hoffe das hilft.

-Scott

Dies sollte mit System.DirectoryServices.DirectoryEntry möglich sein.Wenn Sie Probleme bei der Remote-Ausführung haben, können Sie möglicherweise etwas auf den Remote-Computern installieren, um Ihre Daten über eine Art RPC bereitzustellen, z. B. Remoting oder einen Webdienst.Aber ich denke, was Sie versuchen, sollte aus der Ferne möglich sein, ohne zu ausgefallen zu werden.

Wenn Windows Ihnen keine Verbindung über den Anmeldemechanismus zulässt, besteht meines Erachtens Ihre einzige Möglichkeit darin, etwas auf dem Remote-Computer mit einem offenen Port auszuführen (entweder direkt oder über Remoting oder einen Webdienst, wie erwähnt).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top