Skip to main content

Set up an Azure app registration for PowerShell SharePoint migrations

How to set up an Azure app registration to run ShareGate Migrate PowerShell SharePoint and Teams migrations without a signed-in user account.

Note: PowerShell integration requires a ShareGate Migrate Pro or Enterprise subscription. It is not available on the Essentials plan.

This article is for the ShareGate Migrate PowerShell integration only.

Application-only authentication lets you run SharePoint and Teams migrations from PowerShell without a signed-in user account. Instead of user credentials, ShareGate Migrate authenticates using an Azure app registration.

During setup, you'll create an app registration, upload a certificate credential, and grant the required API permissions.

You'll then use the Application (client) ID and certificate to authenticate from PowerShell.

Before you begin

  • ShareGate Migrate Pro or Enterprise subscription

  • Global Administrator access in the Microsoft 365 tenant is needed to create the app registration and grant admin consent

Set up the app registration

Do this in each tenant you migrate to or from.

For a single-tenant app (used only within a single tenant), repeat the full setup for each tenant.

For a multi-tenant app (where a single registration is reused across tenants), complete the steps in your home tenant, then grant admin consent in each additional tenant.

Step 1: Generate a certificate

ShareGate uses a certificate to authenticate as your app. Run the following PowerShell script to generate a self-signed certificate in your local user store and export it to your Desktop.

# Generate a self-signed certificate in your local user store
$certName = "AzureAppAuthCert"
$cert = New-SelfSignedCertificate -Subject "CN=$certName" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256

# Export the public key (.cer) - upload this to Azure in Step 3
Export-Certificate -Cert $cert -FilePath "$home\Desktop\$certName.cer"

# Export the private key as a .pfx - required if connecting via Option B
$pfxPassword = ConvertTo-SecureString -String "choose-a-strong-password" -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath "$home\Desktop\$certName.pfx" -Password $pfxPassword

# Copy this value for use with New-AzureApplication
Write-Host "Thumbprint: $($cert.Thumbprint)"

Both files are saved to your Desktop. Upload the .cer file to Azure in Step 3. If you plan to connect via Option B, you'll also need the .pfx file.

Note the thumbprint printed to the console. You'll use it with New-AzureApplication in the Connect step.

Step 2: Register the app in Microsoft Entra ID

  1. Sign in to the Microsoft Entra admin center as a Global Administrator.

  2. Go to Entra ID > App registrations > New registration.

  3. Give the app a name (for example, ShareGate Migration).

  4. Under Supported account types, choose My organization only for a single-tenant app, or Multiple Entra ID tenants for a multi-tenant app used across several tenants.

  5. Leave the Redirect URI empty.

  6. Click Register.

  7. On the Overview page, copy the Application (client) ID. You'll use it with New-AzureApplication.

Step 3: Upload the certificate

  1. In your app registration, go to Certificates & secrets > Certificates, then select Upload certificate.

  2. Upload the .cer file from your Desktop.

  3. Click Add.

Step 4: Add API permissions

  1. In your app registration, go to API permissions > Add a permission.

  2. Add each Application permission listed below. Add the Microsoft Graph permissions and the SharePoint permissions as separate entries. Do not select Delegated permissions.

  3. Click Grant admin consent for [your tenant] and confirm.

Microsoft Graph permissions:

ChannelMember.ReadWrite.All

Teams channel membership

ChannelSettings.ReadWrite.All

Teams channel settings

Directory.ReadWrite.All

Directory objects

Files.ReadWrite.All

Files in all site collections

Group.ReadWrite.All

Microsoft 365 groups

InformationProtectionPolicy.Read.All

Information protection policies

SensitivityLabels.Read.All

Sensitivity labels

Notes.ReadWrite.All

OneNote notebooks

Sites.FullControl.All

Full control of all site collections

Sites.Manage.All

Create, edit, and delete items in all site collections

Sites.ReadWrite.All

Read and write items in all site collections

Tasks.ReadWrite.All

Planner tasks

Team.Create

Create teams

TeamMember.ReadWrite.All

Team membership

TeamsAppInstallation.ReadWriteForUser.All

Teams app installations

TeamSettings.ReadWrite.All

Team settings

TeamsTab.ReadWrite.All

Tabs in Teams channels

TermStore.ReadWrite.All

Term store

User.Read.All

User profiles

SharePoint permissions:

Note: SharePoint permissions are found under SharePoint in the API list, not Microsoft Graph.

Sites.FullControl.All

Full control of all site collections

Sites.Manage.All

Create, edit, and delete items in all site collections

Sites.Read.All

Read items in all site collections

Sites.ReadWrite.All

Read and write items in all site collections

TermStore.Read.All

Term store (read)

TermStore.ReadWrite.All

Term store (read/write)

User.Read.All

User profiles (read)

User.ReadWrite.All

User profiles (read/write)

Connect from ShareGate

Build a credential object with New-AzureApplication, then pass it to Connect-Site or Connect-Tenant.

Option A: Certificate thumbprint (from the generation script)

If you used the script in Step 1, the certificate is in Cert:\CurrentUser\My. Pass the thumbprint directly:

# Build a credential object from the certificate thumbprint
$app = New-AzureApplication -ClientId "<application-client-id>" -Thumbprint "<certificate-thumbprint>"

# Connect to a specific site
Connect-Site -Url "https://contoso.sharepoint.com/sites/Marketing" -AzureApplication $app

# Or connect at the tenant level
Connect-Tenant -Domain "contoso" -AzureApplication $app

Option B: Certificate from a .pfx file

If you have the certificate as a .pfx file, load it directly:

# Load the certificate from a .pfx file
$certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new(
"C:\certs\sharegate-app.pfx",
"your-pfx-password")

# Build a credential object
$app = New-AzureApplication -ClientId "<application-client-id>" -Certificate $certificate

# Connect to a site
Connect-Site -Url "https://contoso.sharepoint.com/sites/Marketing" -AzureApplication $app

A single app object can authenticate multiple connections in the same session. Reuse the same $app variable across multiple Connect-Site or Connect-Tenant calls.

Note: If your security policy prevents granting one of the required permissions, add -AllowMissingPermissions to Connect-Site or Connect-Tenant to connect anyway.

Operations that rely on the missing permission will fail with Forbidden errors.

This switch only relaxes the permission check after authentication succeeds. It won't resolve a failed sign-in.

Save and reuse an app

You can save an app registration object and retrieve it in later sessions, so you don't need to rebuild it each time. Use Save-AzureApplication to store it and Get-AzureApplication to load it back.

Known limitations

  • Modified By and Created By are not carried over during migration. Items show the app's service identity instead of the original author.

  • User alerts are skipped. App-only auth has no user context to send alerts.

  • Classic web parts are not migrated.

  • Classic SharePoint workflows are not migrated.

  • InfoPath forms are partially migrated. Expect warnings.

  • Publishing approval workflows require a user context. Expect errors or warnings.

  • Sensitivity labels are not yet applied during migration. Support is planned for a future update.

Did this answer your question?