Pages

Showing posts with label O365. Show all posts
Showing posts with label O365. Show all posts

Monday, December 26, 2022

Updated: Create an automated report for Office 365 / Microsoft 365 license usage with friendly names using Azure a Function App (using a system assigned managed identity) and Logic Apps

One of my colleagues who used my previous blog post:

Create an automated report for Office 365 / Microsoft 365 license usage with friendly names using Azure a Function App and Logic Apps
https://terenceluk.blogspot.com/2022/07/create-automated-report-for-office-365.html

… recently informed me that his Function App would fail to run every couple of months due to the issue I mentioned in my other blog post:

Azure Function App fails with: “ERROR: Assembly with same name is already loaded”
https://terenceluk.blogspot.com/2022/10/azure-function-app-fails-with-error.html

After giving the problem a bit of thought, what I recommended was to change the authentication for connecting to Microsoft Graph (Connect-MgGraph) in the function app from certificate authentication to using a Managed Identity instead. This post serves to provide the alternate steps for the setup.

Step Configurations that are no longer needed

The following are the changes to the steps in my previous blog post:

Create an automated report for Office 365 / Microsoft 365 license usage with friendly names using Azure a Function App and Logic Apps
https://terenceluk.blogspot.com/2022/07/create-automated-report-for-office-365.html

Step #1 - Creating a Service Principal for App-Only authentication for Microsoft Graph PowerShell SDK (Connect-MgGraph)
This step will no longer be required.

Step #3 – Create a Function App that will retrieve Office 365 / Microsoft 365 license usage with friendly names and return it in HTML format
As we will no longer be using certificate based authentication, we will not need to create the application settings appID and WEBSITE_LOAD_CERTIFICATES.

Step Configurations Additions and Changes

