Using Teams from a browser with 3rd-party cookies blocked

Here’s a quick one that should help some folks.

We recently enabled Office365 teams for a group of testers in our environment.  A couple of our users, who use Linux as their primary desktop OS, noted that running with 3rd party cookies blocked in their web browser prevents Teams from loading successfully.

Working with Microsoft, we identified a group of exceptions that can be added to Firefox to allow Teams to load up with a 3rd-party cookie block in place.  Here they are!

https://.asm.skype.com
https://login.microsoftonline.com
https://.teams.microsoft.com
https://.infra.lync.com
https://.teams.skype.com
https://.sfbassets.com
https://.skypeforbusiness.com

Make sure to enter them exactly as listed.

Linux desktop users are restricted to the web interface only since there is no desktop client for Linux like there is for other platforms.  If you agree that there should be one, please go vote for this uservoice item to encourage Microsoft to put one out.

Advertisements

Enabling or Disabling Specific Services Within Your Office365 License using Powershell

As I’ve discussed in previous posts, an Office365 “License”, which Microsoft refers to as an AccountSkuID, can be conceptualized as a bundle of services which make up that license offering.  For example, in the educational tenant that I am working with at the moment, the license “STANDARDWOFFPACK_STUDENT” can grant a person access to a number of services, such as Exchange Online, Sharepoint Online, OneDrive, the Office web apps, Skype for Business, and a few other things.

A frequent request I’ve had is for a way to easily turn on or off specific services for a user or a set of users.  This is easy enough to do via the Office365 admin portal by flipping the toggles on the screen, but that obviously won’t scale.  Also, the trick is to make sure that you toggle the setting for the one service plan you are looking for while leaving all of the other service plans in their current states.

The approach that I’ve settled on to manipulate a single service plan’s status within an Office365 license is as follows:

  • Read the target user’s object from AAD using get-msoluser.
    $userObject = get-msoluser -UserPrincipalName $userPrincipalName
  • Create a hashtable of ServicePlan:ProvisioningStatus values for all of the service plans in the user’s current license.
    $plans = @{}
    $userObject.licenses.servicestatus | % { $plans.add($_.serviceplan.servicename, $_.provisioningstatus) }
  • Look for a key in the hashtable you just created which matches the name of the service plan that we are looking for and set it to the desired value.  In this example, we are disabling the service plan by changing it from “Success” to “Disabled” in the hashtable.
    if ($plans.get_item($targetServicePlan) -eq "Success") {
        $plans.set_item($targetServicePlan,"Disabled")
    }
  • Use the values in the updated hashtable to build a new licenseOptions object with the updated set of disabled service plans.
    The New-msolLicense opject seems to be very picky about the value passed to the disabledPlans parameter.  The only way that I have found which works consistently is to create a list (array) with each item in the list being a service plan name.  Some sources seem to suggest that a comma-separated string will work but I haven’t had much luck with that.

    $disabledPlans = @()
    $plans.Keys | % { if ($plans.get_item($_) -eq "Disabled") { $disabledPlans += $_ } }
    if ($disabledPlans) {
        $licenseOptions = new-msolLicenseOptions -AccountSkuId $baseLicense -DisabledPlans $disabledPlans -verbose
    } else { # If there is nothing on the list of disabled services
        $licenseOptions = new-msolLicenseOptions -AccountSkuId $baseLicense
    }
  • Use Set-msoluserlicense to apply the updated license information to the target user.
    get-msoluser -UserPrincipalName $userObject.userprincipalname | Set-MsolUserLicense -LicenseOptions $licenseOptions

You can find a pair of Powershell scripts named enable-O365ServicePlan.ps1 and disable-O365ServcicePlan.ps1, which demonstrate this approach, at my GitHub repo.  The scripts perform a series of checks to make sure that the target user is in the correct state before any changes are made.

A limitation of these scripts is that they only handle cases where the target user has a single license assigned to them.  While a single license is the most common configuration, users may also have more than one license assigned and the scripts do not handle that use case.

