• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 419
  • Last Modified:

Edit AD Users name properties

My AD users currently have no entry in 'First Name' or 'Last Name', just an entry in 'Display Name' . Is it possible to script splitting the display name into the First\Last name parts and putting them in the correct fields? Crazy I know.
0
Pete
Asked:
Pete
  • 18
  • 16
  • 4
  • +1
1 Solution
 
bluntTonyCommented:
Below is the bones of what you need.
Change strBase to the DN of the OU holding the users you want to change. I think it's probably safer to specificy and OU rather than your domain as there's lots of other user accounts you wouldn't want to change. If you have an OU structure and want to change all users down the tree, specify the top OU, and change strScope to 'subtree'.
If you want to just show what users you're about the change, uncomment the 'Wscript.Echo...' line and comment out the 'objUser.SetInfo' line. This will just show you what users will be changed...

strBase   =  "<LDAP://[ENTER DN OF OU HERE!!!]>;"
strFilter = "(&(objectclass=user)(objectCategory=person));" 
strAttrs  = "distinguishedName;"
strScope  = "onelevel"
 
Set objConn = CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOObject"
objConn.Open "Active Directory Provider"
Set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope)
 
objRS.MoveFirst
While Not objRS.EOF
	Set objUser = GetObject("LDAP://" & Replace(objRS.Fields(0).Value,"/","\/"))
	WScript.Echo objUser.displayName
	If Not objUser.DisplayName = "" Then
		objUser.sn = Mid(objUser.displayName,InStr(objUser.displayName," ")+1)
		objUser.givenName = Left(objUser.displayName,InStr(objUser.displayName," ")-1)
		'WScript.Echo "Will be changing " & objUser.displayName
		objUser.SetInfo
	End if
	objRS.MoveNext
Wend

Open in new window

0
 
bluntTonyCommented:
This is VB script incidentally. Save it as a vbs and call it from the command line, e.g.
cscript changeusers.vbs
0
 
JBlondCommented:
http://support.microsoft.com/kb/300427

That script seems to do exactly what you want.
0
Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

 
Chris DentPowerShell DeveloperCommented:

I made a little PowerShell version as well, I figure I'll post it for interest even if it's a bit late ;)

It would need these two:

http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx
http://www.quest.com/activeroles-server/arms.aspx

Code below :)

Chris
$FromOU = "OU=somewhere,DC=domain,DC=com"
Get-QADUser -SearchRoot $FromOU -LdapFilter "(&(!givenName=*)(!sn=*)(displayName=*))" | %{
  $Names = $_.DisplayName.Split(" ")
  If ($Names.Count -gt 1) {
    $FirstName = $Names[0]; $LastName = $Names[$Names.Count - 1]
    Set-QADUser $_.DN -FirstName $FirstName -LastName $LastName
  }
}

Open in new window

0
 
bluntTonyCommented:
I really must learn Powershell :0)
0
 
PeteAuthor Commented:
What happens to the 'space' bewteen the first and last name in the 'display name' field? does it get removed?
0
 
bluntTonyCommented:
In my script, it does remove it, or more precisely it doesn't pass it into neither the first or last name. It gets the text either side.
By the way, it assumes the displayName format 'First Last', rather then 'Last First'
0
 
Chris DentPowerShell DeveloperCommented:

Mine takes a name like this:

Chris David Dent

Splits it based on the space, turning it into a list:

Chris
David
Dent

Then it grabs the first and last value so we have this (without the quotes):

$FirstName: "Chris"
$LastName: "Dent"

The MS script in the KB article uses almost exactly the same approach but in VbScript.

Chris
0
 
PeteAuthor Commented:
I am testing Chris Dent's solution as it seems simpler, I have changed OU and Domain to my setup but powershell is coming back with:
"Get-QADUser is not recognised as a cmdlet function........... "

0
 
Chris DentPowerShell DeveloperCommented:

You'll need to either run this:

Get-PSSnapIn -Reg | Add-PSSnapIn -EA 0

Or run the shortcut for PowerShell active roles from the quest folder.

As soon as it has the snap-in loaded it should work :)

Chris
0
 
PeteAuthor Commented:
Thanks, this worked perfectly.
0
 
PeteAuthor Commented:
Running that Get-PSSnapIn -Reg | Add-PSSnapIn -EA 0 command works but only until the powershell window is closed and re-opened, then it goes back to the same unknown command error message, is this right? can't I get those tools\commands installed permanently?
 
0
 
Chris DentPowerShell DeveloperCommented:

Yes it's right.

