Category Archives: Exchange Online

Name must be unique per owning mailbox. There’s already a request with the name

While migrating some public folders to Office 365 Groups, I kept running into issues with one of the target groups:

“De gebruiker XXX heeft al een aanvraag die in behandeling is. Verwijder de bestaande aanvraag en hervat de huidige batch of start een nieuwe batch voor deze gebruiker. –> Name must be unique per owning mailbox. T”

In english you’ll probably see “Name must be unique per owning mailbox. There’s already a request with the name “.

I figured there was a moverequest hanging / not properly cleaned up; but none to be found with get-moverequest, get-migrationuser or get-migrationbatch; all clean!

In the end, it took almost 2 weeks of patience after contacting support until the Exchange Online backend team reset a hanging job on their end. So if you google above errors and come here, check if you have double jobs, if you don’t, request support and make sure they escalate to the product team immediately.

Exchange Online reconnect script v2

A few weeks ago I posted a script that would automatically, periodically, reconnect to Exchange Online. In field testing it would still prompt for credentials after 1-2 days, whatever I did.

So I took a different route and am now rewriting Microsofts’ module on the fly to no longer prompt for credentials. If you use below function to connect to Exchange Online, you should never receive reconnect prompts 🙂

disclaimer: don’t overwrite $o365Creds with invalid creds elsewhere in your script as those are used globally.


function buildResilientExchangeOnlineSession {
    Param(
        [Parameter(Mandatory=$true)]$o365Creds,
        $commandPrefix
    )
    Write-Verbose "Connecting to Exchange Online"
    Set-Variable -Scope Global -Name o365Creds -Value $o365Creds -Force
    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $o365Creds -Authentication Basic -AllowRedirection
    Import-PSSession $Session -AllowClobber -DisableNameChecking
    Write-Verbose "Connected to Exchange Online, exporting module..."
    $temporaryModulePath = (Join-Path $Env:TEMP -ChildPath "temporaryEXOModule")
    $res = Export-PSSession -Session $Session -CommandName * -OutputModule $temporaryModulePath -AllowClobber -Force
    $temporaryModulePath = Join-Path $temporaryModulePath -ChildPath "temporaryEXOModule.psm1"
    Write-Verbose "Rewriting Exchange Online module, please wait a few minutes..."
    [String]$newContent
    $found = $False
    (Get-Content $temporaryModulePath) | % {
        if(!$found -and $_.IndexOf("host.UI.PromptForCredential(") -ge 0){
            $line = "-Credential `$global:o365Creds ``"
            if($line){
                $found = $True
            }
        }
        if($line){
            $newContent += $line
            $line=$Null
        }else{
            $newContent += $_
        }
        $newContent += "`r`n"
    }
    $newContent | Out-File -FilePath $temporaryModulePath -Force -Confirm:$False -ErrorAction Stop
    $Session | Remove-PSSession -Confirm:$False
    Write-Verbose "Module rewritten, re-importing..."
    if($commandPrefix){
        Import-Module -Name $temporaryModulePath -Prefix $commandPrefix -DisableNameChecking -WarningAction SilentlyContinue -Force
        Write-Verbose "Module imported, you may now use all Exchange Online commands using $commandPrefix as prefix"
    }else{
        Import-Module -Name $temporaryModulePath -DisableNameChecking -WarningAction SilentlyContinue -Force
        Write-Verbose "Module imported, you may now use all Exchange Online commands"
    }
    return $temporaryModulePath
}

download: https://gitlab.com/Lieben/assortedFunctions/blob/master/buildResilientExchangeOnlineSession.ps1

 

Exchange Online Reconnect script

I’ve seen and known many scripts that interact with Exchange Online for extended periods of time. After a while, Exchange Online likes it if you reconnect, this can be an Impliciet Authentication popup, or it can simply drop you based on what command you’re using.

If you call the following function every loop in whatever you’re doing, it’ll automatically force a reconnect to Exchange Online every hour (adjustable if you prefer longer):

Edit: read v2 of this post 🙂

Note: if you run this script in an Exchange Shell, something in the Exchange Shell modules will still prompt for reconnects every 1-2 days. In a normal PS window, I’ve verified it working for up to a week until it asks for a reconnect.

Public Folder to Office 365 Groups Migration Script

Earlier, I wrote on a new technet article that details migration to Office 365 groups from on prem public folders. Actually walking through that I noticed some inconveniences I figured I could improve on with a script. The main one being that the endpoint in Office 365 only supports a single Public Folder, excluding child folders.

