MaryK
 New Member Posts:31
 |
| 05 Aug 2008 06:45 PM |
|
Hello,
I am in the process of migrating 2000 users from exchange 2003 to Exchange 2007. My objective is to spread the mailboxes evenly across all the databases on the target 2007 sever. The source users would be just the aliases of the users in a text file. I am working on a powershell script but it may take me some time given that I am a newbie. can anyone help?
|
|
|
|
|
halr9000
 Basic Member Posts:316
 |
| 05 Aug 2008 06:51 PM |
|
Jon Noble just wrote an article about this the other day. Also, we discussed it on Episode 36 of the PowerScripting Podcast. |
|
|
|
|
MaryK
 New Member Posts:31
 |
| 05 Aug 2008 07:11 PM |
|
I had looked at that posting earlier but unfortunately it does not address what I am looking to do. |
|
|
|
|
halr9000
 Basic Member Posts:316
 |
| 05 Aug 2008 07:29 PM |
|
Sorry, I got excited. :) I know next to nothing about Exchange myself, so maybe some others can pitch in. |
|
|
|
|
KarlMitschke
 Basic Member Posts:161
 |
| 05 Aug 2008 07:35 PM |
|
Are the users already spread out evenely on 2003?
What do you mean by "even" - do you want 300 users in each database, or do you want 20GB of data in each one?
Karl |
|
|
|
|
MaryK
 New Member Posts:31
 |
| 05 Aug 2008 07:42 PM |
|
Let's say I do a migation every night. I want to input the alias of 200 users in a text file (regardless of the size of their mailboxes) and move them evenly across 50 databases I have on the server. The ideal way to do it I guess is to put geimailboxdatabse in an array and then for each db in mailboxdatabase pick one user and move it then move to the second db in the array and pick the next user in the input file. Or, maybe do it the other way arround and do get-content of c:\users.txt and move-mailbox of one user to one db and the next user into the next db and stop at the last user but keep looping onto the dbs. I hope that makes sense... |
|
|
|
|
KarlMitschke
 Basic Member Posts:161
 |
| 05 Aug 2008 08:08 PM |
|
Something like this might help. NOTE, this is not tested. Try it with the -whatif as posted, and once you see what it is going to do, remove the -whatif.
On the first day, do only 51 to make sure it really works. (Obviously, 51 of your least favorite people) ;)
$mailboxes = Get-Content "C:\monday.txt"
$DBIncriment = 0
foreach ($mailbox in $mailboxes)
{
do
{
$DBIncriment ++
Get-Mailbox -Identity $mailbox |Move-Mailbox <server\database$DBIncriment -WhatIf
}while ($DBIncriment -ne 51)
} |
|
|
|
|
MaryK
 New Member Posts:31
 |
| 05 Aug 2008 08:41 PM |
|
I will try it and let you know but I have a question:
I am not sure what to put in the <server\database$DBIncriment . Let say my server is called server1 and I have 50 storage groups SG1-SG10and each 1 has a DB Let's say the DBs are called server1SG1DB1to Server1SG50DB50.
|
|
|
|
|
MaryK
 New Member Posts:31
 |
| 05 Aug 2008 08:52 PM |
|
I meant SG1 through SG50 (not SG10). |
|
|
|
|
KarlMitschke
 Basic Member Posts:161
 |
| 05 Aug 2008 09:01 PM |
|
This should look like:
Get-Mailbox -Identity $mailbox |Move-Mailbox server1\SG$DBIncriment\database$DBIncriment -WhatIf |
|
|
|
|
MaryK
 New Member Posts:31
 |
| 05 Aug 2008 09:38 PM |
|
Hi,
This is not working because of the naming convention we have for the databases (see below)
server1\server1sg01\server1sg01db01
server1\server1sg02\server1sg02db02
server1\server1sg03\server1sg033db03
.
.
server1\server1sg50\server1sg50db50
I will play with it more tonight and see.
Thanks
|
|
|
|
|
KarlMitschke
 Basic Member Posts:161
 |
