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.
janhoedtAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

janhoedtAuthor Commented:
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
0
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
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

0
janhoedtAuthor Commented:
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

0
How the Cloud Can Help You as an MSSP

Today, every Managed Security Service Provider (MSSP) needs a platform to deliver effective and efficient security-as-a-service to their customers. Scale, elasticity and profitability are a few of the many features that a Cloud platform offers. Register today to learn more!

Jeremy WeisingerSenior Network Consultant / EngineerCommented:
Is there anything we can know about the data in the text file? There's no way to distinguish between middlename and multi part surname but if we know there are no middle names we can deal with it.

Another option would be look through and match based on first and last to see if that's unique enough. Something like this:

$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) {
                           $firstnameFilter = "*" + ($user.split(' ')[0]) + "*"
                           $familyname = $user.split(' ') | select -Last 1
                           $familynameFilter = "*" + $familyname + "*"
                           
                           #if familynamenamefirst $name = "$familyname $firstname" else $name = "$firstname $familyname"
                           Get-ADUser -Filter {givenname -like $firstname -and surname -like $familynameFilter} | select -ExpandProperty samaccountname
}

Open in new window

0
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
If we know that there's no middle name then you can use this to make the surname:

$familyname = $user.split(' ')
$namecount = $familyname.count - 1
$familyname = $familyname[1..$namecount] -join " "

Open in new window

1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
janhoedtAuthor Commented:
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

0
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
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

1
janhoedtAuthor Commented:
Solved it this way

  $familyname = $familyname[1..$namecount]
  $familyname = $($familyname -join (' ')).trim()
0
janhoedtAuthor Commented:
Note: why use wildcard? Want an exact result.
0
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
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.
0
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
Glad to help. :)
0
janhoedtAuthor Commented:
One more thing: What if you put family name first? How would you approach it then?
0
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
Which are you referring to? The list or the display name?
0
janhoedtAuthor Commented:
DisplayName
I d like to make this work:
#if familynamenamefirst $name = "$familyname $firstname" else $name = "$firstn...
0
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
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

1
janhoedtAuthor Commented:
Thanks! Problem though is again the family names consisting of multiple parts ....
0
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
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.
1
janhoedtAuthor Commented:
Not sure I'm getting what you are saying.
The function needs the parameters -lastnamefirstname for reversing the logic right?
0
Jeremy WeisingerSenior Network Consultant / EngineerCommented:
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

1
janhoedtAuthor Commented:
Let me check what is actually doing in powershell.I ll understand beter then.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.