Is there a better way to get AD group members for a given list of AD group ObjectGUIDs?
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
add a comment |
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
add a comment |
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
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
powershell
asked Dec 27 at 14:34
deano
126
126
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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
1
Also cache the result ofGet-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'sGet-ADGroupMember
list. Caching is done via global object of type dictionary, you then doif {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...}
and then addressdic[$_.samaccountname]
instead of always callingGet-ADUser
.
– Vesper
2 days ago
|
show 1 more comment
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
1
Also cache the result ofGet-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'sGet-ADGroupMember
list. Caching is done via global object of type dictionary, you then doif {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...}
and then addressdic[$_.samaccountname]
instead of always callingGet-ADUser
.
– Vesper
2 days ago
|
show 1 more comment
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
1
Also cache the result ofGet-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'sGet-ADGroupMember
list. Caching is done via global object of type dictionary, you then doif {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...}
and then addressdic[$_.samaccountname]
instead of always callingGet-ADUser
.
– Vesper
2 days ago
|
show 1 more comment
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
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
answered Dec 27 at 15:08
LotPings
17.5k61532
17.5k61532
1
Also cache the result ofGet-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'sGet-ADGroupMember
list. Caching is done via global object of type dictionary, you then doif {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...}
and then addressdic[$_.samaccountname]
instead of always callingGet-ADUser
.
– Vesper
2 days ago
|
show 1 more comment
1
Also cache the result ofGet-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'sGet-ADGroupMember
list. Caching is done via global object of type dictionary, you then doif {dic[$_.samaccountname] -eq $null} {dic[$_.samaccountname]=Get-ADUser $_.objectGUID ...}
and then addressdic[$_.samaccountname]
instead of always callingGet-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
|
show 1 more comment
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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