Using Powershell custom tables to get more useful license usage information from O365

When you want to check the number of licenses in your O365 environment, you use the command get-msolaccountsku, which returns a set of information on the licenses that are part of your environment.  This shows the total number of licenses, the number that have been assigned to users (“consumed”) and the number of licenses that are in a warning state.

While working with a customer that has a number of active SKU ID’s, I needed to improve on this to add a column which has a count of unassigned licenses for easy reference, so here’s a Powershell script which is also a simple example of how you can use custom table formats to generate custom output on the fly.

Most of the format entries are a straight replica of what comes back from the get-msolaccountsku command but the line highlighted in red does a calculation to show the number of unassigned licenses for that SkuID.  The expression element of a table format is in the form of a script block so you can do some really interesting stuff by inserting whatever code you want.  Inside the block, the $_ variable refers to the object that the table is processing at that particular moment

# get-o365licensecounts.ps1
#
# Outputs license information for O365 including a column showing # of unassigned licenses by SKU
#
# Format string to define the table
$f = @{expr={$_.AccountSkuID};label="AccountSkuId"},
 @{expr={$_.ActiveUnits};label="Total"},
 @{expr={$_.ConsumedUnits};label="Consumed"},
 @{expr={$_.activeunits-$_.consumedunits};label="Unassigned"},
 @{expr={$_.WarningUnits};label="Warning"}

# output the info using the format we just defined.
# sorted by active units -descending.
Get-MsolAccountSku | sort activeunits -desc | ft $f -auto

Default output from get-msolaccountsku:..

… and with the script using the custom format…:

Much better.

For more information on how custom tables work, see this TechNet article.

Want to log on to Office365 with your email address instead of your UPN? AlternateLoginId function with ADFS on WS2012R2 is just what you’ve been waiting for.

[ UPDATE 27-FEB-2015:  Added “Known Issues” Section and link to KB article. ]
[ UPDATE 13-JUN-2014 with some additional information about infrastructure requirements. ]

A few weeks ago, Microsoft announced that an interesting new capability has been added to ADFS if you use WS2012R2.  The new function is called “Alternate Login ID” and allows you to configure your ADFS server to treat the value entered in the username field not only as a UPN or domain\username but also to perform an LDAP query for that value against a specified attribute across one or more AD forests to identify which AD has a user object which matches.  If you have a multiforest environment with Office365 and/or don’t like the idea of having to change your UPN’s to use federated AuthN with Office365, this is exactly what you’ve been waiting for. The primary goal here is to remove a common complaint about using ADFS with Office365, which is an assumption on the part of Office365 that the userPrincipalName value in your AD is the same as a person’s UPN in Office365.  For most customers that I have worked with on implementing Office365 with federated AuthN, this has required changing the UPN’s of users who will use Office365 services which is a relatively low-risk action but still presents execution challenges. The new function is enabled by running a command like this one:

Set-AdfsClaimsProviderTrust -TargetIdentifier "AD AUTHORITY" -AlternateLoginID mail -LookupForests contoso.com,fabrikam.com

This command specifies what the attribute name is that should be used — mail is recommended — and the list of AD forests that the lookup should be performed against.  I’ve found that you need to specify the forest root domain if the target AD is a multidomain environment even if the users that you’re looking for are in a subdomain. The ADFS server(s) must be able to reach Global Catalog servers in the target forest so make sure that your A records for the global catalogs (gc._msdcs.contoso.com) are correct. This document has lots of details about how this works and a nice flow chart of how authentication is performed with AlternateLoginId enabled, but what essentially happens is:

  1. User provides username and password strings to ADFS
  2. ADFS performs an LDAP query against the AD forests provided to see if any of them has a user where the specified user attribute (like “mail”) matches the username value provided by the user:
    1. IF one and only one AD responds with a matching user object, ADFS proceeds with authentication against that user object.
    2. IF no match is found in any AD, ADFS tries again, treating the username string provided as a UPN or domain\username combination.
    3. IF more than one AD responds with a match, the authentication fails and an error message is logged.

