Script to assign Office 365 full access permissions based on the MigrationWiz bulk import CSV file

When you’re migrating to Office 365 using a tool like MigrationWiz, one of the requirements should be to have a “MigrationWizAdmin” account, on Office 365, that will have full access to all the mailboxes (unless you want to specify each user’s password when importing the users to the MigrationWiz project).

Most of the times the “easy” solution is to run the following cmdlet:

Get-Mailbox -ResultSize unlimited | Add-MailboxPermission -User MigrationWizAdmin@yourdomain.com -AccessRights fullaccess -InheritanceType all -AutoMapping $false

And you can also use the “Filter” parameter on the “Get-Mailbox” to narrow the number of mailboxes where the MigrationWizAdmin will have full access, based on one or several specific attributes, as show below:

Get-Mailbox -ResultSize unlimited -Filter {(RecipientTypeDetails -eq 'UserMailbox') -and (Alias -ne 'Admin')} | Add-MailboxPermission -User MigrationWizAdmin@yourdomain.com -AccessRights fullaccess -InheritanceType all -AutoMapping $false

The cmdlet above filters all user mailboxes, excludes the one that has the Alias “Admin”, and assigns full permissions to the migrationwizadmin user.

So could this solution fit the requirements of all your scenarios? Not really. Why? Some of the reasons are outlined below:

  • If you’re moving a subset of users to an existing tenant (i.e on a company acquisition), giving full permissions to the MigrationWizAdmin on all online mailboxes might just not be an option. Why should you give full access permissions on an existing Office 365 mailbox that is not going to be migrated? You should have a plan B.
  • Filtering might be a good option, but you need to set specific and unique attributes on the Office 365 mailboxes that are going to be migrated, and in most cases that just doesn’t happen.

So what could be your plan B? Well if you’re familiar with the MigrationWiz process, you know that after creating the project, the next step would be adding the users/items. You have several options to add them, such as using autodiscover, bulk add users via a CSV file or manually add each user.

I normally use the CSV file. To download it you have to choose the “Add > Bulk Add” option on the project, and click on “Download sample CSV file”.

1-done

Then all you have to do is, export the e-mail addresses from your source system, copy them into the MigrationWiz CSV and import the CSV via the portal.

Now, can i use that CSV file to assign permissions to the Office 365 mailboxes? Yes, and by using the CSV file you will be assigning permissions only to the users you’re going to migrate.

I’ve built a small and simple script that will read the “Destination Email” column and assign permissions to all the users on the CSV. You can copy and paste the script into a notepad and save it as a “.ps1” script. You need to connect to the Exchange Online management shell to run the script. Click here for guidance.

#Script to add mailbox permissions on Office 365 to an admin account#
#This script should run from an Exchange Online Management Shell#
#Version 1.0 - 27/05/2014#
#Author: Antonio Vargas#

foreach ($user in Import-Csv "C:\BlogTestDir\migrationwiz_import.csv"){ 
 Get-MailBox -Identity $user."Destination Email" |Add-MailboxPermission -user antonio.vargas@yourtenant.onmicrosoft.com -AccessRights FullAccess -InheritanceType All -AutoMapping $false
 write-host "Permissions added for the mailbox:" $user."Destination Email"
}

2-Done

Replace the user “antonio.vargas@yourtenant.onmicrosoft.com” with your Office 365 admin MigrationWiz admin user.

Note: The Office 365 MigrationWiz admin user, that will have full access on the destination, to all mailboxes being migrated, needs to be mailbox enabled.

Now see below an example of the CSV file, and the output of the script based on that file.

5-Done

3-Done

Finally if you want to check if the your admin user has full access on a specific mailbox, you can run the following cmdlet:

Get-MailboxPermission -Identity jorgelorenzo@domain.com -User antonio.vargas@yourtenant.onmicrosoft.com

4-Done

This blog post and the script can be useful to things as simple as giving permissions on mailboxes (on premises or on Office 365) based on a CSV file, or more specific such as during a MigrationWiz project.

