Using Windows Azure Active Directory to Manage Office 365

 

Summary: Use Windows PowerShell to Manage Office 365 using Windows PowerShell cmdlets, scripts, and batch processes.

You’re right: when you see the term “Azure Active Directory” your first thought probably isn’t, “Hey, I bet that’s the way you manage Office 365 using Windows PowerShell.” As it turns out, however, “Azure” has long been the name for Microsoft’s cloud service, and “Active Directory” has long been the name for, well, for Active Directory. Put them together and you get Azure Active Directory Directory, a technology enables you to use Windows PowerShell to manage Office 365 users, groups, licenses, and subscriptions. This topic includes information about:

  • Returning Office 365 User Account Information

  • Selecting the User Account Property Values to be Returned

  • Configuring User Account Property Values

  • Working with Office 365 User Licenses

  • A Quick Note Regarding Positional Parameters and Office 365

If you’d like a little more information on the Azure Active Directory cmdlets, you can find that information here.

Returning Office 365 user account information

Names aside, it’s far more interesting (and important) to focus on the management tasks that can be carried out using Azure Active Directory. Azure Active Directory includes 66 cmdlets, most of which are used to manage your Office 365 users, groups, and licenses. For example, need a quick list of your Office 365 users? Try this command:

Get-MsolUser

Although this is a bit of a detour, it might be a good time to talk about cmdlet names. If you look at the names of the Azure Active Directory cmdlets, you’ll notice they all have one thing in common:

  • Add-MsolForeignGroupToRole

  • Add-MsolGroupMember

  • Add-MsolRoleMember

  • Confirm-MsolDomain

  • Connect-MsolService

As you can see, each cmdlet noun (the part of the name that comes after the hyphen) begins with the prefix Msol. Coincidence? Not exactly. Instead, the Msol prefix (short for MsOnline) is used to identify these cmdlets as Azure Active Directory cmdlets. All the Azure Active Directory cmdlets must use the prefix Msol, and no other Windows PowerShell cmdlets can use the Msol prefix. For example, the SharePoint Online cmdlets all have the prefix:

  • Add-SPOUser

  • Connect-SPOService

  • Disconnect-SPOService

  • Get-SPOAppErrors

  • Get-SPOAppInfo

The Lync Online cmdlets all use the prefix Cs:

  • Get-CsAudioConferencingProvider

  • Get-CsOnlineUser

  • Get-CsTenant

  • Get-CsTenantFederationConfiguration

  • Get-CsTenantHybridConfiguration

The Cs prefix is actually short for Communication Server. That’s because Lync Server was formerly known as Office Communications Server. At the time the name was officially changed, a large number of the cmdlets had already been completed. Because changing cmdlet names at that late date could have delayed the release of the product, the decision was made to keep the Cs prefix.

Interestingly enough, the Exchange cmdlets do not use a prefix of any kind:

  • Add-RecipientPermission

  • Get-LinkedUser

  • Get-RecipientPermission

  • Get-RemovedMailbox

  • Get-SendAddress

Why not? Exchange was the first server product to release a set of Windows PowerShell cmdlets. At that time, no one was enforcing the use of a cmdlet prefix or other identifier. As other server teams began to create cmdlets, however, it soon became apparent that there was a problem: if Exchange had a cmdlet named Set-User (which it does) then what are other teams who need a cmdlet for setting user properties supposed to do? (Cmdlet names have to be unique.) The solution was to use prefixes. As a result, we now have cmdlets with names like Set-MsolUser, Set-CsUser, and Set-SPOSiteUser.

At any rate, running Get-MsolUser is going to bring back information similar to this:

UserPrincipalName                     DisplayName           isLicensed
-----------------                     -----------           ----------
ZrinkaM@litwareinc.onmicrosoft.com    Zrinka Makovac        True
BonnieK@litwareinc.onmicrosoft.com    Bonnie Kearney        True
FabriceC@litwareinc.onmicrosoft.com   Fabrice Canel         True
BrianJ@litwareinc.onmicrosoft.com     Brian Johnson         False 
AnneWlitwareinc.onmicrosoft.com       Anne Wallace          True

Those are all your Office 365 users.

