Move Mailbox from a CSV Import file

A while back, I had promised to write another post detailing how to use Import-CSV and then run Move-Mailbox against the users in that CSV file.  Well, quite a bit of time has passed since then, and getting this figured out proved a little more difficult than I thought it would be.  I finally got it worked out, though.

Here are the details of the setup.  You have users that you want to split up between several target databases.  In my CSV file, I have 3 columns, as outlined below (sample file)

Name, Username, TargetDB

A user, auser, "Server\Storage Group\Mailbox Database"
B user, buser, "Server\Storage Group\Second Database"
C user, cuser, "Server\Storage Group\Third Database"

The TargetDB column means that you will have to do a little bit of legwork in determining where you want to put the users, and populate that column, but it shouldn't take too much effort.

Next, we'll start writing the script itself.

##################################################################
#                                                                                                                                                                #
#                                   Script to move mailboxes multithreaded from CSV import                                    #
#                                                                                                                                                                #
##################################################################

write-output "Moving mailboxes from CSV import"

#First we are going to import from your csv file
#where the CSV file contains 3 columns.  Name, Username and TargetDB

$users = import-csv c:\userimport.csv

#Now we are going to filter the list down and get a
#list of just the users on the first database

$db1 = $users| where {$_.targetdb -like "*mailbox database"} |
foreach { $_.name } | get-mailbox

#getting a list of the users on the second target database

$db2 = $users | where {$_.targetdb -like "*Second Database"} |
foreach { $_.name } | get-mailbox

#Repeat the above line for each additional database that you have.

#Now we move each group of users to their respective databases

$db1 | move-mailbox -targetdatabase "E2K7-2\First Storage Group\Mailbox Database" -confirm:$false -maxthreads:10

$db2 | move-mailbox -targetdatabase "E2K7-2\Second Storage Group\Second Database" -confirm:$false -maxthreads:10

#Repeat the above line for each additional mailbox database that you have

write-output "Completed Mailbox moves from CSV file"

I first tried to get this working with just one command, but kept failing on the target database portion.  When I was creating my arrays, I had a separate array for the target database, but the problem I kept running into was that the value for the array was only being recognized as the last value in the CSV file.  So if Third Database was the last value for TargetDB, that was where all users ended up being moved.  After multiple failed attempts to correct that, I decided that the best way to approach this would be to filter the CSV and move all users with a common target database, then move on to the next group.  It still achieves the desired result of being able to take advantage of multi-threading, and it also does everything in one shot.

If you have any suggestions for improvement, please feel free to pass on your suggestions.

Comments

  • Anonymous
    January 01, 2003
    Hello Ben, I'm using this script to move mailboxes from E2K7 to E2K7. Looks like mailboxes which are planned to move to DB2 wait for DB1 move to complete. I'm I missing something here? Regards, Harisha N

  • Anonymous
    January 01, 2003
    This totally saved my tail last night. A sincere thank you!! AJ

  • Anonymous
    January 01, 2003
    How Microsoft Office Communicator enhances Outlook 2007 functionality Why boot an Exchange server from

  • Anonymous
    January 01, 2003
    Are you using SamAccountName and UserPrincipalName in your CSV?

  • Anonymous
    January 01, 2003
    Hi Harisha, Nope - you aren't missing anything. The way the script is set up, it does exactly what you are seeing. I did note this in the post above. "After multiple failed attempts to correct that, I decided that the best way to approach this would be to filter the CSV and move all users with a common target database, then move on to the next group" I'm sure it is possible to get this to work the way you want, but I haven't had time to further refine this.

  • Anonymous
    November 19, 2012
    Hi Ben, Is there any way to specify the target DB in input file and script should take it from that file?