Thanks and ping me if you have questions! 🙂

Office 365: Quick tip to list users with “onmicrosoft.com” UPN due to invalid on premises configuration

Imagine this scenario: You are doing a migration to Office 365, with Microsoft Dirsync, but you’re not the one preparing the on premises Active Directory. Someone else is doing that work and dedicated to the local AD.

You tell them that all users to be activated on Office 365 need to have a vanity domain as their User Principal Name (e.g yourcompany.com). They prepare the Active Directory, you install and configure Dirsync and you do the initial sync. Now you want to make sure that no user got the username user1@yourcompany.onmicrosoft.com due to an invalid configuration on premises.

Note: If the UPN of the user on premises has a domain that is not validated on Office 365, the username on 365 will be the @yourcompany.onmicrosoft.com.

What should you do? Well, in those cases what i do is, i list all the *onmicrosoft.com usernames, export it into a .csv file, and send it to the Active Directory team for validation. The question should be: “Do any of the listed users need to be activated on Office 365, and therefore need the UPN fixed on premises?”

To build that list is quite simple. First you need to open the Windows Azure Active Directory Module for Windows Powershell, and connect to your tenant, by running the following cmdlets:

$msolcred = get-credential
connect-msolservice -credential $msolcred

See detailed instructions here.

Once connected, to get a list of all the users with an *onmicrosoft.com username, run the following cmdlet:

Get-MsolUser |where-object {$_.UserPrincipalName -like "*.onmicrosoft.com"}

The output of the cmdlet above should be:

1-Done

If you want to know the total number of users with the *onmicrosoft.com username, run the following cmdlet:

(Get-MsolUser |where-object {$_.UserPrincipalName -like "*.onmicrosoft.com"}).count

The output of the cmdlet above should be:

2-Done

Now, to export those users to a .csv file, run the following cmdlet:

Get-MsolUser |where-object {$_.UserPrincipalName -like "*.onmicrosoft.com"} | Select-Object Userprincipalname, Displayname, Islicensed | Export-Csv C:\Test\UsersWrongUPN.csv -NoTypeInformation

You will get a csv file, like the one shown below:

3-Done

On the .csv file you will probably see users like the tenant admin, or service accounts. The tenant admin is a cloud user and doesn’t need to have the username fixed on the on premises Active Directory. The service accounts might be irrelevant also, and to prevent them from showing on Office 365 your solution would be to use OU based filtering on Dirsync. See here how.

All you have to do now is send the .csv file to your Active Directory administrators and have them validate the users that need fixing, the users you can/should filter to exclude from being synced to 365, and the users you can ignore and keep them with an *onmicrosoft.com username.

Again this is particularly useful when you’re not the one preparing the Active Directory for your Office 365 deployment.

Office 365 Script: Enable users with a value on the mail attribute as mail users

When your Office 365 migration, is not from an environment where the mailboxes are on an Exchange On Premises (Hybrid/Staged/Cutover Migrations), and you’re are using Microsoft Dirsync to push your objects from the on premises active directory, into Office 365, then you need to prepare those objects on premises. That means that you should have users with the following attributes:

  1. A valid User Principal Name
  2. A Mail attribute
  3. Valid Proxy Addresses and ideally Exchange Attributes to be managed on premises

Regarding point 3, if like me, you’ve already done migrations from a 3rd party mail system to Office 365, with dirsync and just by adding a mail attribute to the users on premises, and pushing it into the cloud, you might ask, why should we have valid proxy addresses, and why should we have Exchange Attributes on those users? Well that is my opinion, and the way i work, and i will outline some reasons below:

  1. If the domain on 365 is federated, having the mail attribute will not be good enough, and you need to add proxy addresses, as described here. Enabling the users as mail users is a very quick and easy way of adding those proxy addresses, as opposed to having to edit those attributes on the Active Directory.
  2. Synced objects with Office 365 (Users, groups, etc) cannot have their attributes edited in the cloud. For example if you want to add an additional e-mail address to a mailbox on Office 365, and that mailbox is from a synced user, you will have to do it on premises and wait for dirsync to replicate those attributes to Office 365. There’s no better and easy way to edit those attributes than having those users enabled as Exchange objects on premises, and having an Exchange Server purely for management purposes.