But let’s say that you’d like to see a list of just the unlicensed users; that is, users who’ve been added to Office 365 but haven’t yet been licensed to use any of the software applications. That’s an easy one, too:

Get-MsolUser -UnlicensedUsersOnly

Again, we’ve called the Get-MsolUser cmdlet, only this time we’ve tacked on the UnlicensedUsersOnly parameter. As the name implies, that parameter limits the returned data to users who haven’t been issued any licenses:

UserPrincipalName                     DisplayName           isLicensed
-----------------                     -----------           ----------
BrianJ@litwareinc.onmicrosoft.com     Brian Johnson         False
ScottW@litwareinc.onmicrosoft.com     Scott Wallace         False

Very nice.

We might point out, too, that Windows PowerShell has the reputation for being a computer language created by Martians. When many people think of Windows PowerShell they think of commands like this:

gc test.txt | sort {[int]$_} |% {$i = 1}{while ($i -lt $_){$i;$i++};$i++}

Granted, that command is a bit … obtuse …. On the other hand, we just showed you a command that returned only the users who haven’t been licensed for Office 365. To do that, we used a cmdlet named Get-MsolUser and a parameter named UnlicensedUsersOnly:

Get-MsolUser -UnlicensedUsersOnly

And when we ran that command we got back the unlicensed users only.

Which simply means that you can often make Windows PowerShell as cryptic, or as clear and straightforward, as you want it to be

Selecting the user account property values to be returned

Windows PowerShell gives you the ability to do things the way you want to do them. For example, we’ve already seen that running the Get-MsolUser cmdlet brings back three property values:

  • UserPrincipalName

  • DisplayName

  • isLicensed

That’s nice, but what if what we’d really like to see is the user’s display name, the department he or she works for, and the country/region where our user “consumes” Office 365 services? What then?

Note

Yes, “consumes” isn’t exactly a great word, either. But don’t worry about the terminology: the UsageLocation property indicates the geographic location where the user typically uses Office 365. And that’s very important: Office 365 licenses, policies, and available features revolve, in part, around this location.

As we’ve already seen, Get-MsolUser only shows us one of our preferred properties: DisplayName. Looks like we’re out of luck, right?

Right. Well, unless we run this command instead:

Get-MsolUser | Select-Object DisplayName, Department, UsageLocation

Here’s what that command returns:

DisplayName             Department                       UsageLocation
-----------             ----------                       -------------
Zrinka Makovac          Sales & Marketing                US
Bonnie Kearney          Sales & Marketing                US
Fabrice Canel           Legal                            US
Brian Johnson
Anne Wallace            Executive Management             US
Alex Darrow             Sales & Marketing                US
David Longmuir          Operations                       US

We won’t bother explaining how this all works today; that’s too much for an overview article. Instead, we’ll just note that the Select-Object cmdlet (which ships as part of Windows PowerShell 3.0) allows you to pick and choose the properties you want a cmdlet to return. You say you only want to see values for UsageLocation property? Then tell Select-Object to return just that one property:

Get-MsolUser | Select-Object DisplayName

Select-Object even lets you return all the property values for an item; try running this command and see what happens:

Get-MsolUser | Select-Object *

That’s useful because, as we’ve already seen, cmdlets don’t always return all the information available for an item. If you want to see everything Get-MsolUser has to say about a user then use a command similar to this:

Get-MsolUser -UserPrincipalName "BelindaN@litwareinc.onmicosoft.com" | Select-Object *

And here’s a handy bonus command, one that returns information about the users who do not have a usage location. (That’s important, because you won’t be able to do certain things with those users until that location has been set.) Here’s the command:

Get-MsolUser | Where-Object {$_.UsageLocation -eq $Null} | Select-Object DisplayName, Department, UsageLocation

And here’s the data that comes back:

DisplayName              Department                      UsageLocation
-----------              ----------                      -------------
Brian Johnson 
Scott Wallace            Operations

Those are the only two users we have who don’t currently have a UsageLocation.

Configuring user account property values

So far we’ve seen how you can use Windows PowerShell to return information. Perhaps even better is the fact that you can also use the Azure Active Directory cmdlets to configure information. You say Belinda Newman has moved to France and needs to have her usage location set to FR, the ISO (International Organization for Standardization) code for France? OK:

Set-MsolUser -UserPrincipalName "BelindaN@litwareinc.onmicosoft.com" -UsageLocation "FR"

You can see how easy this easy. We already know that the Get-MsolUser cmdlet can return a property named UsageLocation. So do we set that property value? We simply use the corresponding Set-MsolUser cmdlet and, yes, the UsageLocation parameter:

Set-MsolUser -UserPrincipalName "BelindaN@litwareinc.onmicosoft.com" -UsageLocation "FR"

There’s really nothing hard about that at all.

And here’s something cool. You say that all your users have moved to France? No problem:

Get-MsolUser | Set-MsolUser -UsageLocation "FR"

In this case, we’ve used the Get-MsolUser cmdlet to return all of our user accounts. We’ve then “piped” that information to the Set-MsolUser cmdlet. See the little pipe separator character in the command, the character that looks like this:

|

When you see the pipe character in a Windows PowerShell command that means you’re going to take whatever information was retrieved using the first cmdlet (Get-MsolUser) and then hand all of that information to the second cmdlet (Set-MsolUser). In this case, that means we’re going to have Set-MsolUser take all our user accounts and set the UsageLocation property to FR.

Not bad, if we do say so ourselves.

Note

OK, maybe that is easy for us to say. But no need to fret: here’s a good introduction to using piping and pipelines with Windows PowerShell.

Working with Office 365 user licenses

As we noted previously, there are plenty of things you can do with the Azure cmdlets; for example, this command returns information about the number of Office 365 licenses you have, as well as the number of licenses you have yet to distribute:

Get-MsolAccountSku

That’s going to return data similar to this:

AccountSkuId                 ActiveUnits   WarningUnits  ConsumedUnits
------------                 -----------   ------------   ------------
litwareinc:ENTERPRISEPACK    25            0              25

In our sample data, the litwareinc domain has been issued 25 licenses (ActiveUnits) and all 25 licenses are currently assigned to users (ConsumedUnits).

That’s good. Of course, even better would be the ability to see the licenses which have been assigned to an individual user. Without explaining all the details, here’s how we can find the licenses currently assigned to Ken Myer:

Get-MsolUser -UserPrincipalName "kenmyer@litwareinc.onmicrosoft.com" | Select-Object -ExpandProperty Licenses | Select-Object -ExpandProperty ServiceStatus

OK, we’ll offer a cursory explanation, because this is definitely a more-complicated command. In this command, we first use Get-MsolUser to return information for the user kenmyer@litwareinc.onmicrosoft.com. We then pipe that information to the Select-Object cmdlet, and use the ExpandProperty parameter to “expand” the Licenses property. We need to do that because Licenses is a multi-valued property; that means it contains multiple values (in this case, multiple licenses), and we want to make sure we are working with all the licenses. We then pipe the license information to Select-Object and expand the ServiceStatus property in order to get detailed information about each individual license.

Note

Take a look at this article on multi-property values if that cursory explanation proved to be no explanation at all.

When all is said and done, we should get back something similar to this:

ServicePlan                      ProvisioningStatus
-----------                      ------------------
YAMMER_ENTERPRISE                None
RMS_S_ENTERPRISE                 Success
OFFICESUBSCRIPTION               Success
MCOSTANDARD                      Success
SHAREPOINTWAC                    Success
SHAREPOINTENTERPRISE             Success
EXCHANGE_S_ENTERPRISE            Success

Admittedly, it might not be obvious at first glance what’s going on here. Fortunately, it’s not as obtuse as it might seem. The ServicePlan property contains a collection of licenses (the licenses available in your organization depend on the Office 365 plan that you purchased). The values in our ServicePlan property equate to the following:

Index Number Service Plan Product

0

YAMMER_ENTERPRISE

Yammer

1

RMS_S_ENTERPRISE

Windows Azure Active Directory

2

OFFICESUBSCRIPTION

Office Professional Plus

3

MCOSTANDARD

Lync

4

SHAREPOINTWAC

Office Web Apps

5

SHAREPOINTNETERPRISE

SharePoint

6

EXCHANGE_S_ENTERPRISE

exchange

In turn, the ProvisioningStatus property tells us whether the license has been assigned or not:

  • None means that no license has ever been assigned.

  • Success means that the license is assigned.

  • Disabled means that the license was assigned but has since been disabled.

