none
Export von AD-Usern aus bestimmten Gruppen RRS feed

  • Frage

  • Hallo,

    ich beiße mir jetzt schon seit einem Tag die Zähne aus, aber ich bekomme es einfach nicht hin. Hoffentlich kann mir hier jemand weiterhelfen. :-)

    Folgende Aufgabe:

    Ich will eine Liste aller User die zu einem bestimmten Subunternehmen gehören (company = sub) und gleichzeitig Mitglieder von Gruppen sind, die im Namen eine bestimmte Buchstabenkombination haben (XA)

    Ich liste mal nur einen Versuch, stellvertretend für alle anderen auf:

    Get-ADGroup -Filter {(samaccountname -like '*XA*')} -Properties * | Select-Object -ExpandProperty Members | ForEach-Object {Get-ADUser -Filter {company -like '*sub*'}} | select-object name, samaccountname, memberof

    Die Ausgabe dieses Befehls wäre sowieso bei weitem nicht optimal, weil ich am liebsten eine Ausgabe hätte, die mir eine Gruppe zeigt, inkl. aller User, dann die nächste Gruppe,...

    Aber schon hier scheitere ich, weil mir die PS memberof einfach nicht befüllen will. Ich bekommen in der Ausgabe einfach nur leere geschweifte Klammern.

    Hat irgendjemand eine Idee?

    Vielen Dank

    Metronom


    • Bearbeitet Metronom8 Freitag, 11. Januar 2013 20:41
    Freitag, 11. Januar 2013 20:40

Antworten

  • Moin,

    das kommt wenn eins der Member eine Gruppe ist, dann funktioniert natürlich get-aduser nicht mehr. Ist eh imho suboptimal auf das members Property zu gehen, da nur String rauskommt. Hier mal ne andere Variante mit get-adgroupmember und der Bedingung mit where-object, dass die objectclass = user ist:

    #Einlesen aller Gruppen nach deiner Vorgabe in die Variable $groups
    $groups = Get-ADGroup -Filter {sAMACcountName -like "*XA*"} -Properties sAMAccountname,members
    
    #Nun Jede Gruppe in Foreach durchgehen, die Mitglieder auslesen und diese Filtern nach deinen vorgaben.
    
    foreach ($gruppe in $groups) {
        Write-Host "$($Gruppe.sAMAccountName) wird bearbeitet"
        $user = Get-ADGroupMember -Identity $gruppe | where-Object {$_.objectClass -eq "User"} | Get-ADUser -properties company|Where-Object {$_.company -like "*sub*"}
        #$gruppe.members|Get-ADUser -properties company|Where-Object {$_.company -like "*sub*"}
        Write-Host "Folgende User gefunden: $($user.sAMAccountName)"
    }

    Gruss

    Bastian

    • Als Antwort markiert Metronom8 Sonntag, 13. Januar 2013 15:22
    Sonntag, 13. Januar 2013 11:17