You can tell it to add the snap in as you load the shell (which is what the Quest version of the shortcut does). Or you can set a startup script for PowerShell to execute that command, adding in the snap-in.

I use the startup script myself. If you want to do the same it goes here:

C:\windows\system32\windowspowershell\v1.0

And should be saved as "profile.ps1". My script is below.

You may also have to run this command (once only, it remembers this one) to allow it to run the startup script:

Set-ExecutionPolicy Unrestricted

Changing the title is because I prefer to test things with my regular user, it's no fun to accidentally "test" something while running as an administrative user :)

Chris
$Host.UI.RawUI.WindowTitle = "PowerShell - Running as: $Env:Username"
$Host.UI.RawUI.BackgroundColor = "DarkGray"
$Host.PrivateData.ErrorBackgroundColor = "DarkGray"
$Host.PrivateData.WarningBackgroundColor = "DarkGray"
$Host.PrivateData.DebugBackgroundColor = "DarkGray"
$Host.PrivateData.VerboseBackgroundColor = "DarkGray"
$Host.PrivateData.ProgressBackgroundColor = "DarkBlue"
 
Get-PSSnapIn -Registered | Add-PSSnapin -ErrorAction "SilentlyContinue"
 
Write-Host "Loaded with SnapIns:`n"
Get-PSSnapIn | Sort-Object -Property Name | %{ Write-Host $_.Name }
Write-Host

Open in new window

0
 
PeteAuthor Commented:
Thanks, that worked - great!
0
 
PeteAuthor Commented:
Chris-Dent I hope you can help me with a slight ammendment my student users have the display name the other way round (lastname firstname) so what I would like to do is run the script to the first part goes to last name and the first part to last name, can you post an ammended script please?
As a final cleanup I suppose I would like to then change the display name the correct way round of firstname lastname.
Grateful of any advice.
0
 
Chris DentPowerShell DeveloperCommented:

Sure.

For your students we could do this. Which sets first and last name and corrects display name.

Do they also appear by that name (lastname firstname) in AD Users and Computers? Did you want to change that value as well? It'll need a bit more.

Chris
$FromOU = "OU=thestudentsOU,DC=domain,DC=com"
Get-QADUser -SearchRoot $FromOU -LdapFilter "(&(!givenName=*)(!sn=*)(displayName=*))" | %{
  $Names = $_.DisplayName.Split(" ")
  If ($Names.Count -gt 1) {
    $FirstName = $Names[$Names.Count - 1]; $LastName = $Names[0]
    Set-QADUser $_.DN `
      -FirstName $FirstName `
      -LastName $LastName `
      -DisplayName "$FirstName $LastName"
  }
}

Open in new window

0
 
PeteAuthor Commented:
That works perfectly thanks but I have just found that some of the users have double spaces between their first\last in their display name....so, last thing prior to running the script above is there something I can script "If there's a double space, then remove one of the spaces"..or something?
thanks for all this help...nearly there!
0
 
Chris DentPowerShell DeveloperCommented:

Might be quicker to just rewrite the display name for all of them.

At the moment the version above will strip out additional spaces for the Students (because of how it puts the name back). This modification does the same for your other users.

I haven't accounted for anyone that has a middle name or initial. Do I need to?

Chris
$FromOU = "OU=somewhere,DC=domain,DC=com"
Get-QADUser -SearchRoot $FromOU -LdapFilter "(&(!givenName=*)(!sn=*)(displayName=*))" | %{
  $Names = $_.DisplayName.Split(" ")
  If ($Names.Count -gt 1) {
    $FirstName = $Names[0]; $LastName = $Names[$Names.Count - 1]
    Set-QADUser $_.DN `
      -FirstName $FirstName `
      -LastName $LastName `
      -DisplayName "$FirstName $LastName"
  }
}

Open in new window

0
 
PeteAuthor Commented:
Sorry, just to clarify will the script above delete any double spaces in the display names?
I ran the last script (2 posts ago) on a year group and it put a space in the first name box hence I lost all my first names and had to type them back in manually.
when you say "Might be quicker to just rewrite the display name for all of them". how would I rewrite them...manually? there's still 4 year groups to go.
0
 
Chris DentPowerShell DeveloperCommented:

> Sorry, just to clarify will the script above delete any double spaces in the display names?

Yes, it overwrites the existing value for display name with a newly constructed one.

Lets just test that Student script. It doesn't make any changes this time, just tells us about what it finds.

If all of them have values in First Name and Last Name now we'll want to change our LDAP Filter. Previously it was looking for everyone that didn't have First Name and Last Name set.