As you can see, Ken Myer has been assigned all the available licenses except for Yammer.

Note

What’s the Index Number in the preceding table? The index number is another identifier for the service plan. Based on good old-fashioned computer programming, the first item in a collection like this is assigned index number 0. Thus YAMMER_ENTERPRISE has the index number 0. The second item in the collection is assigned index number 1, the third item is assigned index number 2, and so on. As we’ll see in a moment, these numbers can be used to do things like show you all the users who have a Yammer license, or all the users who don’t have a Yammer license.

So can we change these licensing assignments; for example, can we disable Ken’s ability to use Exchange and Lync Online? You bet we can. Again, we won’t bother to explain how this all works; that’s a topic for another day. However, in Office 365 you can manage licenses (in part anyway) by indicating which licenses should be disabled. That’s done by creating a new licensing options object, like this one:

$disabledLicenses = New-MsolLicenseOptions -AccountSkuId "litwareinc:ENTERPRISEPACK" -DisabledPlans "MCOSTANDARD","EXCHANGE_S_ENTERPRISE"

What we’ve done here is simply say that, for the litwareinc domain (which has purchased the Enterprise licensing pack) we want to disable two plans: Lync (MCOSTANDARD) and Exchange (EXCHANGE_S_ENTERPRISE). Note that this command, by itself, doesn’t disable these licenses for any user. Instead, it creates a generic user license in which both Lync and Exchange have been disabled. We can then take that generic user license and assign it to an actual person:

Set-MsolUserLicense -UserPrincipalName "kenmyer@litwareinc.onmicrosoft.com" -LicenseOptions $disabledLicenses

If we run that command and then take a second look at Ken’s user licenses we should see something that looks like this:

ServicePlan                      ProvisioningStatus
-----------                      ------------------
YAMMER_ENTERPRISE                None
RMS_S_ENTERPRISE                 Success
OFFICESUBSCRIPTION               Success
MCOSTANDARD                      Disabled
SHAREPOINTWAC                    Success
SHAREPOINTENTERPRISE             Success
EXCHANGE_S_ENTERPRISE            Disabled

Voila! Both Exchange and Lync Online have been disabled.

Viewing Office 365 licensing information for multiple users

Admittedly, Office 365 user licensing can be a little complicated. But that has nothing to do with Office 365; instead, it’s because, well, Office 365 user licensing can be a little complicated. After all, there are different license packs available through Office 365, and users can be assigned as many (or as few) of the individual product licenses as you see fit. Keeping track of all of that isn’t easy, especially in light of the fact that the Office 365 Admin center only allows you to view license details for one user at a time. Would you like a list of all the users who have been assigned a license for Lync Online? Of course you would. But the Admin center can’t readily supply that.

But Windows PowerShell can. Remember the index numbers that we talked about in the Working with Office 365 user licenses section? If you do, then you might remember that, in our license pack, Lync Online has an index number of 3. That means we can use this admittedly-cryptic looking line of code to return a list of all the users who have been issued a license for Lync Online:

Get-MsolUser | Where-Object {$_.isLicensed -eq $true -and $_.Licenses[0].ServiceStatus[3].ProvisioningStatus -ne "Disabled"}

And yes, it’s definitely a little complicated. But it does return the information you asked it to return:

UserPrincipalName                     DisplayName           isLicensed
-----------------                     -----------           ----------
ZrinkaM@litwareinc.onmicrosoft.com    Zrinka Makovac        True
FabriceC@litwareinc.onmicrosoft.com   Fabrice Canel         True
AnneW@litwareinc.onmicrosoft.com      Anne Wallace          True
AlexD@litwareinc.onmicrosoft.com      Alex Darrow           True

If you prefer, you could also get back a list of all the users who haven’t been issued a license for Lync Online:

Get-MsolUser | Where-Object {$_.isLicensed -eq $true -and $_.Licenses[0].ServiceStatus[3].ProvisioningStatus -ne "Enabled"}

That will bring back a totally different list of users:

UserPrincipalName                     DisplayName           isLicensed
-----------------                     -----------           ----------
BonnieK@litwareinc.onmicrosoft.com    Bonnie Kearney        True
BrianJ@litwareinc.onmicrosoft.com     Brian Johnson         False