Alle Antworten

  • Hi,

    ich poste einfach mal was geht und du kannst ja dann Fragen stellen, wenn du was nicht verstehst:

    #Einlesen aller Gruppen nach deiner Vorgabe in die Variable $groups
    $groups = Get-ADGroup -Filter {sAMACcountName -like "*XA*"} -Properties sAMAccountname,members
    
    #Nun Jede Gruppe in Foreach durchgehen, die Mitglieder auslesen und diese Filtern nach deinen vorgaben.
    
    foreach ($gruppe in $groups) {
        Write-Host "$($Gruppe.sAMAccountName) wird bearbeitet"
        $user=$gruppe.members|Get-ADUser -properties company|Where-Object {$_.company -like "*sub*"}
        Write-Host "Folgende User gefunden: $($user.sAMAccountName)"
    }

    Falls du unbedingt nen 1-Zeiler haben willst, dann sowas ähnliches:

    Get-ADGroup -Filter {sAMACcountName -like "*XA*"} -Properties sAMAccountname,members | ForEach-Object {write-host "Gruppe $($_.sAMACcountname)";$_.members|Get-ADUser -properties company|Where-Object {$_.company -like "*sub*"}|Select-Object sAMAccountName | fl}

    Gruss

    Bastian


    • Bearbeitet baschuel Samstag, 12. Januar 2013 22:13
    Samstag, 12. Januar 2013 22:03
  • Vielen Dank für deine Hilfe! Das hat mich auf jeden Fall schon ein gutes Stückchen weitergebracht.

    Leider kommt bei der Ausführung ein seltsamer Fehler, der bewirkt dass keine User ausgelesen, bzw. angezeigt werden:

    Get-ADUser : Cannot find an object with identity: 'CN=XYZ,OU=groups,OU=AAA,DC=rrr,DC=com' under: 'DC=rrr,DC=com'.

    Allerdings existieren diese Gruppen selbstverständlich.

    Hast du da vielleicht noch eine Idee?

    Schönen Gruß
    Sven

    Sonntag, 13. Januar 2013 10:32
  • Moin,

    das kommt wenn eins der Member eine Gruppe ist, dann funktioniert natürlich get-aduser nicht mehr. Ist eh imho suboptimal auf das members Property zu gehen, da nur String rauskommt. Hier mal ne andere Variante mit get-adgroupmember und der Bedingung mit where-object, dass die objectclass = user ist:

    #Einlesen aller Gruppen nach deiner Vorgabe in die Variable $groups
    $groups = Get-ADGroup -Filter {sAMACcountName -like "*XA*"} -Properties sAMAccountname,members
    
    #Nun Jede Gruppe in Foreach durchgehen, die Mitglieder auslesen und diese Filtern nach deinen vorgaben.
    
    foreach ($gruppe in $groups) {
        Write-Host "$($Gruppe.sAMAccountName) wird bearbeitet"
        $user = Get-ADGroupMember -Identity $gruppe | where-Object {$_.objectClass -eq "User"} | Get-ADUser -properties company|Where-Object {$_.company -like "*sub*"}
        #$gruppe.members|Get-ADUser -properties company|Where-Object {$_.company -like "*sub*"}
        Write-Host "Folgende User gefunden: $($user.sAMAccountName)"
    }

    Gruss

    Bastian

    • Als Antwort markiert Metronom8 Sonntag, 13. Januar 2013 15:22
    Sonntag, 13. Januar 2013 11:17
  • Hallo Bastian,

    nochmals vielen Dank! Das hat soweit geklappt. Ich habe es ein bisschen angepasst, weil ich die Daten exportieren wollte.

    Soweit ich das jetzt verstanden habe löst das Skript aber keine Gruppen rekursiv auf. Es kann durchaus sein, dass in einer Gruppe eine andere Gruppe ist, in der dann wieder User des Tochterunternehmens drinnen sind. Reicht es da einfach den Switch recursive bei $groups ranzuhängen?

    So schaut das derzeit bei mir aus:

    $groups = Get-ADGroup -Filter {sAMACcountName -like "*XA*"} -Properties sAMAccountname,members
    foreach ($gruppe in $groups) {
    	$Dateiname = $gruppe.samaccountname.tostring()
    	$Datei = $Dateiname + ".txt"
        $user = Get-ADGroupMember -Identity $gruppe | where-Object {$_.objectClass -eq "User"} | Get-ADUser -properties company|Where-Object {$_.company -like "*sub*"} | select-object name | out-file $Datei -append
    }

    Jetzt arbeite ich an einer umgekehrten Auswertung, die mir unique-User anzeigt. Ich hätte gerne eine Liste aller User des Tochterunternehmes, die eben Mitglied in mindestens einer dieser Gruppen ist um die Gesamtzahl an Usern zu bestimmen.

    Vielen Dank (gerade am Sonntag!)

    Sven

    edit:

    Hier meine Umsetzung der Unique-User. Was hälst du davon?

    $groups = Get-ADGroup -Filter {sAMACcountName -like "*XA*"} -Properties sAMAccountname,members
    foreach ($gruppe in $groups) {
    	#$Dateiname = $gruppe.samaccountname.tostring()
    	#$Datei = $Dateiname + ".txt"
        $user = Get-ADGroupMember -Identity $gruppe | where-Object {$_.objectClass -eq "User"} | Get-ADUser -properties company|Where-Object {$_.company -like "*sub*"} | select-object name | out-file Userliste-XA.txt -append
    }
    Get-Content Userliste-XA.txt | Sort-Object | Get-Unique | out-file Userliste-XA_bereinigt.txt


    edit2: Jetzt fehlt mir nur noch die Gewissheit, dass alle Gruppen auch rekursiv abgearbeitet werden. Kannst du mir da bitte noch einen Hinweis geben?
    • Bearbeitet Metronom8 Sonntag, 13. Januar 2013 12:42
    Sonntag, 13. Januar 2013 12:28
  • Hi,

    was ich davon halte sollte nur relativ interessant sein, da ich selber nen Anfänger bin und sicher einiges von den Pros besser/anders gemacht werden würde. Aber das schöne an Powershell ist ja, dass es viele Wege gibt, die zum Ziel führen. :-) Insofern passt das denke ich schon, was du machst. Andere Wege wären ein Array oder Hashtable zu füllen und bei jedem Hinzufügen prüfen ob es den Wert schon gibt.

    Auch versuch ich nur Anhaltspunkte zu geben und keine fertigen Lösungen. Je nachdem wie, wo, wie oft und von wem so ein Script ausgeführt werden wird, würde ich es nochmal ganz anders machen bzw. versuchen :), hübscher, mehr Ausgänge, intelligenter. Das waren hier quick und dirty Vorschläge um dir Ideen zu geben.

    Wichtig ist die Hilfe..mit get-help bzw. dem Alias help (ist eher glaub ne Proxy Funktion, da help ein |more noch anhängt und dir die Hilfe Seitenweise anzeigt) bekommst du immer gute Anhaltspunkte.

    Da ist dann auch zu sehen, dass der Schalter recursive bei Get-ADGroup nicht existiert. Diesen gibt es aber bei Get-ADGroupmembers, der dann genau das tut, nämlich recursive Auflösung der Gruppenmitgliedschaften. Hänge den also einfach an "$User = Get-ADGroupmember ..." an und schon wird recursiv aufgelöst

    Gruss

    Bastian

    • Als Antwort markiert Metronom8 Sonntag, 13. Januar 2013 15:22
    • Tag als Antwort aufgehoben Metronom8 Sonntag, 13. Januar 2013 15:22
    Sonntag, 13. Januar 2013 13:16
  • Ich habe den Schalter hinzugefügt, aber erreiche damit das Sizelimit. Leider gibts ja sowas wie resultsize unlimited nicht für get-adgroupmember.

    Aber ich glaube damit kann ich vorerst leben. Vielen Dank für deine Hilfe!

    Gruß

    Sven

    Sonntag, 13. Januar 2013 15:21
  • Normalerweise Kommunizieren alle mir bekannten Active Directory Techniken über COM und RPC  mit dem LDAP Provider. (.NET Directory Services [ADSI], Windows Scripting Host (WSH),IADs usw..)

    Die Cmdlets des Microsoft Active Directory Modul kommunizieren mit dem Active Directory Web Service (ADWS) der auf einem oder mehreren Domaincontrolern Installiert ist.

    Der ADWS hat in seine Voreinstellungen ein Limit von 5000 GroupMember!
    Siehe MaxGroupOrMemberEntries in :
    http://technet.microsoft.com/en-us/library/dd391908%28WS.10%29.aspx

    Um dies hoch zusetzen sollte auf Allen DC die Voreinstellungen geändert werden. Dies könnte aber den Speicher der DC voll laufen lassen !

    DU kannst es mit einer rekursiven (sich selbst aufrufenden) Funktion versuchen. Hier hat PowerShell eine verschachtelungstiefe von 1000 Rekursionen. Das sollte reichen.

    Beide Lösungen laufen wahrscheinlich über, wenn man im AD mit den Gruppen Zirkelbezüge erzeugt hat.
    Zirkelbezüge erzeugen eine Endlos schleife. Dies Passiert im AD sehr leicht und ist nicht immer zu vermeiden.

    Beispiel eines einfachen Zirkelbezugs:
    Gruppe A enthält Gruppe B, Gruppe B enthält wieder Gruppe A

    Rekursive Funktion um alle Gruppen Member aufzulisten:

    Function Get-ADNestedGroupMembers {
      [cmdletbinding()]
      param ( [String]$Identity )           
     
      Get-ADGroupMember -Identity $Identity | ForEach-Object {
        If($_.ObjectClass -eq "group") {
          Get-ADNestedGroupMembers -Identity $_.distinguishedName
        } else {
          return $_
        }
      }           
    }
    
    # Beispielaufruf:
    Get-ADNestedGroupMembers NameVonMeinerTollenGruppe



    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!



    Montag, 14. Januar 2013 07:50