Chris
$FromOU = "OU=thestudentsOU,DC=domain,DC=com"
# Filter to find users with no first name, no last name but with a display name
# Get-QADUser -SearchRoot $FromOU -LdapFilter "(&(!givenName=*)(!sn=*)(displayName=*))" | %{
# Filter to find all users in $FromOU with a display name set
Get-QADUser -SearchRoot $FromOU -LdapFilter "(displayName=*)" | %{
  $Names = $_.DisplayName.Split(" ")
  If ($Names.Count -gt 1) {
    $FirstName = $Names[$Names.Count - 1]; $LastName = $Names[0]
    #Set-QADUser $_.DN `
    #  -FirstName $FirstName `
    #  -LastName $LastName `
    #  -DisplayName "$FirstName $LastName"
    Write-Host "Setting the following values for $($_.DN) : " + `
      "First Name: $FirstName Last Name: $LastName Display Name: $FirstName $LastName"
  }
}

Open in new window

0
 
PeteAuthor Commented:
sorry no one has a value in first name or last name the only entry is still only display name, the only thing that has chnaged is that I've noticed some of the users have a double space between their display name:
eg-
Smith  John
So the double space needs to be changed to a single space then the script below will work. I do like the idea of testing the change before implementing though.

$FromOU = "OU=thestudentsOU,DC=domain,DC=com"
Get-QADUser -SearchRoot $FromOU -LdapFilter "(&(!givenName=*)(!sn=*)(displayName=*))" | %{
  $Names = $_.DisplayName.Split(" ")
  If ($Names.Count -gt 1) {
    $FirstName = $Names[$Names.Count - 1]; $LastName = $Names[0]
    Set-QADUser $_.DN `
      -FirstName $FirstName `
      -LastName $LastName `
      -DisplayName "$FirstName $LastName"
  }
}

Open in new window

0
 
Chris DentPowerShell DeveloperCommented:

Right, lets get this sorted out :)

This little snippet will make us a new "object" that contains the current Display Name and what the script wants to change things to.

We'll tweak it then import the finished thing into the accounts once we're sure.

Note the comments (a comment is preceded by #) around the part it creates the names, we have two versions, one for Students, and one for everyone else. We'd just uncomment the one we need to use, Students at the moment.

Just to be totally clear. This snippet makes no changes to AD.

Chris
$NewNames = @()
$FromOU = "OU=thestudentsOU,DC=domain,DC=com"
Get-QADUser -SearchRoot $FromOU `
  -LdapFilter "(&(!givenName=*)(!sn=*)(displayName=*))" | %{
    $Names = $_.DisplayName.Split(" ")
    If ($Names.Count -gt 1) {
      # For Students (Imports from "LastName FirstName")
      $FirstName = $Names[$Names.Count - 1]; $LastName = $Names[0]
      # For everyone else (Imports from "FirstName LastName")
      # $FirstName = $Names[0]; $LastName = [$Names.Count - 1]
 
      $NewNames += $_ | Select-Object DisplayName, `
        @{n='NewFirstName';e={ $FirstName }}, `
        @{n='NewLastName';e={ $LastName }}, `
        @{n='NewDisplayName';e={ "$FirstName $LastName" }}, DN
    }
}
$NewNames | Format-Table

Open in new window

0
 
PeteAuthor Commented:
great, i am on bank hol but will try tomorrow. do i copy the results to a .txt file?
thanks for all your continued help with this. only 2 year groups to go now! i will run the script on each year group and see what the results are.
 
 
0
 
PeteAuthor Commented:
the script runs but where does it output to please?
 
Thanks
0
 
Chris DentPowerShell DeveloperCommented:

The script above only outputs to the screen, but you can have it output to a file if you prefer by tagging this on the bottom:

$NewNames | Export-CSV "SomeCSVFile.csv"

Chris
0
 
PeteAuthor Commented:
sorry, I have worked something out for myself (!) and outputted to a txt file on c.
the newfirstname and newlastname column appear fine on all the users. so finally what changes do I make to the script to actually edit, rather than query the AD?
 
Thanks
0
 
Chris DentPowerShell DeveloperCommented:

Excellent, that sounds good.

I added the DN (distinguished name) to a column, so we should be able to do this now:

$NewNames | %{
  Set-QADUser $_.DN `
      -FirstName $_.NewFirstName `
      -LastName $_.NewLastName `
      -DisplayName $_.NewDisplayName
}

It picks up the columns from the table we made for it, saves us having to make it figure out the names again.

Chris
0
 
PeteAuthor Commented:
sorry, last thing - how can I then change the OU the script is running on?
0
 
Chris DentPowerShell DeveloperCommented:

This one sets the OU:

$FromOU = "OU=Somewhere,OU=somewhereelse,DC=yourdomain,DC=com"

It can also be written in this format:

$FromOU = "yourdomain.com/Somewhereelse/Somewhere"

It doesn't matter which you use, just a case of which you find easiest. If you use the second, make sure you enter "/", it won't get it if you use the other slash.

If you want to test them to make sure it's returning the right thing you can run this on its own:

Get-QADUser -SearchRoot $FromOU -LdapFilter "(&(!givenName=*)(!sn=*)(displayName=*))"

That just runs the search and will drop the output to the screen (as we did with $NewNames). That can be used for reporting on things if you like, you can add a pipe to Export-CSV onto the end.

Chris
0
 
PeteAuthor Commented:
nearly there!
I don't understand how to run the final script on my remaining 2 x OU's, we have confirmed the script will edit the correct fields but please can you post the final command I need to run?
0
 
Chris DentPowerShell DeveloperCommented:

Popping it all together we get this. You don't have to run all of this in one go, the list it makes will be held in memory until you close the PowerShell prompt. So run Part 1, check it, then if you're happy, just paste in Part 2 afterwards.

Chris
# Enter the OU name you want to run the following commands on
$FromOU = "OU=thestudentsOU,DC=domain,DC=com"
 
# Part 1 - Making a list of the possible changes
# This section makes a list of all the changes the script would like to make
# Watch the ordering of FirstName and LastName, two options in the code below.
# The hash (#) is the comment character, add or remove the comment as appropriate
 
$NewNames = @()
Get-QADUser -SearchRoot $FromOU `
  -LdapFilter "(&(!givenName=*)(!sn=*)(displayName=*))" | %{
    $Names = $_.DisplayName.Split(" ")
    If ($Names.Count -gt 1) {
 
      # For Students (Imports from "LastName FirstName")
      $FirstName = $Names[$Names.Count - 1]; $LastName = $Names[0]
      # For everyone else (Imports from "FirstName LastName")
      # $FirstName = $Names[0]; $LastName = [$Names.Count - 1]
 
      $NewNames += $_ | Select-Object DisplayName, `
        @{n='NewFirstName';e={ $FirstName }}, `
        @{n='NewLastName';e={ $LastName }}, `
        @{n='NewDisplayName';e={ "$FirstName $LastName" }}, DN
    }
}
$NewNames | Format-Table
$NewNames | Export-CSV "NewNames.csv"
 
# Part 2 - Making the changes
 
# Don't run this part until you're happy with the values returned above.
# This is the bit that actually makes the change
$NewNames | %{
  Set-QADUser $_.DN `
      -FirstName $_.NewFirstName `
      -LastName $_.NewLastName `
      -DisplayName $_.NewDisplayName
}

Open in new window

0
 
PeteAuthor Commented:
still nearly there...
part1 runs as desired on my first OU but running part 2 in same powershell window:

Set-QADUser : The argument cannot be null or empty.
At line:2 char:14
+   Set-QADUser  <<<< $_.DN `

0
 
Chris DentPowerShell DeveloperCommented:

If you run $NewNames on its own do you get anything back? It's upset because the DN column appears to be empty for one or more values in that.

Chris
0
 
PeteAuthor Commented:
$NewNames just returns back to the C:\ powershell prompt, nothing is output to the screen.
0
 
Chris DentPowerShell DeveloperCommented:

Then the search failed to find anything. Run this line on it's own:

Get-QADUser -SearchRoot $FromOU -LdapFilter "(&(!givenName=*)(!sn=*)(displayName=*))"

That's the search we're running to find the users. If that doesn't return anything then NewNames won't have anything in it.

Chris
0
 
PeteAuthor Commented:
I get this running that line:
Get-QADUser : The argument cannot be null or empty.
At line:1 char:24
+ Get-QADUser -SearchRoot  <<<< $FromOU -LdapFilter "(&(!givenName=*)(!sn=*)(displayName=*))"
I also get nothing running: $FromOU
0
 
Chris DentPowerShell DeveloperCommented:

Did you set a value for it?

It was this line in the above (prior to Part 1):

# Enter the OU name you want to run the following commands on
$FromOU = "OU=thestudentsOU,DC=domain,DC=com"

Chris
0
 
PeteAuthor Commented:
Hooray!!! I had much better success copy\paste into powershell rather than running ps1 scripts.
Thanks so much for your efforts, you do indeed deserve the 'genius' rank!! ;)
 
0
 
Chris DentPowerShell DeveloperCommented:

You're welcome, glad we got there :)

Chris
0

Featured Post

Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

  • 18
  • 16
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now