The above does not mean in any way that your Exchange objects or your Exchange Server on premises will be part in any Hybrid Deployment. We are talking about migrations from a system which is not an Exchange on premises. The source can be Hosted Exchange, Lotus Notes, Google Mail, etc. And of course this scenario applies also when you have Dirsync.

Anyway I really highly recommend doing the described above, and to do that there’s sometimes a need to enable users as mail users. As a pre requisite I always ask my customers to prepare (or help them in the process, usually with scripting) the users with two important attributes: a valid User Principal Name and a valid mail attribute.

And once you have the two attributes above, and you want to enable those users as mail users, you can use the following script:

#This script enables users, on a specific OU, that have an e-mail address defined and are not exchange objects#
#This script is limited to the “TestAV” OU #
#Date:30/12/2014#
#Author: Antonio Vargas#

$users = Get-ADUser -SearchBase “OU=TestAV,DC=domain,DC=com” -Filter * -properties msExchRecipientTypeDetails, EmailAddress |where-object {$_.msExchRecipientTypeDetails -eq $null -AND $_.EmailAddress -ne $null}

foreach ($user in $users){
Enable-mailuser $User.UserPrincipalName -ExternalEmailAddress $User.EmailAddress
write-host $User.EmailAddress “<- This user was enabled as a Mail User.”
}

Now a quick example from my lab. I have 3 users on the OU being used by the script:

1

See below the output of the first part of the script, where it filters all the relevant users. User2 is the only one that does not have a mail attribute, and therefore was excluded from the output, which means that it will not be enabled as mail user by the script:

2

And when you run the script:

3

 

 

 

Finally you can see that both users are now enabled as Exchange Mail Users, and all your attributes, like the proxy addresses, should be in place. You can now manage those objects via your on premises Exchange Management Server.

This script should be executed on the Exchange Management Shell.

Again i very often bump into situations where my option is to execute a script like this one, and enable everyone as Exchange objects on premises, and if you are reading this post then probably that is also what you want to achieve.

Hope the above helped and as always any questions let me know.

Public Folder migration request error creating the Public Folder Hierarchy – “Property Expression [property name] isn’t valid”

To migrate your legacy public folders to Exchange 2013, you should follow all the steps described on the official Microsoft article.

Step 2 of the article mentioned above, helps you prevent errors related to the public folder name, such as having a “\”. But this blog post is related with something which is not covered by the article, and that can make your public folder migration request throw an error: Invalid alias on mail enabled public folders.

So as described on step 5 of the article, you start your migration request by running the following cmdlet:

1-done

 

New-PublicFolderMigrationRequest -SourceDatabase (Get-PublicFolderDatabase -Server <Source server name>) -CSVData (Get-Content <Folder to mailbox map path> -Encoding Byte) -BadItemLimit 200 -acceptlargedataloss -largeitemlimit 200

Note: On the above cmdlet i used both the baditemlimit and largeitemlimit set to 200, because i knew that my public folders had a significant number of both bad and large items. If that is not your case keep the bad and the large item limits to a minimum if at all specified.

Once the public folder migration starts you can run the following cmdlet to see the progress. If you have invalid alias on the mail enabled public folders, the migration request will fail at 10%, when creating the Public Folder Hierarchy:

3.1-Done

 

 

To get the details of the error you need to run the same cmdlet, but with the “|fl” at the end, as shown below:

2-done

 

Get-PublicFolderMigrationRequest |Get-PublicFolderMigrationRequestStatistics |fl

On the details you can see the following:

3.2-done