A new claim is returned by ADFS called http://schemas.microsoft.com/ws/2013/11/alternateloginid which contains the alternate login ID.

HOWEVER, turning on AlternateLoginId is not enough by itself to make things work with Office365 and ADFS!  You still need to make sure that Office365 UPN’s are configured correctly and also make a configuration change to the claim rules created in ADFS for Office365 to make everything line up. Office365 UPN must match the value that ADFS is sending for the alternateLoginId In order to log in to Office365, the federation service needs to send a claim containing the userPrincipalName (UPN) of the user.  The default configuration for ADFS is to simply send the UPN of the on-premise user to Office365, which is why you need to make sure that the UPN in AD matches their Office365 UPN.

The default behavior of the Dirsync tool is to set the UPN of a user in the cloud to match their Active Directory UPN so everything works fine if your AD UPN’s use routable domain names and you use an unmodified ADFS environment. HOWEVER, with AlternateLoginId enabled, ADFS will be sending the value of the specified attribute — usually “mail” — as the UPN so we need to make sure that users in the cloud have their UPN matching that attribute and not their active directory UPN.  While it is possible — but not supported — to tweak the configuration of Dirsync to map these attributes, Dirsync may not be able to make this change because there are limitations on the ability to change a user’s UPN in Azure AD.

ADFS Claim Rule Change required: You must also update ADFS to send the value of the mail attribute as the UPN value instead of sending the userPrincipalName.  To do this, open the first claim rule for Office365 on ADFS and change the default rule from this:

c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]
 => issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/claims/UPN", "http://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableID"), query = "samAccountName={0};userPrincipalName,objectGUID;{1}", param = regexreplace(c.Value, "(?<domain>[^\\]+)\\(?<user>.+)", "${user}"), param = c.Value);

… to this (changed value is in red):

c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]
 => issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/claims/UPN", "http://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableID"), query = "samAccountName={0};mail,objectGUID;{1}", param = regexreplace(c.Value, "(?<domain>[^\\]+)\\(?<user>.+)", "${user}"), param = c.Value);

ImmutableID note:  If you are using a custom identity sync solution to Office365 such as FIM with the Azure Active directory Connector and your implementation requires you to provide your own ImmutableID value, you will need to update the value for the immutableId claim sent by ADFS as well as the UPN claim.

Infrastructure and connectivity requirements.  (Added 13-JUN-2014)

  • The “lookupdomain name(s) specified must point to the forest root domain, even if the domain that the target users are in is a subdomain.
  • You must be able to reach a server that is a global catalog in the target forest root domain on port 389 in order for the LDAP lookup to succeed.
  • Make sure that all DNS SRV records are in good shape for all AD’s in play.

Prerequisites:  KB2919355, which is a major update for WS2012R2, adds the new capability.  Also, you must install KB2919422 first.

References for additional detail:  Configuring Alternate Login ID and another detailed description of how AlternateLoginId works.

Known Issues:  (Added 27-FEB-2015)
There are a set of known issues that occur when the UPN of the user in AzureAD/O365 doesn’t match the actual UPN of the on-premise user that is associated with it.  Applications which make their own direct calls to AD after authenticating to AAD, such as the desktop Lync client, are most likely to be affected.  This can result in multiple authentication popups being presented to the user where the user must enter their on-premise identity — either domain\username or actual on-premise UPN — to proceed.  For more information on this, see this KB article.

Moving a mailbox from one user to another in Office365

[ IMPORTANT UPDATE March 2015:  Microsoft deprecated the procedure for moving mailboxes from one user to another which was described in this post and also removed the get-removedmailbox Powershell cmdlet on which it depended.  

The current approach to this seems to be built around the New-RestoreMailboxRequest powershell cmdlet, where the idea is that you take the mailbox that was deleted from user A and restore its content to a mailbox for user B.  

Microsoft’s current blog post discussing this topic can be found here.

The text that was originally on this page has been deleted because following those directions with today’s Exchange Online environment would result in data loss.  I have it on my to-do list to do some experimentation and document how to do this using today’s tools. ]