Step #2 – Create a Storage Account Container that will provide the CSV file containing the product friendly names
The reason why I opted to download the CSV file that Microsoft provides which contain the product friendly names is because the link may change over time but for this blog post, I will use the direct link to download.microsoft.com (https://download.microsoft.com/download/e/3/e/e3e9faf2-f28b-490a-9ada-c6089a1fc5b0/Product%20names%20and%20service%20plan%20identifiers%20for%20licensing.csv)

Step #3 – Create a Function App that will retrieve Office 365 / Microsoft 365 license usage with friendly names and return it in HTML format
Since we’ll be using Managed Identity for authentication, we’ll be adding the steps here.

The following are the steps for the new configuration.

Step #1 - Creating a Service Principal for App-Only authentication for Microsoft Graph PowerShell SDK (Connect-MgGraph)

Step #2 – Create a Storage Account Container that will provide the CSV file containing the product friendly names

Step #3 – Create a Function App that will retrieve Office 365 / Microsoft 365 license usage with friendly names and return it in HTML format

Proceed to create the new Function App as described in my previous post:

Create a Function App that will retrieve Office 365 / Microsoft 365 license usage with friendly names and return it in HTML format. This Function App collects the data that will in turn be call by a Logic App to generate an email and send the report off to an email address.

image

Proceed to create a Function App with the following parameters:

Publish: Code
Runtime stack: PowerShell Core
Version: 7.2
Operating System: Windows

Configure the rest of the parameters as required by the environment.

image

image

Step #4 – Create a System assigned managed identity for the Function App

With the Function App created, navigate to Settings > Identity and turn on the System assigned status to create a managed identity:

image

image

You should now see a Object (principal) ID created for the function app:

image

Make a note of the Object (principal) ID as well be using it to confirm an Enterprise application is created.

Next, navigate to Azure Active Directory > Enterprise applications, then search for the Object (principal) ID to look for the service principal created:

image

Step #5 – Use PowerShell to grant Graph API permissions to the System assigned managed identity for the Function App

Note the returned result of the service principal and the associated Application ID in the returned result. What normally happens now is when we navigate to the App Registration blade, locate the object with the Application ID then configure the API Permissions blade. However, given that this is a managed identity, you will not find the entry in the App Registration list and navigating to the Permissions blade of the Enterprise Application will not allow you to grant API permissions:

image

A quick search will return the following Microsoft blog post explaining the process:

Grant Graph API Permission to Managed Identity Object
https://techcommunity.microsoft.com/t5/integrations-on-azure-blog/grant-graph-api-permission-to-managed-identity-object/ba-p/2792127

As described in the blog post above, PowerShell is required to assign the permissions but while the instructions are fairly straight forward, the cmdlets did not work for me as of December 25, 2022 (the blog post was published on Sept 28, 2021). The problem appears to be due to line:

$AppRole = $GraphServicePrincipal.AppRoles | Where-Object {$_.Value -eq $PermissionName -and $_.AllowedMemberTypes -contains "Application"}

… because the Where-Object is not able to successfully filter the AppRole with the Value and AllowedMemberTypes parameters. This led me down the path to explore using Connect-MgGraph cmdlets that another user provided in the comments below the post but that did not work either because I was not able to use them to configure Managed Identities (they can configure other Enterprise Applications). Here are 2 additional useful sources I found while troubleshooting:

The complete list only shows applications configured in Azure AD as EnterpriseApplications, not Managed Identities:
https://github.com/Azure/azure-powershell/issues/18412

Using New-MgServicePrincipalAppRoleAssignment to configure permissions:
https://copyprogramming.com/howto/how-to-set-microsoft-graph-api-permissions-on-azure-managed-service-identity-with-powershell-7

So after trying numerous changes, what worked is to use both:

  1. Get-AzureADServicePrincipal to retrieve the ObjectId of the Graph API
  2. Get-AzADServicePrincipal to retrieve the App Roles of Graph API so we can assign them using the role’s ID

With the above challenges described, let’s proceed with how we can grant the following API permissions required for the Managed Identity:

  • Directory.Read.All
  • Directory.ReadWrite.All
  • Organization.Read.All
  • Organization.ReadWrite.All

If we were only granting one API permissions then the PowerShell script variables that are required to be defined are:

$TenantID="provide the tenant ID"

$GraphAppId = "00000003-0000-0000-c000-000000000000" <-- Note that this parameter is optional and the provided value here does not need to be changed because this corresponds to Graph API GUID.

$DisplayNameOfMSI="Provide the Function App name"

$PermissionName = "Directory.Read.All"

Since we have more than one permission to assign, we’ll be storing the required permissions in an array as such:

$TenantID="provide the tenant ID"

$GraphAppId = "00000003-0000-0000-c000-000000000000"

$DisplayNameOfMSI="Provide the Function App name"

$permissionsNames = @(

'Directory.Read.All'

'Directory.ReadWrite.All'

'Organization.Read.All'

'Organization.ReadWrite.All'

)

The script to configure the appropriate managed identity permissions can be found at my GitHub here: https://github.com/terenceluk/Azure/blob/main/PowerShell/Configure-Managed-Identity-API-Permissions.ps1

The following is a sample output once the permissions successfully granted via the PowerShell cmdlets:

image

The required permissions should now be listed in the Permissions blade of the Enterprise Application representing the Managed Identity:

image

Step #6 – Configure Function App to download required dependencies

Proceed to configure the requirements.psd1 file in the App files blade so the appropriate modules will be loaded for the PowerShell code in the function app. Note that I choose to import the specific modules required for the cmdlets Connect-MgGraph (Microsoft.Graph.Authentication) and Get-MgSubscribedSku (Microsoft.Graph.Identity.DirectoryManagement) because the Microsoft.Graph modules has 38 sub modules in it and I was not able to get the function app code to run by importing that.

'Az.Accounts' = '2.*'
'JoinModule' = '3.*'
'Microsoft.Graph.Identity.DirectoryManagement' = '1.*'
'Microsoft.Graph.Authentication' = '1.*'

image

Navigate to the profile.ps1 and verify that the following lines are uncommented:

if ($env:MSI_SECRET) {

Disable-AzContextAutosave -Scope Process | Out-Null

Connect-AzAccount -Identity

}

image

Step #7 – Create a HTTP trigger Function that will generate the report and turn on Application Insights

Application Insights is extremely useful for troubleshooting issues with the Function App so I would highly recommend turning it on:

image

With the prerequisites configured for the Function App, proceed to create the actual function trigger:

image

Select HTTP trigger as the template and provide a meaningful name:

image

With the trigger created, navigate to Code + Test and paste the following code from my GitHub repo into run.ps1:
https://github.com/terenceluk/Microsoft-365/blob/main/Administration/Get-M365-License-Report-Function-v2.ps1

image

The following are changes you’ll need to apply to the code:

<h2>Client: Contoso Limited</h2>

image

With the function app code in place, proceed to use the Test/Run feature to test it. Note that the function app expects the tenant ID to be passed to it so the Body of the test should include the following:

{

"tenant": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

}

image

The following log entries will be displayed if Application Insights is turned on:

image

Confirm the HTTP response code of 200 OK and the HTTP response content results:

image

Note that I have experienced an odd behavior where running the Test/Run feature displays a 503 Service Unavailable HTTP response code as shown in the screenshot below:

image

Step #8 – Create a Logic App that is scheduled and will call the Azure Function App to retrieve the license report and then send it out

I won’t go into the details for the Logic App setup as it would be repeat from my previous post so please refer to it to set up the triggering of the Function App and send the report out via email.

Create an automated report for Office 365 / Microsoft 365 license usage with friendly names using Azure a Function App and Logic Apps
https://terenceluk.blogspot.com/2022/07/create-automated-report-for-office-365.html

Thursday, November 17, 2022

Setting up BitTitan to migrate mailboxes from O365 to another O365 tenant fails source authentication with the error: "Your migration failed while checking source credentials. The request failed. The remote server returned an error: (401) Unauthorized."

It has been a while since I’ve been involved with Office 365 mail migrations but I was recently contacted by a colleague who was setting up BitTitan’s MigrationWiz for a migration and could not figure out why he was not able to authenticate so I hopped on to help. The search results from Google directed me to various documentation provided by BitTitan but none of them lead me to the right solution. I don’t usually use YouTube for troubleshooting as most of us probably feel it takes too long to watch a video as compared to reading a blog post like this but the following video is where I eventually found the answer:

How to solve BitTitan MigrationWiz Error 401 Unauthorized in 2022
https://www.youtube.com/watch?v=iI35AJrGYiw

This blog post serves to help anyone who might encounter the same problem quickly find the answer.

Problem

You attempt to use the Verify Credentials feature in MigrationWiz after setting up the source and destination tenants but receive the status: Failed (Verification)

image

Navigating into one of the accounts display the following error message:

Your migration failed while checking source credentials. The request failed. The remote server returned an error: (401) Unauthorized.

image

Solution

The reason why the environment I was troubleshooting in has this failure is because Microsoft had started disabling basic authentication for Office 365 that affects the EWS service that MigrationWiz relies on (3 minute mark in the video). This can be confusing because if you navigate to Settings > Org Settings > Modern Authentication, you’ll see that it states basic authentication is enabled for various services (including Exchange Web Services). The problem here is that this only applies to the modern Outlook client, which MigrationWiz isn’t.

image

To remediate this, click on the Help & support button at the bottom right corner of the administration console:

image

Then type in the following string to search:

diag: enable basic auth in exo

imageimage

Proceed to click on the Run Tests button:

image

Assuming basic authentication is disabled, we should be provided with a drop down menu box to select a service to enable:

image

Select Exchange Web Services (EWS) to enable the MigrationWiz dependent service, then click on Update Settings:

image

The following message will be displayed:

Run diagnostics
Basic authentication has been re-enabled for the selected protocol.

The Basic authentication blocked applications setting has been updated. You should be able to use Basic authentication with the selected protocol within the next hour.

image

Proceed to try and verify the credentials in an hour or so and the process should complete successfully.

Hope this helps as it took me a bit of time to figure this out.

Tuesday, June 8, 2021

Skype for Business Online (SkypeOnlineConnector) PowerShell connections are blocked and Set-CsUser no longer works

Problem

You’ve noticed that the following cmdlets fail with the error message indicating Skype for Business Online (SkypeOnlineConnector) PowerShell connections are blocked:

Import-Module SkypeOnlineConnector

$sfbSession = New-CsOnlineSession

New-PSSession : [admin0b.online.lync.com] Processing data from remote server admin0b.online.lync.com failed with the

following error message: Skype for Business Online PowerShell connections are blocked. Please replace the Skype for

Business Online PowerShell connector module with the Teams PowerShell Module. Please visit https://aka.ms/sfbocon2tpm

for supported options. For more information, see the about_Remote_Troubleshooting Help topic.

At C:\Program Files\Common Files\Skype for Business

Online\Modules\SkypeOnlineConnector\SkypeOnlineConnectorStartup.psm1:254 char:16

+ ... $session = New-PSSession -Name $psSessionName -ConnectionUri $Connec ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : OpenError: (System.Manageme....RemoteRunspace:RemoteRunspace) [New-PSSession], PSRemotin

gTransportException

+ FullyQualifiedErrorId : IncorrectProtocolVersion,PSSessionOpenFailed

PS C:\WINDOWS\system32> Import-PSSession $sfbSession

Import-PSSession : Cannot validate argument on parameter 'Session'. The argument is null. Provide a valid value for

the argument, and then try running the command again.

At line:1 char:18

+ Import-PSSession $sfbSession

+ ~~~~~~~~~~~

+ CategoryInfo : InvalidData: (:) [Import-PSSession], ParameterBindingValidationException

+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.ImportPSSessionCommand

image

As per the following Microsoft documentation:

Migrating from Skype for Business Online Connector to the Teams PowerShell module
https://aka.ms/sfbocon2tpm

Skype for Business Online (SkypeOnlineConnector) PowerShell connections will be rejected / blocked starting May 17, 2021 and to use Teams PowerShell Module for administration. However, attempting to use Connect-MicrosoftTeams and then executing the Set-CsUser cmdlet to enable a user for Enterprise Voice fails indicating it is not recognized:

image

Solution

One of the reasons why the Set-CsUser or any Cs- cmdlets will not work even if the MicrosofTeams module is used is if an old version is used. In order for the legacy Cs- cmdlets to be available, Teams PowerShell Module 2.0 or later needs to be installed and imported. The example above has an older module imported:

Get-Module

image

To update the module to the latest version, execute the following:

Uninstall-Module -Name MicrosoftTeams

Install-Module -Name MicrosoftTeams -RequiredVersion 2.0.0 -AllowClobber

Import-Module -Name MicrosoftTeams

image

The legacy Cs- cmdlets should now work:

Import-Module MicrosoftTeams

Connect-MicrosoftTeams

$usernameUPN = "tluk@contoso.com"

$extension = "tel:+7899"

Set-CsUser -Identity $usernameUPN -EnterpriseVoiceEnabled $true -HostedVoiceMail $true -OnPremLineURI $extension

Get-CsOnlineUser -Identity $usernameUPN | FL *uri

Grant-CsOnlineVoiceRoutingPolicy -Identity $usernameUPN -PolicyName "Toronto"

Grant-CsTenantDialPlan -PolicyName Toronto -Identity (Get-CsOnlineUser $usernameUPN).SipAddress

image

Saturday, November 21, 2020

Configuring Office 365 license app options with PowerShell

I’ve recently had to perform a bit of licensing management for a client because they had a set of users who have Office 365 E1 licenses assigned but the Apps configured were inconsistent across the board. Using the Microsoft 365 admin center to perform this is possible but isn’t the most efficient method for large batches.

https://admin.microsoft.com/

image

What I ended up using was PowerShell for the assignments and thought it would be useful to share the PowerShell cmdlets for some common licensing tasks that may be useful for others.

All of the cmdlets below require you to connect to the O365 tenant via Connect-MsolService cmdlet.

Obtaining licenses available in the tenant

The cmdlet to obtain the licenses available in the tenant is Get-MsolAccountSku and as the output below shows, the AccountSkuId name will not directly reflect what you see in the portal. Case in point, STANDARDPACK is actually the name for Office 365 E1:

image

Most of the names for these SKUs can be found at the following TechNet article:

Product names and service plan identifiers for licensing
https://docs.microsoft.com/en-us/azure/active-directory/enterprise-users/licensing-service-plan-reference

Obtaining the enabled or disabled apps for the license assigned to a user

Each Office 365 license actually bundles a group of applications that can be enabled or disabled for a user. Below is an example of what Apps are available when Office 365 E1 is assigned:

imageimage

The following cmdlet allows us to obtain the Apps and their status for the specified user:

(Get-MsolUser -UserPrincipalName shaejames@contoso.com).Licenses.ServiceStatus

image

Note that this cmdlet will list all the Apps and their status. Success and Disabled is self-explanatory, while PendingProvisioning and PendingActivation is reflected in the follow 3 app entries with the same description:

This app is assigned at the organization level. It can’t be assigned per user.

image

Assigning a usage location and E1 license to a user

Set-MsolUser -UserPrincipalName "ATrott@contoso.com" -UsageLocation BM

Set-MsolUserLicense -UserPrincipalName "ATrott@contoso.com" -AddLicenses "reseller-account:STANDARDPACK"

**Note that the usage location cmdlet is Set-MsolUser

Retrieving a list of all users with E1 license

Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match "STANDARDPACK"}