On the screenshot above you can see that the mail enabled public folder “Accountancy Properties” has an invalid alias, and that is because you cannot have spaces (and other characters as shown above) on the alias. So the next step would be to fix all mail enabled public folders with invalid aliases.

Go to your Exchange Management Shell and run a cmdlet that will list all the mail enabled public folders with spaces. Of course some other mail enabled public folders can have other problems, but in my case it was only the spaces. If you have other problems besides spaces you can adapt the “where-object” filtering from the cmdlet below, to those characters. Also to get an output of all the mail enabled public folders with issues, you can run the following cmdled and see which public folders throw a warning:

Get-MailPublicFolder

All the mail enabled public folders will throw a warning on the output, but of course we need to have a list of only the ones with problems to resolve the issue quicker. So to have a list with all the ones with spaces, and export it into a csv file, run the following cmdlet:

5-done

 

 

 

 

Get-MailPublicFolder | Where-Object {$_.Alias -like "* *"} | Select-Object alias, identity |export-csv [CSV file path and name]

Note: On the cmdlet above, if you’re problem is not limited to spaces on the alias, you can change the where-object filtering to try and find other invalid characters.

Once that is done you will get a csv file with all the mail enabled public folders with invalid aliases, as shown below:

6.1-done

 

 

Having that information you can now fix all the mail enabled public folders. You have two ways of doing it:

Option 1:

You can open your Exchange Management Console, go to tools and then open the Public folder Management Console. Expand the Public Folder tree and go to the properties of each public folder with problems. On the “Exchange General” tab change the alias and apply, as shown below.

7-done

 

 

 

 

Option 2:

You can use the Exchange Management Shell, and run the following cmdlet:

8-done

 

 

 

 

Get-MailPublicFolder [Public Folder Name] |Set-MailPublicFolder -Alias [PublicFolderAlias]

Once you set the valid alias you problem is solved for that specific public folder. You might be thinking “how can i automate this for the dozens or hundreds of public folders i have with issues?”. Well the answer is you should use that csv file you exported with all the public folders, insert a column with valid aliases, build a script that reads from the csv file and run it from the Exchange Management Shell to have all your folders fixed in one go. In my case i had a low number of folders with issues, so i haven’t built the script. I am planning to build 2 scripts, one to export public folders with issues and another one to use that exported file and fix those issues, but at the moment i don’t have it. Feel free to ping me an e-mail or comment if you’re interested on the script and i can find some time to build it. It should be a fairly simple script. Or feel free to have a go on doing that.

But back to the issue. Once you have all your mail public folders with valid aliases, i recommend that you remove the current public folder migration request and create a new one. To do that run the sequence of cmdlets shown below:

9-done

 

 

 

 

 

To see the current failed request:
Get-PublicFolderMigrationRequest

To delete the current failed request:
Get-PublicFolderMigrationRequest |Remove-PublicFolderMigrationRequest
To create a new request:
New-PublicFolderMigrationRequest -SourceDatabase (Get-PublicFolderDatabase -Server <Source server name>) -CSVData (Get-Content <Folder to mailbox map path> -Encoding Byte) -BadItemLimit 200 -acceptlargedataloss -largeitemlimit 200

Finally after the new request is created, you can see that now the migration is ongoing and went past the Public Folder Hierarchy creation without issues.

10-done

 

 

Problem solved and happy migration! 🙂

 

 

 

 

 

 

Public Folders migration to 2013 gets “StalledDueToMailboxLock” Status

Are you trying to migrate your public folders from legacy Exchange versions to Exchange 2013? And are you getting stuck on a “StalledDueToMailboxLock” error when you try to resume the migration? Well then continue reading. I will try to keep this post short and simple, just like the solution to your problem.

First things first.. the migration process.. To successfully complete the migration, and if you don’t have experience on doing it, you should follow all the steps from the link below:

https://technet.microsoft.com/en-us/library/jj150486(v=exchg.150).aspx

