Create a ShareGate User mapping file between on Premise AD and o365 / Azure AD

We use ShareGate to migrate content.

We recently started using ShareGate to migrate content from On Premise to SharePoint Online.

When I did this, I found that one of our domain’s users kept showing up as errors in ShareGate – it said it could not find the user in SharePoint Online.

ShareGate has a nice feature for mapping users from one system to users in another – but doing this manually to any scale would be pretty time consuming.

Thankfully, ShareGate lets us save the mappings, which are just XML files with a .sgum file extension.

Wouldn’t it be great if there was a way to automate creating a mapping file like this for everyone in the domain at once?

Have a look at the script below, it pulls all the user accounts from an OU in AD, then looks up each user to find them in MSOL (Office 365 Azure AD) Then grabs the o365 display name and makes the mapping . Any user not found is logged so it can be dealt with separately.

The whole thing is written out as a complete .sgum file, ready to import into ShareGate the next time you migrate!

Note I didn’t figure out the XML stuff in a vacuum – I found an article on to be very helpful and noted it in the script.

# use at your own risk

$users = get-aduser -server -filter * -searchbase "OU=Users,DC=server,DC=domain,DC=COM"

$total = $users.count
$count = 0
$badnames = @()

# from
$dt = get-date -format "yyyyMMdd"
$path = "$(get-location)\UserMap_$dt.sgum"
$XmlWriter = new-object System.XML.XMLTextWriter($path, $null)
$XmlWriter.Formatting = 'Indented'
$xmlwriter.Indentation = 1
$XmlWriter.IndentChar = "`t"

#write the header

$XmlWriter.WriteComment("Start of XML")
$XmlWriter.WriteAttributeString('xmlns:xsd', '')
$XmlWriter.WriteAttributeString('xmlns:xsi', '')

$XmlWriter.WriteComment("Start of main loop")
foreach ($OneUser in $users)
    $count ++
    $SourceAccountName = "DOMAINGOESHERE\$($OneUser.Samaccountname)"
    $SourceDisplayname = $

    $DestinationAccountName = "i:0#f|membership|$($OneUser.UserPrincipalName)"
    #pull the destination user name from MSOnLine
    $DDN = $(get-MSOLuser -userprincipalName $OneUser.UserPrincipalName).Displayname
    #if MSOL not found, length will be zero. in that case use the AD displayname
    if ($DDN.length -eq 0)
       $DestinationDisplayname = $
       $badnames += $OneUser.userprincipalName
       write-host "Warning: $($OneUser.userprincipalName) username Not found in MSOL" -foregroundcolor cyan
       $DestinationDisplayname = $DDN 
       write-host "$count of $total"
    $XmlWriter.WriteAttributeString('AccountName', $SourceAccountName)
    $XmlWriter.WriteAttributeString('DisplayName', $SourceDisplayname)
    $XmlWriter.WriteEndElement() #source

    $XmlWriter.WriteAttributeString('AccountName', $DestinationAccountName)
    $XmlWriter.WriteAttributeString('DisplayName', $DestinationDisplayname)
    $XmlWriter.WriteEndElement() #Destination
    $XmlWriter.WriteEndElement() #mapping
$XmlWriter.WriteEndElement() #mappings
$XmlWriter.WriteEndElement() #UserAndGroupMappings

#finalize the document

$bnpath = "$(get-location)\BadNames_$dt.txt"
$badnames | out-file -filepath $bnpath
notepad $path

– Jack

2 thoughts on “Create a ShareGate User mapping file between on Premise AD and o365 / Azure AD

  1. I really appreciate you creating this documentation! I am, however, having an issue identifying my Azure AD server. I had tried putting one of our on-prem ad servers in the beginning of the script, but it did not work. Do you know how I can point directly to my AD server that is in Azure AD?

    1. When I did the script up, I used the on premise server up top (line 4)
      and did not use Azure AD at all (I did use get-MSOLUser on line 41 which does pull from azure AD automatically.)’

      Basically the script just makes names pretty for a migration, If you haven’t already done so, It’s worth doing a migration in sharegate and manually updating a single user and then exporting that sgum file so you can look at the finished product – That should give an indication of what the “From” and “To” look like and what the script is trying to grab.

Leave a Reply