Is there a better way to get AD group members for a given list of AD group ObjectGUIDs?












0














I have a list of ObjectGUID's (49 of them) stored in a CSV, and I'm outputting a CSV which contains a listing of all members of those groups in the following format: "LastName, FirstName" , "AD Group Name"
I have it working (most of the time; sometimes I get IOException errors from the Add-Content cmdlt), but it is very slow (takes ~30 minutes for 8000 members). I don't have a lot of experience with Powershell , but I feel like there is a better/more efficient way of doing this. Any ideas on how to make this more efficient?



Note: I use the "-Server" switch because I actually have to run this script across a couple different domains, so the code I've pasted is duplicated twice in my original code, with a different CSV input, and a different domain passed to the "-Server" switch.



#read in CSV of ObjectGUIDs
$guids = Import-CSV .ObjectGUIDs.csv

#loop through each AD group
foreach($group in $guids) {
$group_name = Get-ADObject -identity $group.objectGUID -server myDomain
$group_name = $group_name.Name

#get list of users in current group
$users = get-adgroupmember -server myDomain -identity
$group.ObjectGUID | where {$_.objectclass -eq 'user'}

#loop through each user of the current group
foreach ($user in $users) {
#get display name of current user
$display_name = get-aduser -identity $user.objectGUID -server
myDomain -properties DisplayName
#build the current row
$row = ('"' + $display_name.DisplayName + '"' + ',' + '"' +
$group_name + '"')
add-content -path "C:Pathtooutput.csv" -value $row
}
}


As I said above, this usually works, but takes a long time.