So in summary, you download the scripts, estimate the number of public folder mailboxes you will have, name and create those mailboxes and start the migration process, that will suspend at 95% with all the data migrated except the delta.

Once that is done you then lock the public folders on the legacy version (step 6 on the link above), by running the following cmdlet:

Set-OrganizationConfig -PublicFoldersLockedForMigration:$true

And what is the purpose of this cmdlet? Simple.. to block the access from the users to the legacy public folders, so that you can migrate the delta, unlock the access on 2013 (Step 8), and have all users using the new modern public folders.

So what can go wrong and when can you see the “StalledDueToMailboxLock” Status?

After you run the Set-OrganizationConfig -PublicFoldersLockedForMigration:$true cmdlet, the changes need to apply on the legacy public folders, before you resume your migration by running the Resume-PublicFolderMigrationRequest -Identity \PublicFolderMigration cmdlet.

If the changes are not applied yet, than your public folder migration request will resume and a minute or two later it will get into a “StalledDueToMailboxLock” status.

When you get into that status there are two things you need to do:

First try and access the public folders, from an Outlook client. Can you still access them? Well that means they are not locked and the changes didn’t apply yet.

So you can either wait for the changes to apply, and keep checking the access to the public folders until it’s blocked, or alternatively you can force the changes to apply, by restarting the Information Store service on the legacy server(s), where the public folder database being migrated is. Once you restart the Information Store service, retry accessing the public folders from an Outlook client. The access should now be blocked. Then you can suspend and resume your public folder migration request, to get it going quicker, by running:

Suspend-PublicFolderMigrationRequest -Identity \PublicFolderMigration
Resume-PublicFolderMigrationRequest -Identity \PublicFolderMigration

The request should now complete without issues, and you can continue following the steps on the link i provided earlier on this post, to get your public folders running on 2013.

Any questions about the entire process let me know.

Office 365 & MigrationWiz: “ErrorNonExistentMailbox: The SMTP Address has no Mailbox associated with it”

Just a few days ago i was using MigrationWiz to push a customer from a hosted Exchange to Office 365. Usually when there’s no possibility of building a Hybrid Deployment, in cases when the source system is a hosted Exchange or a 3rd party e-mail platform, i recommend and use MigrationWiz as the tool to migrate the mailboxes data into Office 365, as it’s an excellent tool and easy to use, which is very handy because we tend to offload the bulk migration of the users to the customer’s IT department.

But back to the problem i encountered. As i usually do, i have configured an administrator account on the source (Hosted Exchange) and one on the destination (Office 365). Both of those administrator accounts had full access permissions to all mailboxes. I configured a connector, to use those accounts, and added some test mailboxes to the connector to start moving data and see if everything was OK. My admin account on the source was admin@domain.com and i added that account to the connector as well to migrate the data, as a test. Once i started the migration i got the following error:

Your migration failed checking source credentials. The SMTP address has no mailbox associated with it. Error: ErrorNonExistentMailbox Detail: SmtpAddress admin@domain.com

Well i was sure that the source mailbox existed as i was able to log into it via Outlook Web Access, so what was the problem?

The answer is actually quite simple. MigrationWiz uses Exchange Web Services (EWS) to perform the moves of the mailboxes, and the reason is better throughput!! 🙂 Read more about the MigrationWiz performance on the below link:

http://blog.bittitan.com/2012/05/15/microsoft-exchange-online-office-365-migration-performance-guide/

But again back to the problem. Those MigrationWiz EWS queries will fail if the mailbox is hidden from the Global Address List. And that was my case. Why? Well for starters you might want to hide from the global address list on the source (and even the destination), a mailbox which is in fact only used for migration purposes.

The solution? Disable the hide from address list option on the mailbox and you’re sorted.

One thing i do recommend if you’re looking at an error just like the one i have is, make sure that the mailbox actually exists. Try logging into the mailbox using Outlook Web Access. Or else you might be chasing ghosts! 🙂

I hope this post was helpful.