Tuesday, August 27, 2013

Adjusting Office 365 licenses in PowerShell

So, we just got hit with Wave 15 finally. This in and of itself was actually something of an accident - Microsoft only allows you to specify one "early adopter" group for testing Office 365 updates, and my boss elected only himself. Further, he realized about three days before our update that Microsoft offers a small notice at the bottom of the upgrade announcement email that you must notify them within 7 days if you wish to postpone your update.

So, we got upgraded in a bit of a hurry.

Now that we're on Wave 15, we have the new Outlook Web Access, which features new topbar buttons for Newsfeed, Sites, and SkyDrive. Well, we're using on-premise SharePoint and have no plans to use SharePoint Online, so those buttons are just going to confuse our user community. It turns out that in order to hide these buttons, you actually have to disable the SharePoint Online (and Office Web Apps) license options for each user that you want to conceal them from.

I was pretty certain I could do this with PowerShell, and it turns out I was right, but not without some gotchas involved. Here's what the final script looks like:

$e1Sku = Get-MsolAccountSku | ? {$_.AccountSkuId -match "STANDARDPACK"}
$e2Sku = Get-MsolAccountSku | ? {$_.AccountSkuId -match "STANDARDWOFFPACK"}
$e3Sku = Get-MsolAccountSku | ? {$_.AccountSkuId -match "ENTERPRISEPACK"}

$e1LicenseOption = New-MsolLicenseOptions -AccountSkuId $e1Sku.AccountSkuId -DisabledPlans SHAREPOINTSTANDARD
$e2LicenseOption = New-MsolLicenseOptions -AccountSkuId $e2Sku.AccountSkuId -DisabledPlans SHAREPOINTSTANDARD, SHAREPOINTWAC

$users = Get-MsolUser | ? {$_.IsLicensed -eq $true}

foreach($user in $users)
{
    foreach($license in $user.Licenses)
    {
        switch($license.AccountSkuId)
        {
            "company:STANDARDPACK"
            {
                Write-Output $user.DisplayName
                $user | Set-MsolUserLicense -RemoveLicenses $e1sku.AccountSkuId -AddLicenses $e2sku.AccountSkuId
                $user | Set-MsolUserLicense -RemoveLicenses $e2sku.AccountSkuId -AddLicenses $e1sku.AccountSkuId -LicenseOptions $e1LicenseOption
                break;
            }
            "company:STANDARDWOFFPACK"
            {
                Write-Output $user.DisplayName
                $user | Set-MsolUserLicense -RemoveLicenses $e2sku.AccountSkuId -AddLicenses $e3sku.AccountSkuId
                $user | Set-MsolUserLicense -RemoveLicenses $e3sku.AccountSkuId -AddLicenses $e2sku.AccountSkuId -LicenseOptions $e2LicenseOption
                break;
            }
        }
    }
}

My boss freaked out seeing this, knowing that removing an Exchange Online license meant the mailbox gets trashed. We spent close to an hour between illustrative tests and dashed alternatives before I finally convinced him that this was safe, and the only option. I'm rather surprised not to see a Set-MsolUserLicenseOptions cmdlet, and simply running Set-MsolUserLicense -LicenseOptions does nothing. It's accepted as valid input, so maybe the cmdlet isn't fully functional. I dunno.

Anyway, you'll notice that I run Set-MsolUserLicense twice. According to MSDN documentation, you can run -RemoveLicenses and -AddLicenses in the same cmdlet and both actions will occur simultaneously, meaning that a user will not be left without a license for any period of time. I tested this on a few accounts and had no issue myself. However, since I want to keep the same license level but merely change the product options, I tried to use the same AccountSkuId in both -AddLicenses and -RemoveLicenses, and it did not work. What I ended up having to do instead was to briefly elevate the user's license level and then re-add the old license with the -LicenseOptions as I had configured them. Without doing this, the cmdlet would always fail insisting that a provided AccountSku was not valid.

No comments:

Post a Comment