Autor Beitrag
FrederikR
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mo 04.07.11 14:39 
Hallo,

mit PowerShell kann ich mit folgendem Befehl einen Benutzer aus dem Acitve Directory einer lokalen Gruppe hinzufügen:

ausblenden Quelltext
1:
([ADSI]"WinNT://$client/Administratoren,group").add("WinNT://$Domain/$accname,user")					


Wie mach ich dies in C#? Folgendes klappt nicht:
ausblenden Quelltext
1:
2:
3:
4:
DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + domain + "/" + client + ",Computer");
DirectoryEntry localGroup = localMachine.Children.Find("Administratoren", "group")

localGroup.Properties["member"].Add("WinNT://" + domain + "/" + accname);



Moderiert von user profile iconTh69: Topic aus Datenbanken (inkl. ADO.NET) verschoben am Di 05.07.2011 um 19:55
FrederikR Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 05.07.11 10:10 
Ist das hier das falsche Unterforum? Wäre für Hilfe echt dankbar! Oder weiß einfach niemand eine Antwort?
Eudaimonie
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 05.07.11 10:57 
Auf Codeproject gibts ne Seite "Everything in AD with C#"..
Damit solltest du weiter kommen.
www.codeproject.com/.../everythingInAD.aspx
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Di 05.07.11 11:12 
Hallo,

also erstmal ist es schon das falsche Unterforum, oder was hat das Thema mit Datenbanken zu tun?
Aber so sollte es schon gehen:
ausblenden C#-Quelltext
1:
2:
3:
DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
DirectoryEntry localGroup = localMachine.Children.Find("Administratoren""group");
localGroup.Invoke("Add""LDAP://CN=John Doe,CN=Users,DC=Fabrikam,DC=com");
WinNT:// -- lokales System
LDAP:// -- Domäne
LG
FrederikR Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 05.07.11 13:17 
user profile iconEudaimonie hat folgendes geschrieben Zum zitierten Posting springen:
Auf Codeproject gibts ne Seite "Everything in AD with C#"..
Damit solltest du weiter kommen.
www.codeproject.com/.../everythingInAD.aspx

Hätte ich vllt dazu schreiben sollen, aber daher hatte ich alles bisherige, was mich aber eben nicht weitergebracht hat.
Dort wird auf lokale Gruppen eingegangen.

user profile iconTrashkid2000 hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,
also erstmal ist es schon das falsche Unterforum, oder was hat das Thema mit Datenbanken zu tun?

Mag das dann jemand ins richtige Forum verschieben?

user profile iconTrashkid2000 hat folgendes geschrieben Zum zitierten Posting springen:

Aber so sollte es schon gehen:
ausblenden C#-Quelltext
1:
2:
3:
DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
DirectoryEntry localGroup = localMachine.Children.Find("Administratoren""group");
localGroup.Invoke("Add""LDAP://CN=John Doe,CN=Users,DC=Fabrikam,DC=com");
WinNT:// -- lokales System
LDAP:// -- Domäne
LG


Vielen Dank, sah vielversprechend aus, hat aber leider nicht geklappt. Irgendwo hatte ich glaube ich mal was davon gelesen, dass "WinNT://" und "LDAP://" nicht kombiniert werden dürfen.
Ein einfaches Ersetzen von "LDAP://" mit "WinNT://" bringt keinen Erfolg.

An anderer Stelle hab ich noch gefunden, dass man den Aufruf wie folgt machen muss, aber auch das bringt mir einen Fehler.
ausblenden Quelltext
1:
group.Invoke("Add", new string[]{user.Path});					


