Updating Phone Numbers for Existing AD users

by jolson at 2013-03-01 14:58:02

We recently went through a domain migration. I need to export the phone numbers from one DC and import them to the existing users on the new DC.
I exported the numbers using PowerShell:
Get-AdUser -Filter * -Properties * | FT samAccountName,HomePhone,MobilePhone,OfficePhone > users.txt
I am trying to import the file using a script:
Import-Module ActiveDirectory
$users = $i = $null
$users = import-csv .\users.txt
ForEach($user in $users)
{

"modifying $($user.name)"

Set-ADUser -Identity $user.samAccountName -HomePhone $user.HomePhone -MobilePhone $user.MobilePhone -OfficePhone $user.OfficePhone
$i++

}

"modified $i users"


I get an error:
Set-ADUser : Cannot validate argument on parameter ‘Identity’. The argument is
null. Supply a non-null argument and try the command again.
At C:\Users\wgtadmin\update_users.ps1:10 char:25
+ Set-ADUser -Identity <<<< $user.SamAccountName -HomePhone $user.HomePhon
e -MobilePhone $user.MobilePhone -OfficePhone $user.OfficePhone
+ CategoryInfo : InvalidData: (:slight_smile: [Set-ADUser], ParameterBindingV
alidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Activ
eDirectory.Management.Commands.SetADUser



My users.txt:
SamAccountName HomePhone MobilePhone OfficePhone
test 1111111 2222222 3333333

The test account exists, just running this against a single user before applying to the entire OU. Why does the script pull a null value from the array? What changes need to be made to parse the file and update each user?
by jolson at 2013-03-01 15:00:20
I also tried this after loading the Quest cmdlets:
$phones = Import-Csv .\users2.txt
foreach ($phone in $phones) {
Get-QADUser -Identity $phone.SamAccountName | Set-QADUser -Identity $phone.SamAccountName -HomePhone $phone.HomePhone -MobilePhone $phone.MobilePhone -OfficePhone $phone.OfficeNumber
}
by DonJ at 2013-03-02 10:08:17
FYI: Don’t reply to your own post - a lot of us use the "view unanswered posts" feature to find questions that need answering, but when you post a reply, you don’t show up on that list ;).

So, the problem is that your Users.txt file is NOT a CSV, so Import-CSV isn’t interpreting it correctly. It is not creating a SamAccountName property, which is why $phone.SamAccountName is null. If you’re going to use Import-Csv, your data file needs a delimiter - a comma, by default, which is where CSV gets its name. Can you modify your input file to have commas?
by jolson at 2013-03-02 16:26:56
Thanks for the tip on posting/replying. I’ve also tried get-content on the file wth the same result. Would it be better to use the export-csv on the old DC? I had run export-clixml, but didn’t see an easy way to edit the file so only my test user would be modified. Another administrator has already manually entered the data, so now I’m going to be testing on the lab vm but I still want to solve the problem. What is the best way to get this content from one domain controller for import on another (disjoined) domain controller? I still have access to the old and pulling the appropriate data would be easier than adding commas to the file.

Don, the script’s loop is from one of your blog postings about adding a description to AD users. I appreciate all you do to help others learn PowerShell. I even watched some of your CBTs trying to figure this out. Going to finish that series so I’m not bagging groceries. Also working on my Month of Lunches.
by DonJ at 2013-03-02 16:35:09
Get-Content doesn’t attempt to parse or interpret the file at all. It just spews the raw text, which is essentially the same as Import-CSV is doing to you. The trick is that Import-CSV is only doing so because the file isn’t formatted as CSV. The file SHOULD look like:


SamAccountName,HomePhone,MobilePhone,OfficePhone
test,1111111,2222222,3333333


With commas separating each field. That’s a CSV file, regardless of the filename extension being TXT.

Yes, you could certainly derive the file by using Export-CSV on the old DC. Get-ADUser -Filter * -Property * | Export-CSV filename.csv would do the trick, provided the number of users didn’t exceed the command’s result set limit. You could change -Property from * to a comma-separated list of the properties you want. The samAccountName property will always be included.

You could POTENTIALLY use the file you have by running Import-CSV filename.txt -Delimiter ’ ' - notice that there is a single space between the quotation marks. This will work if NONE of your data elements contains a space. I’d run that command all by itself, from the console, as a test. You SHOULD get back an object for each data row in the file, and each object should have properties for SamAccountName, HomePhone, etc. You’re simply telling Import-CSV that the file’s fields are separated by spaces, rather than by commas (the default).

Thanks for the kind words ;).
by jolson at 2013-03-03 09:14:59
Thanks, trying the suggested steps, I now see the difference in how PowerShell treats the file by creating the objects. I knew the extension wouldn’t matter, but since the command was displaying my data, I thought PowerShell would be able to parse it regardless of space or comma. Fixing the file showed me the difference in output.
by jolson at 2013-03-03 14:52:44
Command to get CSV from old DC:
Get-ADUser -Filter * -Property HomePhone,MobilePhone,OfficePhone | Export-CSV phones.csv
This properly formats the file so objects are created when the file is imported. I received an ADInvalidOperationException when trying to pass the data to the Set-ADUser command in my script. After trying different ways to format the statement, I tried the Quest cmdlet Set-QADuser. This command took the array input without error. I did have to change OfficePhone to PhoneNumber in the header row in my csv and my script.

Final Script:
Import-Module ActiveDirectory
add-pssnapin Quest.ActiveRoles.ADManagement

$users = $i = $null
$users = import-csv .\phones.csv
ForEach($user in $users)
{
"modifying $($user.SamAccountName)"

Set-QADUser -Identity $user.SamAccountName -HomePhone $user.HomePhone -MobilePhone $user.MobilePhone -PhoneNumber $user.OfficePhone
$i++

}

"modified $i users"


Quest cmdlets:
http://www.quest.com/powershell/activeroles-server.aspx

Hi, I am new here to both the site and Powershell.
I want to learn how to get the officephone property, parse it into variables - area code and number- , display the variables, format the number correctly Ex. (###) ###-#### x####
and then put the new number back in AD.
I do not want to use a csv or external file.
I just want to read AD, get the value, display the value, parse it, fix it, display fix, put it back into AD. I got an idea for some of this but not all.
I am having trouble getting the value into a variable and displaying.
I know that seems real easy to most of you, but I am a newb - in powershell.
I will probably kick myself when I see the proper method.
any help would be appreciated.
Thanks.

Jerry,

First you need to determine which AD attribute holds the phone number you want to work with. There are many that are setup to hold phone number for different purposes.

For Example:
facsimileTelephoneNumber
homePhone
mobile
otherFacsimileTelephoneNumber
otherHomePhone
otherIpPhone
otherMobile
otherPager
otherTelephone
pager
personalPager
telephoneAssistant
telephoneNumber

Once you determine which attribute you need, you can easily retrieve it using the get-aduser cmdlet

For Example:

Get-ADUser user1 -Properties telephoneNumber | select -ExpandProperty telephoneNumber

If you do not store it in a variable, it will by default display on the console as standard output. If you want to put the returned value in a variable, simple specify the variable to assign it to.

For Example:

$phonenumber = Get-ADUser user1 -Properties telephoneNumber | select -ExpandProperty telephoneNumber

You can then display the contents of the variable by just typing it

For Example:

$phonenumber

After you have done your manipulation, you can user Set-ADUser to write the property back to AD. Many of the phonenumber attributes have parameters available with Set-ADUser, or you can use the -replace, -add, -remove, or -clear parameters. Whichever is the most appropriate.