Avatar of janhoedt
janhoedt
 asked on

Powershell: Add users to group from list surname givenname

Hi,

I need to add users to an ad group based upon a list a user provide me. Of course in a format which is useless to me:
surname givenname
surname givenname
...

How can I convert this into samaccountnames so I can easily add the users to a group?

Please advise.
J.
PowershellActive Directory

Avatar of undefined
Last Comment
janhoedt

8/22/2022 - Mon
janhoedt

ASKER
Got something here but would appreciate input.

$users = Get-Content 'C:\userstoadd.txt'
$users
#remove whitespaces in front and at then end, then also make sure there is
#only one whitespace between  family name and firstname (family name is also sometimes more then one or even two words)
#then need to get $lastname and $firstname of each of the users and it should not stop when it does not find the user
#maybe even suggest a name in case it doesn't find the user (spelled differently) but that's a next level wish :-)

Get-ADUser -Filter "Name -like '*$lastname*'" -Properties * | Where {($_.Surname -eq $lastname) -and (($_.GivenName -eq $firstName) -or ($_.DisplayName -like "*$firstname*")) } | Select samAccountName
Jeremy Weisinger

If the list matches AD then you can do something simple like this:

$userlist = "C:\userlist.txt"
Get-Content $userlist | %{Get-ADUser -Filter {name -eq $_}} | select -ExpandProperty samaccountname

Open in new window

janhoedt

ASKER
Got somewhere now, commented what my problem is = selecting family name because it can exist of multiple parts.
Thanks for your input.

$file = 'C:\userlist.txt'
#Remove whitespaces
#The first parameter to -replace is a regular expression pattern to match, and the second parameter is the text that will replace any matches.  \s will match a whitespace character, and + indicates to match one or more occurrences, so, in other words, one or more adjacent whitespace characters will be replaced with a single space. Enter help about_comparison_operators or see here for more information.
$users = (Get-Content $file) | ForEach-Object { $PSItem -replace '\s+', ' ' }

#option familyname first or firstname first
foreach ($user in $users) {
                           $firstname = $user.split(' ')[0]
                           $familyname = $user.split(' ')[1] #PROBLEM HERE IS THAT USER SOMETIMES EXISTS OF 2, 3 OR MORE NAMES f.e. Erica Van Den Bossche, John Wrest Chesterburgh
                           
                           #if familynamenamefirst $name = "$familyname $firstname" else $name = "$firstname $familyname"
                           Get-ADUser -Filter {displayname -like "$familyname $firstname"} | select -ExpandProperty samaccountname
}

Open in new window

Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
SOLUTION
Jeremy Weisinger

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
ASKER CERTIFIED SOLUTION
Jeremy Weisinger

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
janhoedt

ASKER
Great thanks! Would you mind clarifying what you are doing there?

Got it partially working now, however, however, some of the users do not resolve because of a comma in the

FirstName  FamilyName         SamAccountame
---------  ----------         -------------
John      {Doe, }                  
Eric        {Whatever, }                    
Wendy      {Ericsson}        wericsson
 Guido      {For,Ever}        

Appreciate your input!

#option familyname first or firstname first
$result = @()
foreach ($user in $users) 
{
  $firstname = $user.split(' ')[0]
  $familyname = $user.split(' ')
  $namecount = $familyname.count - 1
  $familyname = $familyname[1..$namecount]
                            
  #if familynamenamefirst $name = "$familyname $firstname" else $name = "$firstname $familyname"
  $UserDisplayNameToLookFor = "$familyname $firstname"
                                      
  $samaccountame = Get-ADUser -Filter {
    displayname -like $UserDisplayNameToLookFor
  } | Select-Object -ExpandProperty samaccountname
  
  $result += [pscustomobject]@{
    FirstName         = $firstname
    FamilyName = $familyname
    SamAccountame = $samaccountame
    
  }
}

Open in new window

Jeremy Weisinger

You can use wildcards and/or filter on the givenname and surname properties.

