Browsed by
Month: March 2014

Cloud Migration Woes: Validating Office 365 Users and Licenses (Part-2)

Cloud Migration Woes: Validating Office 365 Users and Licenses (Part-2)

Previous Post: http://www.sharepointevolved.com/2014/03/17/cloud-migration-woes-validating-office-365-users-licenses-part-1/ In the first part of this article I talked about the steps necessary using PowerShell to find information about users on Office 365 and validate their license status. We were able to connect to Office 365 with PowerShell and search for users via several parameters. This search mechanism helps us resolve the users that have been synchronized or created in the cloud. It is rather easy as well to include additional search fields if users are somehow addressed by a different format for logons & UPNs, it does not need to explicitly be Display Name or Alias, and it could be any combination of searches specific to an organization. This method works extremely well for a single user that you want to validate, however what would you do if you had a group of users, say a list of users exported from a SharePoint site? It would be extremely helpful to iterate through that list and compare the users to users in Office 365 and see if they should be successfully migrated. Luckily PowerShell makes this scenario very simple and we need to follow these logical steps:

  • Get a List of SharePoint Users
  • Iterate through List of SharePoint Users and Search Office 365 for matching Cloud Users
  • Validate the Licenses of Each Matching User
  • Create a List of Matches, Misses, and license results
  • Output the list of Users

I have made the completed  PowerShell script available for download at the end of the article and the following steps explain the processing and setup of each section of the script. Following the first part of the article, we should be on a SharePoint Server in the Farm (in order to get the users) and have installed the PowerShell CommandLets for Office 365 as well as the login feature. In our script we then reference both the SharePoint CommandLets as well as the Office 365 ones in the following script header.

 

Once we have created the references to the right CommandLets, we have to set up the global variables for the script. The only real global variable is a data table(ValidatedUsers) that stores the results of each of the matching actions in the following columns Email – Local Email  (On premise reference) Alias – Logon Name (On premise reference) Display Name – Local Display Name  (On premise reference) Validation Result – Was the script able to find the user in Office 365 User Principal Name(UPN) – If found what is the sign in name Is Licensed – Does this user have a license assigned to it User Mapping – Field to Create User Mappings for 3rd Party Products

 

This section creates a data table object that we can reference throughout the script, as well as the columns that we referenced above, and then adds those columns to the newly created datatable. Once we have the datatable available as a reference, we need to see if we are already connected to Office 365 or if we need to initiate a request for credentials and then generate a new connection.

 

This section attempts to get the current subscription info as a test to see if the service is already connected. this is useful if you want to run multiple searches against sites in one window without re-authenticating every time. If we see that no subscription information was returned we need to initiate a connection and therefore we request the user credentials and attempt the Office 365 connection. Now that we’ve got the bulk of our preparation done for connecting to Office 365, we step into the Search User function of the script. The SeachUser function takes a SPUser object as a parameter and then uses properties of that user to attempt a match in the cloud.

 

We get the user properties, Email, LoginName (Alias), and Display name from the user object to be used in the search.

 

Then we run the searches in the following order against the user properties 1 Email -> 2 Alias -> 3 Display Name Hopefully we’ll never hit the third condition where the display name is searched since we would rather make a match on a unique value like an email or a domain logon.

 

If a user is found, we then do a quick test to make sure that the user actually has a license available, if not the user migration will fail. And once we have the licensing results we create a row for the data table and add cumulative information we’ve obtained to the row and then to the data table. Bonus: The UserMappingXML Field can be modified to suit the format of the third party tool you may be using, it is otherwise not used. The script also outputs to the console the status of each check when it is finalized along with some nifty coloring.

 

In the case that we don’t find a matching cloud user, we record the user information as a row in the data table as well along with the failed validation result, as well as outputting it to the console. That covers the SearchUser function, next we need to get a bunch of users from SharePoint and then pass them over to the search so we can validate them.  Since the script can take any SPUser Object, getting those objects can be modified to suit a users needs at this point.

 

This section access iterates through the sites in a specified web application and gets a gigantic list of users to test, adding each user to the $allusers object.

 

Once we have all the users to check its pretty simple to go through and validate each one using the above SearchUser function.

 

And Bonus, once the users have been validated and the table created, the table can be exported to a CSV file in the current directory. The filename is in the format “Results-sp2010-134134134134.csv” for uniqueness. To make this work in your environment, there are only two things that need to be changed:

  1. $web should be updated to point to a valid web application in your environment
  2. $searchdomain needs to be updated to the domain that the majority of your users log into SharePoint with

So now that you know how the script works, you can Download the Powershell Script Here
Bonus Update: Additional Script using users in a CSV file is available here

Cloud Migration Woes: Validating Office 365 Users and Licenses (Part-1)

Cloud Migration Woes: Validating Office 365 Users and Licenses (Part-1)