Enabling or disabling apps for a user assigned with an E1 license

The following are examples of how to enable and disable various applications:

Only disable SWAY and enable all apps

$E1_DefaultApps = New-MsolLicenseOptions -AccountSkuId reseller-account:STANDARDPACK -DisabledPlans SWAY

Set-MsolUserLicense -UserPrincipalName "shaejames@contoso.com" -LicenseOptions $E1_DefaultApps

Disable SWAY and Exchange Online and enable all apps

$DisabledApps=@()

$DisabledApps+="SWAY"

$DisabledApps+="EXCHANGE_S_STANDARD"

$E1_DefaultApps = New-MsolLicenseOptions -AccountSkuId reseller-account:STANDARDPACK -DisabledPlans $DisabledApps

Set-MsolUserLicense -UserPrincipalName "shaejames@contoso.com" -LicenseOptions $E1_DefaultApps

Enable all apps

$DisabledApps=@()

$E1_DefaultApps = New-MsolLicenseOptions -AccountSkuId reseller-account:STANDARDPACK -DisabledPlans $DisabledApps

Set-MsolUserLicense -UserPrincipalName "shaejames@contoso.com" -LicenseOptions $E1_DefaultApps

Disable Skype for Business Online (Plan 2) and Exchange Online and enable all apps