Wildcard against the Displayname:
#option familyname first or firstname first
$result = @()
foreach ($user in $users) 
{
  $firstname = $user.split(' ')[0]
  $familyname = $user.split(' ')
  $namecount = $familyname.count - 1
  $familyname = $familyname[1..$namecount]
                            
  #if familynamenamefirst $name = "$familyname $firstname" else $name = "$firstname $familyname"
  $UserDisplayNameToLookFor = "*$familyname $firstname*"
                                      
  $samaccountame = Get-ADUser -Filter {
    displayname -like $UserDisplayNameToLookFor
  } | Select-Object -ExpandProperty samaccountname
  
  $result += [pscustomobject]@{
    FirstName         = $firstname
    FamilyName = $familyname
    SamAccountame = $samaccountame
    
  }
}

Open in new window

Wildcard against the given name and surname:
#option familyname first or firstname first
$result = @()
foreach ($user in $users) 
{
  $firstname = $user.split(' ')[0]
  $gnfilter =  "*" + $firstname + "*"
  $familyname = $user.split(' ')
  $namecount = $familyname.count - 1
  $familyname = $familyname[1..$namecount]
                            
  #if familynamenamefirst $name = "$familyname $firstname" else $name = "$firstname $familyname"
  $snfilter = "*$familyname*"
                                      
  $samaccountame = Get-ADUser -Filter {
    givenname -like $gnfilter -and surname -like $snfilter
  } | Select-Object -ExpandProperty samaccountname
  
  $result += [pscustomobject]@{
    FirstName         = $firstname
    FamilyName = $familyname
    SamAccountame = $samaccountame
    
  }
}

Open in new window

janhoedt

ASKER
Solved it this way

  $familyname = $familyname[1..$namecount]
  $familyname = $($familyname -join (' ')).trim()
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
janhoedt

ASKER
Note: why use wildcard? Want an exact result.
Jeremy Weisinger

If you specify the name with the wildcard surrounding it, that still has to match the whole string but will allow for preceding and trailing characters that are not part of the name like a space or a comma.
Jeremy Weisinger

Glad to help. :)
Your help has saved me hundreds of hours of internet surfing.
fblack61
janhoedt

ASKER
One more thing: What if you put family name first? How would you approach it then?
Jeremy Weisinger

Which are you referring to? The list or the display name?
janhoedt

ASKER
DisplayName
I d like to make this work:
#if familynamenamefirst $name = "$familyname $firstname" else $name = "$firstn...
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Jeremy Weisinger

Well you could just reverse the order in your script or if you need to check for both use an -or operator and match against both. But I would not even bother with the display name. Filter against the givenname and surname (as I was doing) and then the displayname doesn't matter.

  $samaccountame = Get-ADUser -Filter {
    givenname -like $firstname -and surname -like $familyname
  } | Select-Object -ExpandProperty samaccountname

Open in new window

janhoedt

ASKER
Thanks! Problem though is again the family names consisting of multiple parts ....
Jeremy Weisinger

So is the family name not going to be entered in the surname/last name attribute? Event if it's multi part it should still match. The only issue is if it's in other attributes and not in the lastname field.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
janhoedt

ASKER
Not sure I'm getting what you are saying.
The function needs the parameters -lastnamefirstname for reversing the logic right?
Jeremy Weisinger

I'm saying to not look at the displayname at all. Look at the givenname (First name) and surname (Last name). So you don't need to know the order that the display name is in.

I've posted several variations on this:
  $samaccountame = Get-ADUser -Filter {
    givenname -like $firstname -and surname -like $familyname
  } | Select-Object -ExpandProperty samaccountname

Open in new window

Do you have any questions on what this is doing?

In this script the order of the display name doesn't matter. It will just look at the first and last name:
$result = @()
foreach ($user in $users) 
{
  $firstname = $user.split(' ')[0]
  $gnfilter =  "*" + $firstname + "*"
  $familyname = $user.split(' ')
  $namecount = $familyname.count - 1
  $familyname = $familyname[1..$namecount]
                            
  #if familynamenamefirst $name = "$familyname $firstname" else $name = "$firstname $familyname"
  $snfilter = "*$familyname*"
                                      
  $samaccountame = Get-ADUser -Filter {
    givenname -like $gnfilter -and surname -like $snfilter
  } | Select-Object -ExpandProperty samaccountname
  
  $result += [pscustomobject]@{
    FirstName         = $firstname
    FamilyName = $familyname
    SamAccountame = $samaccountame
    
  }
}

Open in new window

janhoedt

ASKER
Let me check what is actually doing in powershell.I ll understand beter then.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.