Last we began like every great week begins, with coffee. The good times as it is said, didn’t last. No sooner had the warmth of the coffee left me, I started running into issues when I started migrating.

Diving Down the Rabbit Hole

The Scenario: Moving a simple and small SharePoint 2010 team site to SharePoint Online using a third party tool
The How: Most migration tools provide the capability to map users from old accounts to new accounts whether it is migrating between domains in a customer’s environment, or mapping to a provider’s hosted SharePoint domain.
The Issue: User migrations were not successful, not all mapped users were being migrated

One small complexity when migrating users to SharePoint Online, users must be mapped to what is their user principle name in Office 365. The problem is that this can take several formats depending on the active directory structure of your organization.

For Example the user Luc Hollande has email luc.hollande@sharepointevolved.com, and the domain logon user (Alias) of lhollande, though he came in from an acquisition, so really his primary email is luckyluc@smallsoftwarevendorthatweaqcuired.com.

What does this mean in terms of the mapping? This user could have one of several mappings to an Office 365 User Object…

Which one do I use? That’s a very good question. I’ll answer that in a moment…

Licensing Implications

Now think about a user that you know that the user mapping is correct, meaning you have verified that their “Domain Logon” matches their “Cloud Logon”, and yet every time you perform the migration the user mapping fails to migrate that user. Well that’s because the user can’t be created if it doesn’t have a license assigned… Think about that for a second. That means inactive users, or users that aren’t necessarily part of a SharePoint migration can have their content migrated, however references to them as users in the site will cease to exists. This doesn’t necessarily mean that these users have left the company or that don’t use SharePoint, this just means that they may not be part of this initial migration to the cloud. This brings a whole slew of additional considerations into Migration planning and unfortunately makes the job more complex in the long run.

I can understand why this check is in place for the cloud service, maintaining active users and assuring licenses. However it may force business to allocate licenses/users much sooner than they are otherwise prepared to commit. What if a business doesn’t have enough licenses purchased to assign all of those users? This rapidly becomes an escalating issue which can be a blocker in a migration project, waiting on a purchase order, or the stakeholders to decide if they want to bring over user history, or perhaps waiting for the Active Directory Synchronization configuration to propagate correctly.

So now if the users have been assigned license and are ready to migrate, you are still faced with the problem of matching on premise users to their counterpart identities in the cloud. Luckily, Microsoft has provide the Microsoft Online PowerShell commandlets which you can use to attempt to match users identities using the “Get-MSOLUser – SearchString” Command. One small downside is that you need to download an installation file here to have access to the commandlets. Even more of a wrinkle, to get the nice login fidelity for Office 365 you really need the Sign In Assistant (Beta)

 

These are the steps necessary to get this script working in your environment

  1. Install the Microsoft Online Services Sign-In Assistance found here http://www.microsoft.com/en-us/download/details.aspx?id=39267
  2. Install the Windows Azure Active Directory Module for Windows Powershell found here http://msdn.microsoft.com/en-us/library/windowsazure/jj151815.aspx
  3. Launch the Windows Azure Active Directory Module, Found in the Start Menu, as pictured in Windows 8
    031714_1558_CloudMigrat1
  4. Create a reference to your Office 365 Credentials using “$cred = Get-Credential”
    031714_1558_CloudMigrat2
  5. Connect to Office 365 by running the command “Connect-MosolService -Credential $cred”
    031714_1558_CloudMigrat3
  6. Search for an online User using the command “Get-Msol-User – SearchString “search query””
    031714_1558_CloudMigrat4
  7. …Profit?!
    Using command $user | fl to get a list of properties and values of the member object of which the property IsLiscensed is very important

Matching Users

Well now that I know how to find users, how do I match up all of these users with their different logon information to their cloud identities? Well in this case I had to run the search three different times

The first search uses an assumed email format (Firstname.Lastname@domain.com) to try and match users to logons

 

 

Last and not least.. well maybe a little desperate, I search based on full name to see if I can find a unique user. In a small environment this works well, however in a larger environment, it might not as well.

The hope is that by this time we will have resolved the local user information to a user in our tenant so we can perform the migration. So what happens after we have found the user? The next most important thing is to determine if the user is licensed Office 365 so we can migrate that user successfully, luckily all we have to do is look at the IsLicensed property to figure that out and while we’re at it we grap the actual User Principal Name of the object in the cloud to refer to.

 

So now given a local user, we can now determine which users are online, which are licensed, and use that information in our migration strategy.

Now I know what you’re saying, wouldn’t it be nice to put this all together and scan a SharePoint site to see if all the users existed in the cloud? Furthermore wouldn’t it be nice to know if those users had licenses assigned? Heck couldn’t you even generate a UserMapping xml document for me to use for this migration?

The answer is yes it would, come back for Part 2 and you’ll see how it’s done.