$DisabledApps=@()

$DisabledApps+="MCOSTANDARD"

$DisabledApps+="EXCHANGE_S_STANDARD"

$E1_DefaultApps = New-MsolLicenseOptions -AccountSkuId reseller-account:STANDARDPACK -DisabledPlans $DisabledApps

Set-MsolUserLicense -UserPrincipalName "shaejames@contoso.com" -LicenseOptions $E1_DefaultApps

Set all users with E1 license to disable Skype for Business Online (Plan 2) and Exchange Online (Plan 1) options

$DisabledApps=@()

$DisabledApps+="MCOSTANDARD"

$DisabledApps+="EXCHANGE_S_STANDARD"

Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match "STANDARDPACK"} | Set-MsolUserLicense -LicenseOptions $E1_DefaultApps

Get all users with Microsoft Teams Commercial Cloud and E1 license

Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match "TEAMS_COMMERCIAL_TRIAL" -and ($_.licenses).AccountSkuId -match "STANDARDPACK"}

Get all users with Microsoft Teams Commercial Cloud and E1 license AND remove Microsoft Teams Commercial Cloud license

Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match "TEAMS_COMMERCIAL_TRIAL" -and ($_.licenses).AccountSkuId -match "STANDARDPACK"} | Set-MsolUserLicense -RemoveLicenses reseller-account:TEAMS_COMMERCIAL_TRIAL