Jetzt ist meine Überlegung, wie man den Pfad "LDAP://CN=John Doe,CN=Users,DC=Fabrikam,DC=com" in "WinNT://..."-Format darstellt?
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Di 05.07.11 13:53 
So muss es aber gehen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
using (DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
{
   using (DirectoryEntry localGroup = localMachine.Children.Find("Administratoren""group"))
   {
      localGroup.Invoke("Add"string.Format("WinNT://{0}/{1},user""domainname""username"));
      localGroup.CommitChanges();
   }
}
Kann es leider neicht testen, da ich hier auf Arbeit zwar in einer Domäne bin, aber keine local Admin, und zu Hause bin ich zwar local Admin, habe aber keine Domäne :P
Wenn es scheitert, schaue mal bitte, was in der InnerException steht.
LG
FrederikR Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Di 05.07.11 14:04 
Vielen Dank, dass du dich meinem Problem annimmst.

Also das sieht glaube ich schon besser aus. Es konnt allerdings eine "UnauthorizedAccessException" (Zugriff verweigert).
Ich benutze zur Authorisierung am lokalen Client (der in der Domäne ist) die gleichen Credentials, wie für die Domäne selbst.
Muss ich den Benutzernamen in einem anderen Format übergeben?
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Di 05.07.11 15:38 
user profile iconFrederikR hat folgendes geschrieben Zum zitierten Posting springen:
[...] Es konnt allerdings eine "UnauthorizedAccessException" (Zugriff verweigert)[...]
Na immerhin, dann kann es ja nicht mehr an so vielen Dingen liegen...
user profile iconFrederikR hat folgendes geschrieben Zum zitierten Posting springen:
[...] Ich benutze zur Authorisierung am lokalen Client (der in der Domäne ist) die gleichen Credentials, wie für die Domäne selbst.
Muss ich den Benutzernamen in einem anderen Format übergeben?
Naja, wenn Du Dich mit deinem Account (also schon den Domänenaccount) am System anmeldest, und dann unter diesem Account den Code ausführst müsste es (vorrausgesetzt, Du bist lokaler Admin oder hast sonst irgendwie die Berechtigung, an der Benutzerverwaltung rumzuspielen) eigentlich schon klappen.
Oder wo übergibst Du Deine Benutzerdaten sonst noch, ausser als bei der Anmeldung von Windows?
FrederikR Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mi 06.07.11 11:10 
user profile iconTrashkid2000 hat folgendes geschrieben Zum zitierten Posting springen:
Naja, wenn Du Dich mit deinem Account (also schon den Domänenaccount) am System anmeldest, und dann unter diesem Account den Code ausführst müsste es (vorrausgesetzt, Du bist lokaler Admin oder hast sonst irgendwie die Berechtigung, an der Benutzerverwaltung rumzuspielen) eigentlich schon klappen.
Oder wo übergibst Du Deine Benutzerdaten sonst noch, ausser als bei der Anmeldung von Windows?

Ich melde mich nicht als Domänen-Admin an Windows an. Das ist auch Voraussetzung des Programms.
Ich übergebe die Credentials des berechtigten Users hier:
ausblenden Quelltext
1:
using (DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer",username,password))					
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Do 07.07.11 22:34 
Hallo,
hast Du denn das Problem nun schon zum laufen gebracht?

Habe es einfach mal ausprobiert (ohne Dömäne, nur mit einen Dummyuser)
user profile iconFrederikR hat folgendes geschrieben Zum zitierten Posting springen:

Ich melde mich nicht als Domänen-Admin an Windows an. Das ist auch Voraussetzung des Programms.
Ich übergebe die Credentials des berechtigten Users hier:
ausblenden Quelltext
1:
using (DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer",username,password))					

Habe es genau so mal probiert. Allerdings ohne Domäne, sondern nur mit lokalem Dummyuser. Dabei habe ich meine lokalen Admin-Credentials übergeben. Ausführung des Programms unter des Context des Dummyusers:
Ergebnis: Zugriff verweigert. Trotz gültiger Angaben.

Ausführung unter den Admin-Context (ausführen als...):
Ergebnis: alles i.O. und Dummyuser wurde auch zu den Admins hinzugefügt.

Ehrlich, keine Ahnung, was da falsch ist, oder wie man die Benutzerdaten übergeben muss.
Sorry.
FrederikR Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Fr 08.07.11 08:52 
Hmm das ist ja ärgerlich. Vielen Dank für deine Mühe! Hat mir vielleicht trotzdem weitergeholfen.
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Fr 08.07.11 21:55 
Hallo,
OMG, ich bin echt dumm!
Die Credentials, die bei der Instanziierung des DirectoryEntry übergeben werden, werden nur benötigt, wenn man sich an der Domäne anmelden muss. Also wenn der Rechner, von dem das Programm ausgeführt wird, nicht in der Domäne ist. Sorry dafür.

Also ganz falscher Weg. Der richtige Weg heißt Impersonifikation. Es muss nämlich Code unter einen anderen Benutzercontext ausgeführt werden (wenn der Benutzer, der das Programm ausführt nicht in der Admin- Gruppe ist).

Bei Codeproject gibt es dafür eine schöne, schlanke Klasse (Impersonator), die das "LogonUser" gut abnimmt. Hier mal der Link: www.codeproject.com/...etaimpersonator.aspx
So, nun mal der Code dafür: Also, ich prüfe erstmal, ob der User, unter dessen Context das Programm ausgeführt wird, in der Admin Gruppe ist. Wenn nicht, wird impersonifiziert, sonst ist das ja nicht nötig.
Naja, und dann klappt das schon so:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
bool isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);

Console.WriteLine(string.Format("Logged in as {0}", isAdmin ? "Administrator" : "User"));

Impersonator impersonator = null;
if (!isAdmin)
{
  Console.WriteLine("Start Impersonation");
  impersonator = new Impersonator("AdminUsername""Domainname""Password");
}
try
{
  using (DirectoryEntry localMachine = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer"))
  {
    using (DirectoryEntry localGroup = localMachine.Children.Find("Administratoren""group"))
    {
      localGroup.Invoke("Add"string.Format("WinNT://{0}/{1},user""domainname""username"));
      localGroup.CommitChanges();
    }
  }
  Console.WriteLine("Successfully added");
}
catch (Exception ex)
{
  Console.WriteLine(ex.Message);
}
finally
{
  if (!isAdmin && impersonator != null)
  {
    impersonator.Dispose();
    Console.WriteLine("End Impersonation");
  }
}
Console.ReadKey();
Ob Du bei der Instanziierung des Impersonators den Domainnamen mit anbegeb musst, weiß ich nicht. Wenn nicht, ist er null.
LG, Marko
FrederikR Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Fr 15.07.11 10:52 
Oh danke! Hab grad erst gesehen, dass du noch was geschrieben hast. Wenn ich nochmal Zeit finde, muss ich das unbedingt ausprobieren. Danke!