D.Losyankov
D.Losyankov

Reputation: 11

Get UPN from Get-ADGroupMember

I have a task to get userPrincipalName attribute from users who are in several groups in our multiple-domain AD forest.

The problem is that I can't use Select-Object to get a user's UPN from Get-ADGroupMember because this cmdlet only returns a limited number of properties (samaccountname, name, SID and DN), and UPN isn't one of them.

I wrote this code (get "name" and than search UPN by "name"):

    $ScriptPath = Split-Path $MyInvocation.MyCommand.Path
    $LocalSite = (Get-ADDomainController -Discover).Site
    $NewTargetGC = Get-ADDomainController -Discover -Service 6 -SiteName 
    $LocalSite
    IF (!$NewTargetGC)
    { $NewTargetGC = Get-ADDomainController -Discover -Service 6 -NextClosestSite }
    $NewTargetGCHostName = $NewTargetGC.HostName
    $LocalGC = “$NewTargetGCHostName” + “:3268”

    $domains = (Get-ADForest).domains
    $MembersOfSFDC_Groups = foreach ($domain in $domains) {
    $Group = Get-ADGroup -Filter { Name -like "*groupname*" } -Server $Domain 
    $Group | Get-ADGroupMember -Server $domain | Select @{
    Name="Domain";Expression={$Domain}},@{
    Name="Group";Expression={$Group.Name}}, name}

    $DisplayNames = $MembersOfSFDC_Groups.name
    $DisplayNames |Out-file (Join-Path $ScriptPath 'DisplayNames.txt')

    Get-content (Join-Path $ScriptPath 'DisplayNames.txt') |
    $displaynames | ForEach-Object {
    Get-ADUser -Server $LocalGC -Filter {Name -eq $_}  | 
    Select-Object -Property userPrincipalName} | 
    Out-File (Join-Path $ScriptPath 'upnOfSDFC_AD_GroupsMembers.txt')

But next problem is that this code is running about 30 min (Measure-Command cmdlet). We have a huge number of users across multiple domains.

My question is how to improve my code to get user's UPN more faster?

I know about System.DirectoryServices.DirectorySearcher, but don't know how to implementing this method with my txt-file (list of "names").

Any help will be much appreciated.

Upvotes: 1

Views: 27657

Answers (3)

speed_racer
speed_racer

Reputation: 45

You can actually get it from one line of code. Simples... :)

Get-ADGroupMember -Identity "group name" |%{get-aduser $_.SamAccountName | select userPrincipalName } > c:\scripts\upnofADgroup.txt

Upvotes: 3

D.Losyankov
D.Losyankov

Reputation: 11

Ok, guys, I'v got it:

  function Get-DomainFromDN ($param)
  {   
  $dn1 = $param -split "," | ? {$_ -like "DC=*"}
  $dn2 = $dn1 -join "." -replace ("DC=", "")
  $script:test = $dn2
  return $dn2
  }

foreach ($Group in $Groups) {
$Members = Get-ADObject -LDAPFilter "(&(objectCategory=user)(memberOf=$($Group.DistinguishedName)))" -Properties UserPrincipalName -Server (Get-DomainFromDN ($group.DistinguishedName))
$UPN_Of_SFDC_Groups += $Members |Select-Object UserPrincipalName }

$UPN_Of_SFDC_Groups | Out-file (Join-Path $ScriptPath 'upnOfSDFC_AD_GroupsMembers.txt')

Upvotes: 0

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174690

Fastest approach is probably avoiding Get-ADGroupMember altogether, and just search for the group, and then search for objects that are members of that group:

$Group = Get-ADGroup -Filter { Name -like "*groupname*" } -Server $Domain 
$Members = Get-ADObject -LDAPFilter "(memberOf=$($Group.DistinguishedName))" -Properties UserPrincipalName
$Members |Select-Object UserPrincipalName |Out-File (Join-Path $ScriptPath 'upnOfSDFC_AD_GroupsMembers.txt')

Now you're down to 2 queries, rather than 2 + N (where N is the number of members)

Upvotes: 0

Related Questions