Provisioning two Office365 tenants from one AD: Making it work with Dirsync

[ UPDATE:  A new version of Dirsync was released in June 2013 which uses the username MSOL_AD_SYNC_ followed by a random hex value in order to make the username unique.  This helps with the two-accounts-with-the-same-username issue but the basic principle of filtering/scoping the two Dirsyncs still applies so I’m leaving this post “up”. ]

I recently assisted an educational customer who had two independent live@EDU tenants with upgrades to Office365.  They were previously provisioning users into the two tenants using two separate management agents on an old MIIS 2003 server  and keep all users in a single AD.  Therefore, we needed to find a way to make things work using only the Dirsync tool provided by Microsoft.

Dirsync is basically a preconfigured version of FIM 2010 which has two management agents in it:  one to connect to an AD and another to connect to Office 365/Azure AD.  What we needed to figure out was how to get two Dirsync installations to cooperate while working from a single source AD.

Here’s how I approached the problem.

1)  How to allow two Dirsync installations to connect to the same source AD:

Getting two copies of Dirsync to both talk to the same AD is easy.  When you run the Dirsync configuration wizard, it creates a domain account called MSOL_AD_Sync which is assigned a randomized password.  Obviously, running the installer for Dirsync #2 overwrites the password used by Dirsync #1 so the solution was to set up Dirsync #1, get it working properly (see below) and then repeat the process with Dirsync #2.  Then, set the password on the MSOL_AD_Sync account to a known value and update the configuration on both Dirsync installations to use that password.  Piece of cake!

2)  How to get two Dirsync installations to provision only the “right” users from the source AD.

I handled this one by taking advantage of one of the few supported customizations to Dirsync:  Using an attribute to limit the objects that Dirsync will handle.  

The first part of this task is to find a way to label all users with a value that indicates what tenant they should be synchronized to.  In my case, since users are imported into MIIS from two separate SQL databases — one for each set of users — I added a flow to the SQL server MA’s to include a value which reflected the user’s origin.  For example, users arriving from the database for students from database A were labeled as belonging to A and similarly for students arriving from database B.

At this point I had MIIS set up so that every user had a label to show where they came from… but this important information was still only within MIIS.

Next, I added a flow to the MIIS management agent for AD which copies the point-of-origin value into the extensionAttribute15 attribute on the matching AD user object.  Now I had  every user in AD labeled with where they belonged.  Progress!

The last step was to configure the two Dirsync installations to each EXCLUDE the “wrong” users.  The process for doing this involves creating a “connector filter” entry within the SourceAD management agent in each Dirsync that matches the value that is applied to users that you don’t want to sync.  This is a fully supported customization for Dirsync and is documented at http://technet.microsoft.com/en-us/library/jj710171.aspx.  An example of how this looks is in the screen shot below.  In this case, any user in AD with the value “A” in extensionAttribute15 will not be processed by Dirsync.

2-dirsyncs-filterA

While doing so isn’t an absolute requirement, I strongly recommend that you make these filter modifications after Dirsync has been configured but BEFORE the first synchronization run so you don’t create a bunch of stuff in Office365 that later needs to be cleaned up.

How this looks when you turn the crank — and ongoing impact to Dirsync:

When you run Dirsync the first time, it will load all users in your AD (“listed as Adds”).  This is normal.  Then, the filter will be applied and you will see a number of objects listed as filtered disconnectors.  These are the objects that Dirsync skipped when processing them because they matched the filter.

Then just verify in your O365 tenant that the right users have been synchronized and, if necessary, check your filters if you are still seeing things that shouldn’t be there.  In my case, I had to add an extra filter condition to also exclude users with no value set in extensionAttribute15 to keep out other non-student accounts that were in AD.

NOTE:  Because Dirsync will re-check all of these disconnectors every time it runs a processing cycle, this approach will increase the load on the Dirsync server and make processing take longer.  For the customer that I was working with, with a total of about 30,000 users between the two tenants, this has not been a problem.