Group comparison

Welcome Forums General PowerShell Q&A Group comparison

  • This topic has 16 replies, 4 voices, and was last updated 1 month ago by
    Participant
    .
Viewing 16 reply threads
  • Author
    Posts
    • #220518
      Participant
      Topics: 3
      Replies: 11
      Points: 62
      Rank: Member

      Hey all! 

      So i have been searching the net for awhile without finding any usefull information about my problem. So any hints or how i should approach this problem would be nice. The problem is…

      I have 10 groups, an AD-user can only be member of ONE of these groups, how can i solve that? So far i have only found a way to compare two groups. Im not fishing for someone who can write the script for me although i would be happy with some hints on how to approach the problem.

      get-aduser -filter * -Properties memberof |
      foreach {
      $_.memberof
      if (-not($_.memberof -match "O365_E1_Basic" -and $_.memberof -match "O365_E1_Teams" )){
      Write-Output "User '$($_.samaccountname)' is not a member of either groups" 
      }else{
      Write-Output "User '$($_.samaccountname)' IS a member of either groups" -Verbose
      }
      }
    • #220521
      Participant
      Topics: 3
      Replies: 324
      Points: 1,056
      Helping Hand
      Rank: Community Hero

      Which group should they be in?

    • #220524
      Participant
      Topics: 12
      Replies: 519
      Points: 1,194
      Helping Hand
      Rank: Community Hero

      What are the names of the 10 groups if you can share that?

    • #220527
      Participant
      Topics: 12
      Replies: 519
      Points: 1,194
      Helping Hand
      Rank: Community Hero
      $UserList = Get-ADUser -filter * -Properties memberof | Select samAccountName,MemberOf 
      foreach ($User in $UserList) {
          Switch ($User.MemberOf) {
              {$_ -match 'O365_E1_Basic'} { "User '$($User.samAccountName)' IS a member of 'O365_E1_Basic'" }
              {$_ -match 'O365_E1_Teams'} { "User '$($User.samAccountName)' IS a member of 'O365_E1_Teams'" }
              {$_ -match 'testgroup1'}    { "User '$($User.samAccountName)' IS a member of 'testgroup1'" }
              {$_ -match 'testgroup2'}    { "User '$($User.samAccountName)' IS a member of 'testgroup2'" }
          }
      }
      
    • #220629
      Participant
      Topics: 3
      Replies: 11
      Points: 62
      Rank: Member

      They can be in one of the groups, but not two. So it will differ between all users.

    • #220632
      Participant
      Topics: 3
      Replies: 11
      Points: 62
      Rank: Member

      What are the names of the 10 groups if you can share that?

      O365_E1_Basic
      O365_E1_Exchange
      O365_E1_Onedrive
      O365_E1_Teams
      O365_E3_All
      O365_E3_Exchange
      O365_E3_Onedrive
      O365_E3_Pro
      O365_E3_Teams
      O365_EMS

      Are all groups, although each member can only be part of one group.

    • #220641
      Participant
      Topics: 4
      Replies: 2231
      Points: 5,414
      Helping Hand
      Rank: Community MVP

      There are a few approaches thinkable … you could use nested loops to determine if a user is member of more than one of the target groups:

      $GroupsList = @(
          'O365_E1_Basic'
          'O365_E1_Exchange'
          'O365_E1_Onedrive'
          'O365_E1_Teams'
          'O365_E3_All'
          'O365_E3_Exchange'
          'O365_E3_Onedrive'
          'O365_E3_Pro'
          'O365_E3_Teams'
          'O365_EMS'
      )
      
      $MembersList = @(
          'O365_E1_Teams'
          'O365_E3_All'
          'O365_E3_Exchange'
      )
      
      foreach($member in $MembersList){
          if ($member -in $GroupsList) {
              $Count++
          }
      }
      $Count

      If the count is more than 1 you’ve got one. 😉

      Or you use Compare-Object:

      (Compare-Object -ReferenceObject $GroupsList -DifferenceObject $MembersList -IncludeEqual |
          Where-Object {$_.SideIndicator -eq '=='}).count

      If the count is more than 1 you’ve got one. 😉

    • #220692
      Participant
      Topics: 3
      Replies: 324
      Points: 1,056
      Helping Hand
      Rank: Community Hero

      So they should only be in the first group they are found in? What if that varies?

    • #220785
      Participant
      Topics: 3
      Replies: 11
      Points: 62
      Rank: Member

      So they should only be in the first group they are found in? What if that varies?

      If a duplicate is found, i actually only need em in a csv, or other output so “manual labour” can decide wich group they actually should be in.

    • #220788
      Participant
      Topics: 4
      Replies: 2231
      Points: 5,414
      Helping Hand
      Rank: Community MVP

      If a duplicate is found, i actually only need em in a csv, or other output …

      Did you try my suggested approach?

    • #220818
      Participant
      Topics: 3
      Replies: 11
      Points: 62
      Rank: Member

      If a duplicate is found, i actually only need em in a csv, or other output …

      Did you try my suggested approach?

      Hey Olaf!

      Yes actually im sitting and testing it now, although im not getting the result i need unfortunatly. I have tried the thing you wrote above. :/

       

       

    • #220833
      Participant
      Topics: 3
      Replies: 11
      Points: 62
      Rank: Member
      $UserList = Get-ADUser -filter * Properties memberof | Select samAccountName,MemberOf
      foreach ($User in $UserList) {
      Switch ($User.MemberOf) {
      {$_ -match ‘O365_E1_Basic’} { “User ‘$($User.samAccountName)’ IS a member of ‘O365_E1_Basic'” }
      {$_ -match ‘O365_E1_Teams’} { “User ‘$($User.samAccountName)’ IS a member of ‘O365_E1_Teams'” }
      {$_ -match ‘testgroup1’} { “User ‘$($User.samAccountName)’ IS a member of ‘testgroup1′” }
      {$_ -match ‘testgroup2’} { “User ‘$($User.samAccountName)’ IS a member of ‘testgroup2′” }
      }
      }
      This method could work, if its somehow possible to add users with duplicate entrys to a string,array or output in someway. Since you cant use “if/else” with switch statements, is there any other way to go around the problem, its pretty much users to go through. (10k approx).

       

    • #220842
      Participant
      Topics: 12
      Replies: 519
      Points: 1,194
      Helping Hand
      Rank: Community Hero

      78, you really need to spend enough time to put a clear, well-articulated, precise description to the task you wish performed, such as:
      “Problem statement: list users who are members of more than one of the 10 AD groups below”

      solution

      # https://powershell.org/forums/topic/group-comparison
      # Problem statement: list users who are members of more than one of the 10 AD groups below
      
      $UserList = Get-ADUser -filter * -Properties memberof | Select samAccountName,MemberOf 
      
      $ReleventUserList = foreach ($User in $UserList) {
          [PSCustomObject][Ordered]@{
              samAccountName    = $User.samAccountName
              ReleventGroupList = Switch ($User.MemberOf) {
                  {$_ -match 'O365_E1_Basic'}    { 'O365_E1_Basic' }
                  {$_ -match 'O365_E1_Exchange'} { 'O365_E1_Exchange' }
                  {$_ -match 'O365_E1_Onedrive'} { 'O365_E1_Onedrive' }
                  {$_ -match 'O365_E1_Teams'}    { 'O365_E1_Teams' }
                  {$_ -match 'O365_E3_All'}      { 'O365_E3_All' }
                  {$_ -match 'O365_E3_Exchange'} { 'O365_E3_Exchange' }
                  {$_ -match 'O365_E3_Onedrive'} { 'O365_E3_Onedrive' }
                  {$_ -match 'O365_E3_Pro'}      { 'O365_E3_Pro' }
                  {$_ -match 'O365_E3_Teams'}    { 'O365_E3_Teams' }
                  {$_ -match 'O365_EMS'}         { 'O365_EMS' }
              }
          }
      }
      
      $ReleventUserList | where { $_.ReleventGroupList.Count -GT 1 }
      
    • #220845
      Participant
      Topics: 3
      Replies: 11
      Points: 62
      Rank: Member

      78, you really need to spend enough time to put a clear, well-articulated, precise description to the task you wish performed, such as:

      “Problem statement: list users who are members of more than one of the 10 AD groups below”

      solution

      PowerShell
      25 lines

      <textarea class=”ace_text-input” style=”opacity: 0; height: 18px; width: 6.59781px; left: 110.38px; top: 342px;” spellcheck=”false” wrap=”off”></textarea>

      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
      # Problem statement: list users who are members of more than one of the 10 AD groups below
      $UserList = Get-ADUser -filter * Properties memberof | Select samAccountName,MemberOf
      $ReleventUserList = foreach ($User in $UserList) {
      [PSCustomObject][Ordered]@{
      samAccountName = $User.samAccountName
      ReleventGroupList = Switch ($User.MemberOf) {
      {$_ -match ‘O365_E1_Basic’} { ‘O365_E1_Basic’ }
      {$_ -match ‘O365_E1_Exchange’} { ‘O365_E1_Exchange’ }
      {$_ -match ‘O365_E1_Onedrive’} { ‘O365_E1_Onedrive’ }
      {$_ -match ‘O365_E1_Teams’} { ‘O365_E1_Teams’ }
      {$_ -match ‘O365_E3_All’} { ‘O365_E3_All’ }
      {$_ -match ‘O365_E3_Exchange’} { ‘O365_E3_Exchange’ }
      {$_ -match ‘O365_E3_Onedrive’} { ‘O365_E3_Onedrive’ }
      {$_ -match ‘O365_E3_Pro’} { ‘O365_E3_Pro’ }
      {$_ -match ‘O365_E3_Teams’} { ‘O365_E3_Teams’ }
      {$_ -match ‘O365_EMS’} { ‘O365_EMS’ }
      }
      }
      }
      $ReleventUserList | where { $_.ReleventGroupList.Count GT 1 }
      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

      You’re right, I’ll try to improve in the future. Thanks so much, works perfectly !!!

    • #220848
      Participant
      Topics: 12
      Replies: 519
      Points: 1,194
      Helping Hand
      Rank: Community Hero

      Note the use of the -match operator in the <condition> of the Switch statement and how that requires changing the <condition> from a literal such as ‘O365_E1_Basic’ to a script block such as {$_ -match ‘O365_E1_Basic’}, because $User.MemberOf string would not have exact matches of the strings like ‘O365_E1_Basic’, but it would have larger strings like ‘CN=O365_E1_Basic,CN=Users,DC=domain,DC=com’

    • #220854
      Participant
      Topics: 3
      Replies: 11
      Points: 62
      Rank: Member

      Ah yes, thats correct. Thank you once again, saved me a week (or more 🙂 )

    • #220893
      Participant
      Topics: 4
      Replies: 2231
      Points: 5,414
      Helping Hand
      Rank: Community MVP

      If I got it right this should do the trick actually:

      $ReferenceADGroupDNList = @(
          'O365_E1_Basic'
          'O365_E1_Exchange'
          'O365_E1_Onedrive'
          'O365_E1_Teams'
          'O365_E3_All'
          'O365_E3_Exchange'
          'O365_E3_Onedrive'
          'O365_E3_Pro'
          'O365_E3_Teams'
          'O365_EMS'
      ) | 
          ForEach-Object  {
              Get-ADGroup -Identity $_ | Select-Object -ExpandProperty DistinguishedName
          } |
              Sort-Object
      
      Get-ADUser -Filter * -Properties memberof | 
          ForEach-Object {
          $MembershipList = $_.memberof | Sort-Object
          $MembershipCount = (Compare-Object -ReferenceObject $ReferenceADGroupDNList -DifferenceObject $MembershipList -IncludeEqual |
              Where-Object { $_.SideIndicator -eq '==' }).count
          [PSCustomObject]@{
              sAMAccountName = $_.sAMAccountName
              MembershipCount = $MembershipCount
          }
      }

      The result would be a list of all AD users and their count of memberships in the given list of groups. If there are users with a count of more than 1 membership you can inspect them further.

Viewing 16 reply threads
  • You must be logged in to reply to this topic.