But what if we don’t want to know about Lync Online licenses; what if you want to know about SharePoint Online licenses? Well, if you look back at the licensing table, you’ll see that SharePoint Online licenses have an index number of 5. Our previous code example used an index number of 3 (the index number for Lync Online) when we specified the ServiceStatus property:

Get-MsolUser | Where-Object {$_.isLicensed -eq $true -and $_.Licenses[0].ServiceStatus[3].ProvisioningStatus -ne "Disabled"}

To get back SharePoint Online licenses, just replace the 3 with a 5:

Get-MsolUser | Where-Object {$_.isLicensed -eq $true -and $_.Licenses[0].ServiceStatus[5].ProvisioningStatus -ne "Disabled"}

It really is that easy.

For more information, take a look at the article License Users for Office 365 Workloads. Does it take a little bit of effort to master the licensing options available to you using Windows PowerShell? Yes, it does. Is it worth that little bit of effort in order to be able to take advantage of the licensing options available to you using Windows PowerShell? That’s really up to you to decide.

But: yes.

A quick note regarding positional parameters and Office 365

The Azure Active Directory cmdlets are different than the Exchange and Lync Online cmdlets, at least when it comes to working with individual user accounts. For example, with Lync Online and the Get-CsOnlineUser cmdlet, you can include the Identity parameter in your command or you can leave out the Identity parameter. In other words, these two commands both work, and they both return the exact same information:

Get-CsOnlineUser -Identity "kenmyer@litwareinc.onmicrosoft.com"
Get-CsOnlineUser "kenmyer@litwareinc.onmicrosoft.com"

But that’s not true for the Azure Active Directory cmdlets. This command works:

Get-MsolUser -UserPrincipalName "kenmyer@litwareinc.onmicrosoft.com"

Note

We used the UserPrincipalName parameter here because Get-MsolUser doesn’t have an Identity parameter.

But this command does not work:

Get-MsolUser "kenmyer@litwareinc.onmicrosoft.com"

Why not? Without going into a lot of technical detail, many of the Lync Online and the Exchange cmdlets configure the Identity parameter as a “positional parameter.” That means that (in these cases, anyway), if you don’t specify a parameter name (like –Identity) the cmdlet assumes that the very first parameter in the command is the Identity parameter. As long as you start off by specifying the user identity, you can either use the –Identity parameter or not use it. Either way works:

Get-CsOnlineUser -Identity "kenmyer@litwareinc.onmicrosoft.com"
Get-CsOnlineUser "kenmyer@litwareinc.onmicrosoft.com"

The Azure Active Directory cmdlets don’t support positional parameters, however. Suppose you include a value without an accompanying parameter:

Get-MsolUser "kenmyer@litwareinc.onmicrosoft.com"

In that case, you’ll get an error message like this one:

Get-MsolUser : A positional parameter cannot be found that accepts argument 'kenmyer@litwareinc.onmicrosoft.com'.

Note, too that Exchange and Lync Online let you refer to users in several different ways. For example, all of these Exchange commands return the same mailbox information:

Get-Mailbox -Identity "Ken Myer"
Get-Mailbox -Identity "kenmyer@litwareinc.onmicrosoft.com"
Get-Mailbox -Identity "kenmyer"

Those commands use the user’s Active Directory display name; his or her user principal name; and his or her email alias, respectively. Any one of those Identities will work. But that’s with Exchange, and with Lync Online. For the most part, Azure Active Directory requires you to use the use principal name and only the user principal name:

Get-MsolUser -UserPrincipalName "kenmyer@litwareinc.onmicrosoft.com"

Note

Well, technically, you can use the ObjectId parameter. But that requires you to enter the GUID (globally unique identifier) assigned to the user account. For example:
Get-MsolUser –ObjectId "62e90394-69f5-4237-9190-012177145e10"
We’ll let you decide for yourself whether to use UserPrincipalName or ObjectId.

Admittedly, that might be a lot to absorb, at least for someone new to Windows PowerShell. If you are new to Windows PowerShell you might want to take a look at our introductory article on working with parameters.

See Also

Best ways to manage Office 365 with Windows PowerShell