Get all users with Microsoft Teams Exploratory and E1 license

Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match "TEAMS_Exploratory" -and ($_.licenses).AccountSkuId -match "STANDARDPACK"}

Get all users with Microsoft Teams Exploratory and E1 license AND remove Microsoft Teams Exploratory license

Get-MsolUser -All | Where-Object {($_.licenses).AccountSkuId -match "TEAMS_Exploratory" -and ($_.licenses).AccountSkuId -match "STANDARDPACK"} | Set-MsolUserLicense -RemoveLicenses reseller-account:TEAMS_Exploratory

------------------------------------------------------------------------------------------------------------------------

I hope these cmdlets will help anyone who may need to undertake a similar task.

Monday, November 2, 2020

Behavior of Microsoft Teams voicemail feature with when the user's mailbox is on an on-premise Exchange Server

Now that working from home has become more popular for organizations during the pandemic, many of the clients I work with have decided to deploy Microsoft Teams’ Direct Routing feature that allows users to receive and make calls out via the PSTN network. A few of the larger organizations I’ve had the opportunity to work with have still kept their messaging on-premise for various reasons and one of the most common complaints I’ve received is the voicemail notification. I still remember researching how it worked for on-premise Exchange Server deployments and found I had to combine several sources to understand what worked and didn’t so this blog post serves as a quick summary of the behavior.