share|improve this question



























    0














    I have a list of ObjectGUID's (49 of them) stored in a CSV, and I'm outputting a CSV which contains a listing of all members of those groups in the following format: "LastName, FirstName" , "AD Group Name"
    I have it working (most of the time; sometimes I get IOException errors from the Add-Content cmdlt), but it is very slow (takes ~30 minutes for 8000 members). I don't have a lot of experience with Powershell , but I feel like there is a better/more efficient way of doing this. Any ideas on how to make this more efficient?



    Note: I use the "-Server" switch because I actually have to run this script across a couple different domains, so the code I've pasted is duplicated twice in my original code, with a different CSV input, and a different domain passed to the "-Server" switch.



    #read in CSV of ObjectGUIDs
    $guids = Import-CSV .ObjectGUIDs.csv

    #loop through each AD group
    foreach($group in $guids) {
    $group_name = Get-ADObject -identity $group.objectGUID -server myDomain
    $group_name = $group_name.Name

    #get list of users in current group
    $users = get-adgroupmember -server myDomain -identity
    $group.ObjectGUID | where {$_.objectclass -eq 'user'}

    #loop through each user of the current group
    foreach ($user in $users) {
    #get display name of current user
    $display_name = get-aduser -identity $user.objectGUID -server
    myDomain -properties DisplayName
    #build the current row
    $row = ('"' + $display_name.DisplayName + '"' + ',' + '"' +
    $group_name + '"')
    add-content -path "C:Pathtooutput.csv" -value $row
    }
    }


    As I said above, this usually works, but takes a long time.










    share|improve this question

























      0












      0








      0







      I have a list of ObjectGUID's (49 of them) stored in a CSV, and I'm outputting a CSV which contains a listing of all members of those groups in the following format: "LastName, FirstName" , "AD Group Name"
      I have it working (most of the time; sometimes I get IOException errors from the Add-Content cmdlt), but it is very slow (takes ~30 minutes for 8000 members). I don't have a lot of experience with Powershell , but I feel like there is a better/more efficient way of doing this. Any ideas on how to make this more efficient?



      Note: I use the "-Server" switch because I actually have to run this script across a couple different domains, so the code I've pasted is duplicated twice in my original code, with a different CSV input, and a different domain passed to the "-Server" switch.



      #read in CSV of ObjectGUIDs
      $guids = Import-CSV .ObjectGUIDs.csv

      #loop through each AD group
      foreach($group in $guids) {
      $group_name = Get-ADObject -identity $group.objectGUID -server myDomain
      $group_name = $group_name.Name

      #get list of users in current group
      $users = get-adgroupmember -server myDomain -identity
      $group.ObjectGUID | where {$_.objectclass -eq 'user'}

      #loop through each user of the current group
      foreach ($user in $users) {
      #get display name of current user
      $display_name = get-aduser -identity $user.objectGUID -server
      myDomain -properties DisplayName
      #build the current row
      $row = ('"' + $display_name.DisplayName + '"' + ',' + '"' +
      $group_name + '"')
      add-content -path "C:Pathtooutput.csv" -value $row
      }
      }


      As I said above, this usually works, but takes a long time.










      share|improve this question













      I have a list of ObjectGUID's (49 of them) stored in a CSV, and I'm outputting a CSV which contains a listing of all members of those groups in the following format: "LastName, FirstName" , "AD Group Name"
      I have it working (most of the time; sometimes I get IOException errors from the Add-Content cmdlt), but it is very slow (takes ~30 minutes for 8000 members). I don't have a lot of experience with Powershell , but I feel like there is a better/more efficient way of doing this. Any ideas on how to make this more efficient?



      Note: I use the "-Server" switch because I actually have to run this script across a couple different domains, so the code I've pasted is duplicated twice in my original code, with a different CSV input, and a different domain passed to the "-Server" switch.



      #read in CSV of ObjectGUIDs
      $guids = Import-CSV .ObjectGUIDs.csv

      #loop through each AD group
      foreach($group in $guids) {
      $group_name = Get-ADObject -identity $group.objectGUID -server myDomain
      $group_name = $group_name.Name

      #get list of users in current group
      $users = get-adgroupmember -server myDomain -identity
      $group.ObjectGUID | where {$_.objectclass -eq 'user'}

      #loop through each user of the current group
      foreach ($user in $users) {
      #get display name of current user
      $display_name = get-aduser -identity $user.objectGUID -server
      myDomain -properties DisplayName
      #build the current row
      $row = ('"' + $display_name.DisplayName + '"' + ',' + '"' +
      $group_name + '"')
      add-content -path "C:Pathtooutput.csv" -value $row
      }
      }


      As I said above, this usually works, but takes a long time.







      powershell






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Dec 27 at 14:34









      deano

      126




      126
























          1 Answer
          1






          active

          oldest

          votes


















          0














          Gathering data in a [PSCustomObject] and using Export-Csv only once should be much more efficient.



          ## Q:Test20181227SO_53946702.ps1

          $guids = Import-CSV .ObjectGUIDs.csv
          $CsvFile = "C:Pathtooutput.csv"
          $Server = myDomain

          $CsvData = foreach($group in $guids) {
          $GroupName = (Get-ADObject -identity $group.objectGUID -server $Server).Name

          #get list of users in current group
          $users = Get-ADgroupMember -Server $Server -Identity $group.ObjectGUID |
          Where-Object ObjectClass -eq 'user'

          foreach ($user in $users) {
          [PSCustomObject]@{
          DisplayName = (Get-ADuser -Identity $user.objectGUID -server $Server -Properties DisplayName).DisplayName
          GroupName = $GroupName
          }
          }
          }
          $CsvData | Export-Csv $CsvFile -NoTypeInformation





          share|improve this answer

















          • 1




            Also cache the result of Get-ADUser by users' SIDs for example, this can save some time because this code requests user details from AD each time it encounters a user in any group. Also this doesn't account for rtansient group membership - but TS didn't state it's needed.
            – Vesper
            Dec 28 at 8:41










          • Can you provide some example code of 'cache(ing) the result of Get-ADUser'? Is that somehow different than using each user's ObjectGUID to get their DisplayName? Also, what is transient group membership? I Googled it but nothing came up with that specific name.
            – deano
            Dec 28 at 15:32










          • To have @Vesper notice your comment, address him like I did with a leading @
            – LotPings
            Dec 28 at 15:35










          • @Vesper See my comment above.
            – deano
            Dec 28 at 15:54






          • 1




            @deano Transient group membership is a construction where Group1 has Group2 as its member, and Group2 has users in it, that are then evaluated as members of Group1 as well, but are not displayed in Group1's Get-ADGroupMember list. Caching is done via global object of type dictionary, you then do if {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...} and then address dic[$_.samaccountname] instead of always calling Get-ADUser.
            – Vesper
            2 days ago











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53946702%2fis-there-a-better-way-to-get-ad-group-members-for-a-given-list-of-ad-group-objec%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          Gathering data in a [PSCustomObject] and using Export-Csv only once should be much more efficient.



          ## Q:Test20181227SO_53946702.ps1

          $guids = Import-CSV .ObjectGUIDs.csv
          $CsvFile = "C:Pathtooutput.csv"
          $Server = myDomain

          $CsvData = foreach($group in $guids) {
          $GroupName = (Get-ADObject -identity $group.objectGUID -server $Server).Name

          #get list of users in current group
          $users = Get-ADgroupMember -Server $Server -Identity $group.ObjectGUID |
          Where-Object ObjectClass -eq 'user'

          foreach ($user in $users) {
          [PSCustomObject]@{
          DisplayName = (Get-ADuser -Identity $user.objectGUID -server $Server -Properties DisplayName).DisplayName
          GroupName = $GroupName
          }
          }
          }
          $CsvData | Export-Csv $CsvFile -NoTypeInformation





          share|improve this answer

















          • 1




            Also cache the result of Get-ADUser by users' SIDs for example, this can save some time because this code requests user details from AD each time it encounters a user in any group. Also this doesn't account for rtansient group membership - but TS didn't state it's needed.
            – Vesper
            Dec 28 at 8:41










          • Can you provide some example code of 'cache(ing) the result of Get-ADUser'? Is that somehow different than using each user's ObjectGUID to get their DisplayName? Also, what is transient group membership? I Googled it but nothing came up with that specific name.
            – deano
            Dec 28 at 15:32










          • To have @Vesper notice your comment, address him like I did with a leading @
            – LotPings
            Dec 28 at 15:35










          • @Vesper See my comment above.
            – deano
            Dec 28 at 15:54






          • 1




            @deano Transient group membership is a construction where Group1 has Group2 as its member, and Group2 has users in it, that are then evaluated as members of Group1 as well, but are not displayed in Group1's Get-ADGroupMember list. Caching is done via global object of type dictionary, you then do if {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...} and then address dic[$_.samaccountname] instead of always calling Get-ADUser.
            – Vesper
            2 days ago
















          0














          Gathering data in a [PSCustomObject] and using Export-Csv only once should be much more efficient.



          ## Q:Test20181227SO_53946702.ps1

          $guids = Import-CSV .ObjectGUIDs.csv
          $CsvFile = "C:Pathtooutput.csv"
          $Server = myDomain

          $CsvData = foreach($group in $guids) {
          $GroupName = (Get-ADObject -identity $group.objectGUID -server $Server).Name

          #get list of users in current group
          $users = Get-ADgroupMember -Server $Server -Identity $group.ObjectGUID |
          Where-Object ObjectClass -eq 'user'

          foreach ($user in $users) {
          [PSCustomObject]@{
          DisplayName = (Get-ADuser -Identity $user.objectGUID -server $Server -Properties DisplayName).DisplayName
          GroupName = $GroupName
          }
          }
          }
          $CsvData | Export-Csv $CsvFile -NoTypeInformation





          share|improve this answer

















          • 1




            Also cache the result of Get-ADUser by users' SIDs for example, this can save some time because this code requests user details from AD each time it encounters a user in any group. Also this doesn't account for rtansient group membership - but TS didn't state it's needed.
            – Vesper
            Dec 28 at 8:41










          • Can you provide some example code of 'cache(ing) the result of Get-ADUser'? Is that somehow different than using each user's ObjectGUID to get their DisplayName? Also, what is transient group membership? I Googled it but nothing came up with that specific name.
            – deano
            Dec 28 at 15:32










          • To have @Vesper notice your comment, address him like I did with a leading @
            – LotPings
            Dec 28 at 15:35










          • @Vesper See my comment above.
            – deano
            Dec 28 at 15:54






          • 1




            @deano Transient group membership is a construction where Group1 has Group2 as its member, and Group2 has users in it, that are then evaluated as members of Group1 as well, but are not displayed in Group1's Get-ADGroupMember list. Caching is done via global object of type dictionary, you then do if {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...} and then address dic[$_.samaccountname] instead of always calling Get-ADUser.
            – Vesper
            2 days ago














          0












          0








          0






          Gathering data in a [PSCustomObject] and using Export-Csv only once should be much more efficient.



          ## Q:Test20181227SO_53946702.ps1

          $guids = Import-CSV .ObjectGUIDs.csv
          $CsvFile = "C:Pathtooutput.csv"
          $Server = myDomain

          $CsvData = foreach($group in $guids) {
          $GroupName = (Get-ADObject -identity $group.objectGUID -server $Server).Name

          #get list of users in current group
          $users = Get-ADgroupMember -Server $Server -Identity $group.ObjectGUID |
          Where-Object ObjectClass -eq 'user'

          foreach ($user in $users) {
          [PSCustomObject]@{
          DisplayName = (Get-ADuser -Identity $user.objectGUID -server $Server -Properties DisplayName).DisplayName
          GroupName = $GroupName
          }
          }
          }
          $CsvData | Export-Csv $CsvFile -NoTypeInformation





          share|improve this answer












          Gathering data in a [PSCustomObject] and using Export-Csv only once should be much more efficient.



          ## Q:Test20181227SO_53946702.ps1

          $guids = Import-CSV .ObjectGUIDs.csv
          $CsvFile = "C:Pathtooutput.csv"
          $Server = myDomain

          $CsvData = foreach($group in $guids) {
          $GroupName = (Get-ADObject -identity $group.objectGUID -server $Server).Name

          #get list of users in current group
          $users = Get-ADgroupMember -Server $Server -Identity $group.ObjectGUID |
          Where-Object ObjectClass -eq 'user'

          foreach ($user in $users) {
          [PSCustomObject]@{
          DisplayName = (Get-ADuser -Identity $user.objectGUID -server $Server -Properties DisplayName).DisplayName
          GroupName = $GroupName
          }
          }
          }
          $CsvData | Export-Csv $CsvFile -NoTypeInformation






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 27 at 15:08









          LotPings

          17.5k61532




          17.5k61532








          • 1




            Also cache the result of Get-ADUser by users' SIDs for example, this can save some time because this code requests user details from AD each time it encounters a user in any group. Also this doesn't account for rtansient group membership - but TS didn't state it's needed.
            – Vesper
            Dec 28 at 8:41










          • Can you provide some example code of 'cache(ing) the result of Get-ADUser'? Is that somehow different than using each user's ObjectGUID to get their DisplayName? Also, what is transient group membership? I Googled it but nothing came up with that specific name.
            – deano
            Dec 28 at 15:32










          • To have @Vesper notice your comment, address him like I did with a leading @
            – LotPings
            Dec 28 at 15:35










          • @Vesper See my comment above.
            – deano
            Dec 28 at 15:54






          • 1




            @deano Transient group membership is a construction where Group1 has Group2 as its member, and Group2 has users in it, that are then evaluated as members of Group1 as well, but are not displayed in Group1's Get-ADGroupMember list. Caching is done via global object of type dictionary, you then do if {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...} and then address dic[$_.samaccountname] instead of always calling Get-ADUser.
            – Vesper
            2 days ago














          • 1




            Also cache the result of Get-ADUser by users' SIDs for example, this can save some time because this code requests user details from AD each time it encounters a user in any group. Also this doesn't account for rtansient group membership - but TS didn't state it's needed.
            – Vesper
            Dec 28 at 8:41










          • Can you provide some example code of 'cache(ing) the result of Get-ADUser'? Is that somehow different than using each user's ObjectGUID to get their DisplayName? Also, what is transient group membership? I Googled it but nothing came up with that specific name.
            – deano
            Dec 28 at 15:32










          • To have @Vesper notice your comment, address him like I did with a leading @
            – LotPings
            Dec 28 at 15:35










          • @Vesper See my comment above.
            – deano
            Dec 28 at 15:54






          • 1




            @deano Transient group membership is a construction where Group1 has Group2 as its member, and Group2 has users in it, that are then evaluated as members of Group1 as well, but are not displayed in Group1's Get-ADGroupMember list. Caching is done via global object of type dictionary, you then do if {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...} and then address dic[$_.samaccountname] instead of always calling Get-ADUser.
            – Vesper
            2 days ago








          1




          1




          Also cache the result of Get-ADUser by users' SIDs for example, this can save some time because this code requests user details from AD each time it encounters a user in any group. Also this doesn't account for rtansient group membership - but TS didn't state it's needed.
          – Vesper
          Dec 28 at 8:41




          Also cache the result of Get-ADUser by users' SIDs for example, this can save some time because this code requests user details from AD each time it encounters a user in any group. Also this doesn't account for rtansient group membership - but TS didn't state it's needed.
          – Vesper
          Dec 28 at 8:41












          Can you provide some example code of 'cache(ing) the result of Get-ADUser'? Is that somehow different than using each user's ObjectGUID to get their DisplayName? Also, what is transient group membership? I Googled it but nothing came up with that specific name.
          – deano
          Dec 28 at 15:32




          Can you provide some example code of 'cache(ing) the result of Get-ADUser'? Is that somehow different than using each user's ObjectGUID to get their DisplayName? Also, what is transient group membership? I Googled it but nothing came up with that specific name.
          – deano
          Dec 28 at 15:32












          To have @Vesper notice your comment, address him like I did with a leading @
          – LotPings
          Dec 28 at 15:35




          To have @Vesper notice your comment, address him like I did with a leading @
          – LotPings
          Dec 28 at 15:35












          @Vesper See my comment above.
          – deano
          Dec 28 at 15:54




          @Vesper See my comment above.
          – deano
          Dec 28 at 15:54




          1




          1




          @deano Transient group membership is a construction where Group1 has Group2 as its member, and Group2 has users in it, that are then evaluated as members of Group1 as well, but are not displayed in Group1's Get-ADGroupMember list. Caching is done via global object of type dictionary, you then do if {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...} and then address dic[$_.samaccountname] instead of always calling Get-ADUser.
          – Vesper
          2 days ago




          @deano Transient group membership is a construction where Group1 has Group2 as its member, and Group2 has users in it, that are then evaluated as members of Group1 as well, but are not displayed in Group1's Get-ADGroupMember list. Caching is done via global object of type dictionary, you then do if {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...} and then address dic[$_.samaccountname] instead of always calling Get-ADUser.
          – Vesper
          2 days ago


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53946702%2fis-there-a-better-way-to-get-ad-group-members-for-a-given-list-of-ad-group-objec%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Monofisismo

          Angular Downloading a file using contenturl with Basic Authentication

          Olmecas