none
get-adgroupmember gives operation timeout error RRS feed

  • Question

  • Hi experts,

    i am tring to get the user names from few groups in AD. But it displays me an eror for few groups like

    ERROR :-

    At D:\All Scripts\AD Scripts\groupmember.ps1:7 (file:///D:/All%20Scripts/AD%20Scripts/groupmember.ps1:7) char:1

    + Get-ADGroupMember vpn_terminal_access | Foreach-object{

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo : O

    perationTimeout: (vpn_terminal_access:ADGroup)

    [Get-ADGroupMember], TimeoutException

    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.TimeoutException,Mi

    crosoft.ActiveDirectory.Management.Commands.GetADGroupMember

    SCRIPT -

    Get-ADGroupMember ABC | Foreach-object{
       $_.samaccountname | get-aduser -properties * | Ft name, emailaddress | out-file .\ABC.csv -enc utf8 -append
    }

    ABC is group name. What i need to do ?

    Tuesday, April 29, 2014 11:55 AM

Answers

  • You can have issues with Get-ADGroupMember on large groups.

    Try the following workaround...

    (Get-ADGroup "vpn_terminal_access" -properties members).members | Get-ADUser -properties emailaddress | 
    Select-Object Name, emailaddress | Export-CSV ".\results.csv" -noType

    Tuesday, April 29, 2014 4:28 PM
  • Doesn't matter. The user principal is very easy to get.  It is the embedded Get-AdUser that is time consuming because it mkes Get-AdGroupMember wait on every member.  If any member is in another domain and the network is slow it can cause a timeout. 

    Yes= Using Get-ADGroup would be faster but it, too, returns an array of strings and NOT a comma delimited list.

    Under most circumstances the difference is trivial.  If the domains are remote then this is an issue.  One more reason to not place users in a group when remote. Place them in a group and place the group in the group.  Overall performance for everything is better and more reliable.  That is why it is designed that way.  In NT4 this was not as easy so NT4 was prone to this kind of failure. Too often Admins just add users to local groups when they are remote. They then complain about performance. It can very badly impact logon performance.

    Notice that this is a collection (array):

    PS C:\scripts> (Get-AdGroup testgrp -prop members).members.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     False    ADPropertyValueCollection                System.Collections.CollectionBase
    For this property only it is a collection of strings. It can be a collection of any "ValueType"


    ¯\_(ツ)_/¯"



    • Edited by jrv Thursday, May 1, 2014 12:10 PM
    • Marked as answer by Amitkumar_Patil Friday, May 2, 2014 7:17 AM
    Thursday, May 1, 2014 12:08 PM

All replies

  • Please read the error message carefully.  It tells you the exact problem:

    ERROR :-

    At D:\All Scripts\AD Scripts\groupmember.ps1:7 (file:///D:/All%20Scripts/AD%20Scripts/groupmember.ps1:7) char:1

    + Get-ADGroupMember vpn_terminal_access | Foreach-object{

    [Get-ADGroupMember], TimeoutException

    You have network or AD issues.  Fix the problem. It is not a scripting issue.


    ¯\_(ツ)_/¯

    Tuesday, April 29, 2014 12:04 PM
  • Actually i don't wanted to mention our companies group name. So i changed it to ABC. Nothing else is edited.

    I am using powershell V3. all members are in one domain and one forest. there are around 2000 users in this group.

    Tuesday, April 29, 2014 12:13 PM
  • I have gone through few blog's where they say that LDAP query is for 2 mints max. And powershell Active directory module is heavy.

    So, Now i am using

    dsget group "CN=vpn_terminal_access,OU=Pune-SG,OU=All-SG,DC=persistent,DC=co,DC=in" -members | dsget user -email

    This cmd line. This gives the output but STOPS if any macting is not found. I want to continue this script even if any error occurs it should by pass it and move forward. (just like -erroraction silentlycontinue in powershell ).

    How can do this ?

    Tuesday, April 29, 2014 12:53 PM
  • Do you still get a timeout if you do a simple Get-ADGroupMember -Identity ABC?

    Don't retire TechNet! - (Don't give up yet - 12,830+ strong and growing)

    Tuesday, April 29, 2014 12:55 PM
  • Please read the error message carefully.  It tells you the exact problem:

    ERROR :-

    At D:\All Scripts\AD Scripts\groupmember.ps1:7 (file:///D:/All%20Scripts/AD%20Scripts/groupmember.ps1:7) char:1

    + Get-ADGroupMember vpn_terminal_access | Foreach-object{

    [Get-ADGroupMember], TimeoutException

    You have network or AD issues.  Fix the problem. It is not a scripting issue.


    ¯\_(ツ)_/¯

    [Get-ADGroupMember], TimeoutException

    ¯\_(ツ)_/¯

    Tuesday, April 29, 2014 4:04 PM
  • I have gone through few blog's where they say that LDAP query is for 2 mints max. And powershell Active directory module is heavy.

    So, Now i am using

    dsget group "CN=vpn_terminal_access,OU=Pune-SG,OU=All-SG,DC=persistent,DC=co,DC=in" -members | dsget user -email

    This cmd line. This gives the output but STOPS if any macting is not found. I want to continue this script even if any error occurs it should by pass it and move forward. (just like -erroraction silentlycontinue in powershell ).

    How can do this ?

    This tells you you have a problem.

    AD CmdLets and DSGET use exactly the same API.  You have an issue with your AD Domain.  You need to fix your issue.


    ¯\_(ツ)_/¯

    Tuesday, April 29, 2014 4:07 PM
  • You can have issues with Get-ADGroupMember on large groups.

    Try the following workaround...

    (Get-ADGroup "vpn_terminal_access" -properties members).members | Get-ADUser -properties emailaddress | 
    Select-Object Name, emailaddress | Export-CSV ".\results.csv" -noType

    Tuesday, April 29, 2014 4:28 PM
  • I have not tried this. let me try this.

    Wednesday, April 30, 2014 5:15 AM
  • Hi,

    This one working correctly. Thanks a lot.

    So, This means the Foreach-object takes a long time ?

    Wednesday, April 30, 2014 7:53 AM
  • It's not a problem with the loop, but with Get-ADGroupMember.

    However, usually, the limit is around 5000 users in a group before you start getting issues.

    The members field of Get-ADGroup is basically a string, but when sent through the pipe to Get-ADUser its sent one entry at a time, which gets around the performance issue.

    Wednesday, April 30, 2014 12:48 PM
  • Unfortunately that is not why it works.  It is almost the exact opposite that is true.

    The outer loop is held open longer on the Get-AdGroupMember. Apparently when this exceeds the timeout the loop fails.

    The working code is actually shorthand for this:

    $members=Get-ADGroup "vpn_terminal_access" -properties members
    $members | 
         Get-ADUser -properties emailaddress | 
         Select-Object Name, emailaddress | 
         Export-CSV ".\results.csv" -noType

    By getting allmembers first it avoids the delay in the middle of the loop.

    It has nothing to so with the speed of PowerSHell of loops.  It is the additive effect of getting each memner in the pipeline.  Using the implied subexpression evaluation ().members forces the members tobepulled first which is slightly faster.

    $members=...
    and
    (Get-Ad...).members

    Are identical.  The second is shorthand for the first.


    ¯\_(ツ)_/¯

    Wednesday, April 30, 2014 4:36 PM
  • (Get-ADGroup "vpn_terminal_access" -properties members).members

    I thought the above just brought back the single attribute, which is basically a comma delimited string (showing the distinguishedname of each member).

    Where as Get-ADGroupMember brings back the full account details for each member (all in one hit).

    Piping the string which contains the distinguishednames into  Get-ADUser basically runs the command once for each entry, and avoids the performance issues.

    Thursday, May 1, 2014 9:19 AM
  • (Get-ADGroup "vpn_terminal_access" -properties members).members

    I thought the above just brought back the single attribute, which is basically a comma delimited string (showing the distinguishedname of each member).

    Where as Get-ADGroupMember brings back the full account details for each member (all in one hit).

    Piping the string which contains the distinguishednames into  Get-ADUser basically runs the command once for each entry, and avoidsG

    the performance issues.

    No.  That brings back an array of DN Principal Objects.

    It is faster to do this:

    $members=Get-AdGroupMember <groupname>

    Once you have the collection you can use it easily because it is in memory.

    This:

    $members |  Get-ADUser

    Will get all user objects using the member DNs BUT "what does Get-AdGroupMember return?  Have you looked at that yet?


    ¯\_(ツ)_/¯



    • Edited by jrv Thursday, May 1, 2014 11:13 AM
    Thursday, May 1, 2014 10:00 AM
  • For the sake of argument review this:

    PS C:\scripts> $g=Get-ADGroupMember testgrp
    PS C:\scripts> $g[0]
    
    
    distinguishedName : CN=Domain Admins,CN=Users,DC=KAHLNET,DC=local
    name              : Domain Admins
    objectClass       : group
    objectGUID        : 85e96c8c-35a5-4895-90b7-25134bceba0a
    SamAccountName    : Domain Admins
    SID               : S-1-5-21-1997746983-321388823-153608166-512
    
    
    
    PS C:\scripts> $g[0].GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     False    ADPrincipal                              Microsoft.ActiveDirectory.Management.ADObject
    
    
    PS C:\scripts> $g[0]|select *
    
    
    distinguishedName  : CN=Domain Admins,CN=Users,DC=KAHLNET,DC=local
    name               : Domain Admins
    objectClass        : group
    objectGUID         : 85e96c8c-35a5-4895-90b7-25134bceba0a
    SamAccountName     : Domain Admins
    SID                : S-1-5-21-1997746983-321388823-153608166-512
    WriteDebugStream   : {}
    WriteErrorStream   : {}
    WriteVerboseStream : {}
    WriteWarningStream : {}
    PropertyNames      : {distinguishedName, name, objectClass, objectGUID...}
    PropertyCount      : 11
    It never hurts to inspect you work more closely until you really know the answers.


    ¯\_(ツ)_/¯

    Thursday, May 1, 2014 10:03 AM
  • Sorry I poste that it was an array of strings.  I fixed the post.  It is an array of Principal objects.

    The important this is to inspect any object that you are not sure of.

    Returning  principal is assumed because most other CmdLets consume Principal objects in the pipeline.


    ¯\_(ツ)_/¯

    Thursday, May 1, 2014 11:15 AM
  • I understand that Get-ADGroupMember brings back six properties for each user, which as you mentioned is the standard principal objects that Get-ADUser also uses.  This means that the command has to query each user to bring back these details, as these are not contained in the group in AD.  It has to go and find these attributes from each users account.  (For groups with 2000+ users, this can take some time).

    I'm guessing that most of the times you want further attributes, like displayname, or emailaddress, which means you have to pipe into Get-ADUser to retrieve those details anyway.

    Therefore I would have thought that you are better to bring back the members array via Get-ADGroup which will be quicker than Get-ADGroupMember.  The array exists on the property of the group.  One attribute to pull back.  I thought this was the reason that the command worked more efficiently.

    I might be missing the point here though.... :-)


    Thursday, May 1, 2014 11:43 AM
  • Doesn't matter. The user principal is very easy to get.  It is the embedded Get-AdUser that is time consuming because it mkes Get-AdGroupMember wait on every member.  If any member is in another domain and the network is slow it can cause a timeout. 

    Yes= Using Get-ADGroup would be faster but it, too, returns an array of strings and NOT a comma delimited list.

    Under most circumstances the difference is trivial.  If the domains are remote then this is an issue.  One more reason to not place users in a group when remote. Place them in a group and place the group in the group.  Overall performance for everything is better and more reliable.  That is why it is designed that way.  In NT4 this was not as easy so NT4 was prone to this kind of failure. Too often Admins just add users to local groups when they are remote. They then complain about performance. It can very badly impact logon performance.

    Notice that this is a collection (array):

    PS C:\scripts> (Get-AdGroup testgrp -prop members).members.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     False    ADPropertyValueCollection                System.Collections.CollectionBase
    For this property only it is a collection of strings. It can be a collection of any "ValueType"


    ¯\_(ツ)_/¯"



    • Edited by jrv Thursday, May 1, 2014 12:10 PM
    • Marked as answer by Amitkumar_Patil Friday, May 2, 2014 7:17 AM
    Thursday, May 1, 2014 12:08 PM
  • Thanks experts for the discussion.

    Concept is clear for me.

    You guys are excellent. I am marking it as answer.

    Friday, May 2, 2014 7:17 AM
  • It works, Helped me. Thank you
    • Proposed as answer by tramesh Friday, September 9, 2016 12:30 PM
    • Unproposed as answer by Bill_StewartModerator Friday, September 9, 2016 2:11 PM
    Friday, September 9, 2016 12:29 PM
  • I find this even simpler if you just want the members in a variable for example:

    $Variable=Get-ADGroup 'Group_Name' -Properties Members | select -ExpandProperty members | % { Get-ADObject $psitem }

    in Get-ADObject you may want to include som extra properties if you need.

    Thursday, December 7, 2017 12:18 PM