| 05 Aug 2008 10:39 PM |
|
Yeah, I'm having problems with it too - don't use my code :) i will work on it when I get a chance. |
|
|
|
|
jonoble
 New Member Posts:6
 |
| 06 Aug 2008 06:18 PM |
|
Unless I'm misunderstanding, I would have thought you could use the code I posted which Hal mentioned... If you give create a variable $Ex2007, containing the name of the server you want to move people to, then use may hashtable method: $mailboxcount = @{} Get-MailboxDatabase -Server $Ex2007 | ?{$_.recovery -eq $FALSE} | ` %{$mailboxcount["$($_.storagegroup)\$($_.name)"] = 0; Get-Mailbox -Database $_ -ResultSize Unlimited | ` %{$mailboxcount["$($_.database)"]++}} That gives you a hashtable, $mailboxcount, which contains all of your databases (regardless of your naming convention), with the number of mailboxes in each. Then you can do this: get-content c:\users.txt | select -first 50 | %{ $mbdatabase = ($mailboxcount.GetEnumerator() | sort value | select -first 1).key get-mailbox $_ | move-mailbox $mbdatabase $mailboxcount[$mbdatabase]++ } So for each of those 50 users/mailboxes, you are picking the database with the fewest mailboxes, moving the current mailbox to that database, then you're incrementing the number of mailboxes in the database in the hashtable, so if you start out with no mailboxes on the server, you'll be stepping through the databases (albeit in a random order) - it won't put a 2nd mailbox on a database before all the databases have one mailbox. Things to bear in mind: 1) You'll need to refresh the file before you run the script on day 2 or it'll move the same 50 mailboxes again. 2) Sticking with a limit of 50 mailboxes moved per day, per source server, is a good idea because the move will generate logs roughly the same size as the moved mailboxes. You want to make sure you aren't generating too many logs before a full backup truncates them. If you want to do more moves between backups, turn on circular logging. If I've misunderstood what you're trying to do, let me know and I'll see if I can suggest something that will suit you better. |
|
|
|
|
MaryK
 New Member Posts:31
 |
| 06 Aug 2008 08:43 PM |
|
Thanks for the posting. That's what I am looking to do. However, I get prompted to enter the database name when I run the script. Any ideas? |
|
|
|
|
MaryK
 New Member Posts:31
 |
| 06 Aug 2008 08:58 PM |
|
Nevermind I just naswered my own question. I just added -targetdatabase to your script where it was missing. I am running into a new issue. The script starts reading the users aliases from c:\users.txt then at the first user (let's say his alias is jdoe) it tells me this:
The operation could not be performed because object 'jdoe' could not be found on domain mydomain.
At line 8, position 0
get-mailbox $_ | move-mailbox -targetdatabase $mbdatabase
However, if I do a simple move from the command like it works like for example:
move-mailbox jdoe -targetdatabase dbname. |
|
|
|
|
MaryK
 New Member Posts:31
 |
| 07 Aug 2008 02:25 AM |
|
jonoble,
I got this to work. It was an issue with some of the accounts. I am trying next, to modify your script (if you do not mind) and add some logging and error checking to see which mailbox moves fails. Any help would be appreaciated.
Thanks |
|
|
|
|
jonoble
 New Member Posts:6
 |
| 07 Aug 2008 08:23 AM |
|
Sorry about missing the -targetdatabase (I was replying without my code to hand). Feel free to modify my script as much as you like. I'll try to help where I can, but for starters you may want to look at the error stream redirector "2>" or using Start-Transcript and Stop-Transcript to catch all the output of your script. You can use the $ErrorActionPreference variable to decide what you want to do with errors throughout the script, or you can use the -ErrorAction parameter on any cmdlet to control that one specifically. If you want to create your own error log to catch specific errors, I find the $? variable useful. It holds $true if the last operation succeeded, or $false if it generated errors. |
|
|
|
|