So I wrote up a script (with resume support) that will map your Public Folders to O365 Groups and migrate them in as many batches as are required, fully automated.

You’ll end up with a nice csv file with all the details. Note:

  1. this script expects you to know what you’re doing!
  2. only tested with Exchange 2010 as source
  3. everything on prem is left untouched
  4. groups are not mail enabled, and security settings are not copied
  5. contacts are not copied
  6. make sure you read the code/in-script instructions between line 1 and line 48, and then if you’re curious, from line 71720

https://gitlab.com/Lieben/assortedFunctions/blob/master/archivePublicFoldersToOffice365Groups.ps1

update 05/01: improved the connection status check + reconnect for remote ExO and fixed report file path auto generation

update 11/01: moved everything to start-job so exchange sessions are always isolated (no prompting after 1-2 days) and added total migration overview display 

update 25/01: exported the remote exchange module and added it as inline code with a modification so it won’t prompt for credentials, nothing else seems to otherwise prevent such prompts. This means the module may not match Microsoft’s if they update Exchange Online. Let me know if that causes issues for you or re-create it yourself with export-pssession and replace.

Setting up Okta User -> Office 365 contact synchronisation

Okta natively does not allow you to sync users to Office 365 contacts; they either exist as users in Office 365, or they don’t exist at all.

In hybrid scenarios where you are doing a staged migration to Office 365, or where you simply manage your contacts in Okta, you may want to populate the Global Address List in Office 365 with your Okta users.

I’ve written a simple solution for this, you will require:

  1. Okta Admin Access (to obtain a token)
  2. Office 365 credentials (to write / modify Contacts)
  3. An Azure Subscription (for automation)

The solution will sync your users in Okta to Office 365, take note of the following: Continue reading Setting up Okta User -> Office 365 contact synchronisation

Migrating Public Folders to Office 365 Groups

Recently, I stumbled upon an article detailing how to migrate on-premises (or online) Public Folders to Office 365 Groups

Of course I had to try that out asap 🙂 I used an older script to make a report of my on prem public folders to pick one below 50GB.

It was mostly a breeze and the interface of Office 365 groups allows users to easily search and administer their old Public Folders. We purposely only use them for archive access, where the IM team manages access to the groups holding PF data. I can really recommend this strategy, especially if you can easily split them up in under 50GB sized groups.

I did have one slight error you may run into:

“MigrationTransientException: Couldn‎’t find a request that matches the information provided. Reason: No such request exists in the specified index. –> Couldn‎’t find a request that matches the information provided. Reason: No such request exists in the specified index. “

Reason for this: The source public folder path is incorrect, make sure your CSV is mapped correctly or your batch will spin forever (or at least longer than I had patience), never completing.

 

 

Provisioning Exchange Online / Office 365 Custom Roles automatically from Okta

Natively, when connected to Office 365, Okta allows you to automatically provision users and/or groups. Additionally, Okta will assign licenses you select, and if configured, set predefined roles in Office 365. This means you have one locus of control, very nice.

Then, Exchange Online allows you to define custom roles where you can scope permissions for your users with far greater granularity compared to the default roles, Okta won’t detect or provision users into these custom roles.

As this was a business requirement for a customer, I coded up a small proof of concept you can schedule that will read membership of selected groups in Okta through the Okta API, then ensure that ONLY those members are in the matching role groups in Exchange Online.

Continue reading Provisioning Exchange Online / Office 365 Custom Roles automatically from Okta

AADSTS165000 after enabling Modern Auth in Exchange Online

If you enable Modern Auth in Exchange Online with Set-OrganizationConfig -OAuth2ClientProfileEnabled $true , and then start seeing this error in Office 2016 or 2013 clients:

AADSTS165000: Invalid request: the request tokens do not match the user context. One or more of the user context values (cookies; form fields; headers) were incorrect or invalid, these values should not be copied between requests or user sessions; always maintain ALL of the supplied values across a complete single user flow. Failure reasons:[Token is invalid;]

You need to re-activate Office.

Copy local AD contacts to O365

Recently I needed a basic method to copy over contacts from a local AD to O365, and in cases where a read-write contact already exists; update it. The scenario made sense, as we were working with multiple source AD’s where some had contacts of each other’s mail users, causing adsync conflicts. Thus we decided to take contacts out of ADsync scope and just copy them once.

The logic of the attached script is as follows:

 

 

 

 

 

 

 

 

Note that the script ONLY imports the displayname, primary and all secondary email addresses, and sets an extra X500 address for the legacy exchangeDN to avoid outlook cache hit misses.

If you need it, here’s a download link:

O365ContactImporter.ps1