The short story of the type of experience a user with an on-premise Exchange Server mailbox would have when they are enabled for Enterprise Voice in Teams is that voicemail notifications are sent to them via email. The email originates from Office 365 Exchange Online and delivered to the on-premise Exchange server and into the user’s mailbox via SMTP. The only issue I’ve seen where users do not receive this notification is if the organization uses a SPAM service such as Mimecast and it is not configured to allow Office 365 IP addresses for relay (https://community.mimecast.com/s/article/Maintaining-Authorized-Outbound-Addresses) and therefore the emails are stuck in the Exchange Online’s queue failing to be delivered.

Users with an on-premise Exchange Server mailbox will see the following message on their smartphones when they receive a voicemail but unable to do anything else within the menu:

We have your voicemail covered.

You can listen to voicemail or read the transcript.

imageimage

Clicking into the Voicemail menu in the Calls section will display the following:

We can’t get your voicemail right now

Please check back soon.

image

All of the above are default behaviors of a Teams user with an on-premise Exchange Server mailbox and the only way around this is to migrate them to Exchange Online.

More information about this can be found at the follow Microsoft documentation:

Set up Cloud Voicemail for Exchange Server Mailbox Users
https://docs.microsoft.com/en-ca/microsoftteams/set-up-phone-system-voicemail#set-up-cloud-voicemail-for-exchange-server-mailbox-users

Hope this helps anyone looking for an explanation of what works and what doesn’t when a user isn’t on Exchange Online.

Monday, October 26, 2020

Attempting to set immutableId for user throws the error: "Set-MsolUser : Uniqueness violation. Property: SourceAnchor."

Problem

You’re attempting to use the Set-MsolUser cmdlet to configure the immutableId attribute for a user in Azure Active Directory but receive the following error:

PS C:\> Set-MsolUser -UserPrincipalName jsmith@contoso.com -ImmutableId "zxGeOiOTdkivMtgkOsuvKA=="

Set-MsolUser : Uniqueness violation. Property: SourceAnchor.

At line:1 char:1

+ Set-MsolUser -UserPrincipalName jsmith@contoso.com -ImmutableId ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : OperationStopped: (:) [Set-MsolUser], MicrosoftOnlineException

+ FullyQualifiedErrorId : Microsoft.Online.Administration.Automation.UniquenessValidationException,Microsoft.Onlin

e.Administration.Automation.SetUser

PS C:\>

image

Reviewing the properties of the user account that you are trying to assign the immutableID value to confirms that it is null:

Get-MsolUser -UserPrincipalName jsmith@contoso.com | FL immutableId

image

Using Get-MsolUser to search for an account with the immutableID does not return any results:

Get-MsolUser | Where-Object {$_.ImmutableId -eq "zxGeOiOTdkivMtgkOsuvKA=="} | select UserPrincipalName

image

Solution

One of the most common reasons I’ve found for this error is if a deleted user object has the same immutableID assigned to it. A typical scenario would be:

  1. An effort was made to merge on-premise Active Directory accounts with Azure AD but Azure AD Connect created a new account with a random number following the name rather than merge the two accounts
  2. The administrator deletes the new account and attempts to assign the ObjectGUID (converted to base 64) of the on-premise Active Directory account to the Azure AD account

To confirm whether there is an account in the deleted users container, execute the following cmdlet:

Get-MsolUser -ReturnDeletedUsers

image

The following cmdlet can return the UPN along with the immutableID of the user accounts found in the deleted users container:

Get-MsolUser -ReturnDeletedUsers | FL UserPrincipalName,immutableID

Once the account with the conflicting immutableID is identified, the following cmdlet can be used to delete it:

Remove-MsolUser -UserPrincipalName jsmith@contoso.com -RemoveFromRecycleBin

image

With the account removed, you should now be able to assign the immutableID.