Konfigurera en Azure-app för Exchange Online

Följ de här stegen för att skapa en Microsoft Azure-app i Azure-portalen. Om du använder den avancerade metoden för dataimport för att kopiera Exchange Online-data till dina Google Workspace-konton behöver du Azure-appen för att säkerställa en säker dataimport. Du kan välja en av två metoder:

Använda ett PowerShell-skript för att konfigurera en automatisk anslutning

Du måste vara global administratör eller administratör med privilegierad roll för att slutföra de här stegen.

Alternativ 1: Använda Azure Cloud Shell

  1. Logga in på Azure-portalen som administratör.
  2. Klicka på Cloud Shell följt av Powershell.
  3. Skapa ett lagringskonto om du blir ombedd att göra det och godkänn standardinställningarna.
  4. Skapa appen genom att ange följande kommando följt av klicka på Retur:

    Install-Module Microsoft.Graph -Scope CurrentUser

  5. Om du uppmanas att installera från en ej betrodd lagringsplats anger du Y följt av klickar på Retur.
  6. Kopiera följande kodblock, klistra in det i PowerShell och klicka på Retur.
    <#
    .SYNOPSIS
    Automates the creation of a Single-Tenant Entra ID App for Workspace Migration.
    Strictly forces account selection and verifies specific Admin roles.
    #>
    
    # Check if the module is missing
    if (-not (Get-Module -ListAvailable -Name Microsoft.Graph.Authentication)) {
        Write-Host "Microsoft Graph module is NOT installed." -ForegroundColor Yellow
        $UserResponse = Read-Host "Would you like to try installing Microsoft Graph? (Y/N)"
    
        if ($UserResponse -ieq "Y") {
            try {
                # Use only native cmdlets, no .NET property setting
                Install-Module -Name Microsoft.Graph -Scope CurrentUser -Force -AllowClobber
                Write-Host "Installation complete!" -ForegroundColor Green
            }
            catch {
                Write-Error "Policy is blocking installation. Please contact IT to install Microsoft.Graph module."
                Read-Host "Press Enter to exit"; exit
            }
        }
        else {
            exit
        }
    } else {
        Write-Host "Microsoft Graph modules detected. Proceeding..." -ForegroundColor Green
    }
    
    # --- STEP 0: THE "DEEP" LOGOUT ---
    Write-Host "Forcing session cleanup..." -ForegroundColor Gray
    Disconnect-MgGraph -ErrorAction SilentlyContinue
    
    # Force clear the local token cache folder if it exists
    $CachePath = "$env:USERPROFILE\.mg"
    if (Test-Path $CachePath) {
        try { Remove-Item $CachePath -Recurse -Force -ErrorAction SilentlyContinue } catch {}
    }
    
    Write-Host "Opening Microsoft Login... (Please select the correct account)" -ForegroundColor Cyan
    
    $RequiredScopes = @(
        "Application.ReadWrite.All",
        "AppRoleAssignment.ReadWrite.All",
        "Directory.Read.All",
        "RoleManagement.Read.Directory"
    )
    
    try {
        # In v2, -ContextScope Process is the most reliable way to force account selection
        # and prevent the session from saving to the machine permanently.
        Connect-MgGraph -Scopes $RequiredScopes -ContextScope Process
    
        $Context = Get-MgContext
        if ($null -eq $Context) { throw "Login was cancelled or failed." }
    
        $UserPrincipal = $Context.Account
        Write-Host "Logged in as: $UserPrincipal" -ForegroundColor Green
    
        # --- ROLE VALIDATION ---
        Write-Host "Verifying Directory Roles..." -ForegroundColor Gray
        $UserRoles = Get-MgUserMemberOf -UserId $Context.Account -All | Where-Object { $_.AdditionalProperties.displayName -ne $null }
        
        $Authorized = $false
        $RequiredRoles = @("Global Administrator", "Privileged Role Administrator")
    
        foreach ($role in $UserRoles) {
            $roleName = $role.AdditionalProperties.displayName
            if ($roleName -in $RequiredRoles) {
                $Authorized = $true
                Write-Host "Access Granted: $roleName" -ForegroundColor Green
                break
            }
        }
    
        if (-not $Authorized) {
            Write-Host "`nCRITICAL ERROR: Insufficient Privileges." -ForegroundColor Red
            Write-Host "Account must be 'Global Administrator' or 'Privileged Role Administrator'." -ForegroundColor Yellow
            Disconnect-MgGraph
            Read-Host "`nPress Enter to exit"; exit
        }
    
    } catch {
        Write-Error "Login failed: $_"
        Read-Host "Press Enter to exit"; exit
    }
    
    # --- USER INPUT ---
    Write-Host "`n--- APPLICATION SETUP ---" -ForegroundColor Cyan
    $InputName = Read-Host "Enter the name for your new Entra ID Application (Default: Workspace Migration App)"
    $AppName = if ([string]::IsNullOrWhiteSpace($InputName)) { "Workspace Migration App" } else { $InputName }
    
    # --- CONFIGURATION ---
    # Updated Map containing all the requested application permissions
    $PermissionMap = @{
        "calendars.read"              = "Calendars.Read"
        "contacts.read"               = "Contacts.Read"
        "directory.read.all"          = "Directory.Read.All"
        "group-conversation.read.all" = "Group-Conversation.Read.All"
        "mail.read"                   = "Mail.Read"
        "mailboxfolder.read.all"      = "MailboxFolder.Read.All"
        "mailboxitem.export.all"      = "MailboxItem.Export.All"
        "mailboxitem.read.all"        = "MailboxItem.Read.All"
        "mailboxsettings.read"        = "MailboxSettings.Read"
        "tasks.read.all"              = "Tasks.Read.All"
        "user.read.all"               = "User.Read.All"
    }
    
    $TenantId = $Context.TenantId
    $GraphAppId = "00000003-0000-0000-c000-000000000000"
    
    try {
        # --- STEP 1: REGISTER APPLICATION ---
        Write-Host "Creating Application: $AppName..." -ForegroundColor Cyan
        $Application = New-MgApplication -BodyParameter @{
            displayName = $AppName
            signInAudience = "AzureADMyOrg"
        }
    
        # --- STEP 2: PREPARE SERVICE PRINCIPAL ---
        $NewServicePrincipal = New-MgServicePrincipal -BodyParameter @{ appId = $Application.AppId }
    
        Write-Host "Waiting 10 seconds for replication..." -ForegroundColor DarkGray
        Start-Sleep -Seconds 10
    
        # --- STEP 3: CONFIGURE & GRANT PERMISSIONS ---
        Write-Host "Configuring API Permissions & Granting Admin Consent..." -ForegroundColor Cyan
        $GraphSP = Get-MgServicePrincipal -Filter "AppId eq '$GraphAppId'" | Select-Object -First 1
    
        $ResourceAccessList = @()
    
        foreach ($key in $PermissionMap.Keys) {
            $RealRoleName = $PermissionMap[$key]
            $Role = $GraphSP.AppRoles | Where-Object { $_.Value -eq $RealRoleName }
    
            if ($Role) {
                $ResourceAccessList += @{ id = $Role.Id; type = "Role" }
    
                New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $NewServicePrincipal.Id -BodyParameter @{
                    principalId = $NewServicePrincipal.Id
                    resourceId  = $GraphSP.Id
                    appRoleId   = $Role.Id
                } | Out-Null
                Write-Host " - Granted: $RealRoleName" -ForegroundColor Gray
            }
        }
    
        Update-MgApplication -ApplicationId $Application.Id -RequiredResourceAccess @(@{
            resourceAppId  = $GraphAppId
            resourceAccess = $ResourceAccessList
        })
    
        # --- STEP 4: CREATE CLIENT SECRET ---
        Write-Host "Generating Client Secret..." -ForegroundColor Cyan
        $ExpiryDate = (Get-Date).AddYears(2).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
        $PasswordCred = Add-MgApplicationPassword -ApplicationId $Application.Id -BodyParameter @{
            passwordCredential = @{
                displayName = "MigrationToolSecret"
                endDateTime = $ExpiryDate
            }
        }
    
        # --- OUTPUT ---
        Write-Host "`n-------------------------------------------------------" -ForegroundColor Yellow
        Write-Host "        SETUP COMPLETE - SAVE THESE DETAILS" -ForegroundColor Yellow
        Write-Host "-------------------------------------------------------" -ForegroundColor Yellow
        Write-Host "Application Name        : $AppName"
        Write-Host "Application (Client) ID : $($Application.AppId)"
        Write-Host "Client Secret Value     : $($PasswordCred.SecretText)"
        Write-Host "Directory (Tenant) ID   : $TenantId"
        Write-Warning "IMPORTANT: Copy the Client Secret Value immediately."
    
    }
    catch {
        Write-Error "Operation failed: $_"
    }
    
    # --- FINAL DISCONNECT ---
    Disconnect-MgGraph
    Read-Host "`nPress Enter to close this window"
        
  7. Anteckna följande användaruppgifter och förvara dem på ett säkert ställe. Om användaruppgifterna läcker kan hackare få åtkomst till all din Exchange Online-data.
    • Klientlösenord
    • App-id (klient-id)
    • Katalog-id (klient)

Alternativ 2: Använd Windows PowerShell

  1. Skapa en ny fil med vanlig text i Windows och ge den namnet migration_app_creator.ps1.
  2. Kopiera följande kodblock, klistra in det i den nya filen och klicka på Kör med Powershell.
  3. <#
    .SYNOPSIS
    Automates the creation of a Single-Tenant Entra ID App for Workspace Migration.
    Strictly forces account selection and verifies specific Admin roles.
    #>
    
    # Check if the module is missing
    if (-not (Get-Module -ListAvailable -Name Microsoft.Graph.Authentication)) {
        Write-Host "Microsoft Graph module is NOT installed." -ForegroundColor Yellow
        $UserResponse = Read-Host "Would you like to try installing Microsoft Graph? (Y/N)"
    
        if ($UserResponse -ieq "Y") {
            try {
                # Use only native cmdlets, no .NET property setting
                Install-Module -Name Microsoft.Graph -Scope CurrentUser -Force -AllowClobber
                Write-Host "Installation complete!" -ForegroundColor Green
            }
            catch {
                Write-Error "Policy is blocking installation. Please contact IT to install Microsoft.Graph module."
                Read-Host "Press Enter to exit"; exit
            }
        }
        else {
            exit
        }
    } else {
        Write-Host "Microsoft Graph modules detected. Proceeding..." -ForegroundColor Green
    }
    
    # --- STEP 0: THE "DEEP" LOGOUT ---
    Write-Host "Forcing session cleanup..." -ForegroundColor Gray
    Disconnect-MgGraph -ErrorAction SilentlyContinue
    
    # Force clear the local token cache folder if it exists
    $CachePath = "$env:USERPROFILE\.mg"
    if (Test-Path $CachePath) {
        try { Remove-Item $CachePath -Recurse -Force -ErrorAction SilentlyContinue } catch {}
    }
    
    Write-Host "Opening Microsoft Login... (Please select the correct account)" -ForegroundColor Cyan
    
    $RequiredScopes = @(
        "Application.ReadWrite.All",
        "AppRoleAssignment.ReadWrite.All",
        "Directory.Read.All",
        "RoleManagement.Read.Directory"
    )
    
    try {
        # In v2, -ContextScope Process is the most reliable way to force account selection
        # and prevent the session from saving to the machine permanently.
        Connect-MgGraph -Scopes $RequiredScopes -ContextScope Process
    
        $Context = Get-MgContext
        if ($null -eq $Context) { throw "Login was cancelled or failed." }
    
        $UserPrincipal = $Context.Account
        Write-Host "Logged in as: $UserPrincipal" -ForegroundColor Green
    
        # --- ROLE VALIDATION ---
        Write-Host "Verifying Directory Roles..." -ForegroundColor Gray
        $UserRoles = Get-MgUserMemberOf -UserId $Context.Account -All | Where-Object { $_.AdditionalProperties.displayName -ne $null }
    
        $Authorized = $false
        $RequiredRoles = @("Global Administrator", "Privileged Role Administrator")
    
        foreach ($role in $UserRoles) {
            $roleName = $role.AdditionalProperties.displayName
            if ($roleName -in $RequiredRoles) {
                $Authorized = $true
                Write-Host "Access Granted: $roleName" -ForegroundColor Green
                break
            }
        }
    
        if (-not $Authorized) {
            Write-Host "`nCRITICAL ERROR: Insufficient Privileges." -ForegroundColor Red
            Write-Host "Account must be 'Global Administrator' or 'Privileged Role Administrator'." -ForegroundColor Yellow
            Disconnect-MgGraph
            Read-Host "`nPress Enter to exit"; exit
        }
    
    } catch {
        Write-Error "Login failed: $_"
        Read-Host "Press Enter to exit"; exit
    }
    
    # --- USER INPUT ---
    Write-Host "`n--- APPLICATION SETUP ---" -ForegroundColor Cyan
    $InputName = Read-Host "Enter the name for your new Entra ID Application (Default: Workspace Migration App)"
    $AppName = if ([string]::IsNullOrWhiteSpace($InputName)) { "Workspace Migration App" } else { $InputName }
    
    # --- CONFIGURATION ---
    # Updated Map containing all the requested application permissions
    $PermissionMap = @{
        "calendars.read"              = "Calendars.Read"
        "contacts.read"               = "Contacts.Read"
        "directory.read.all"          = "Directory.Read.All"
        "group-conversation.read.all" = "Group-Conversation.Read.All"
        "mail.read"                   = "Mail.Read"
        "mailboxfolder.read.all"      = "MailboxFolder.Read.All"
        "mailboxitem.export.all"      = "MailboxItem.Export.All"
        "mailboxitem.read.all"        = "MailboxItem.Read.All"
        "mailboxsettings.read"        = "MailboxSettings.Read"
        "tasks.read.all"              = "Tasks.Read.All"
        "user.read.all"               = "User.Read.All"
    }
    
    $TenantId = $Context.TenantId
    $GraphAppId = "00000003-0000-0000-c000-000000000000"
    
    try {
        # --- STEP 1: REGISTER APPLICATION ---
        Write-Host "Creating Application: $AppName..." -ForegroundColor Cyan
        $Application = New-MgApplication -BodyParameter @{
            displayName = $AppName
            signInAudience = "AzureADMyOrg"
        }
    
        # --- STEP 2: PREPARE SERVICE PRINCIPAL ---
        $NewServicePrincipal = New-MgServicePrincipal -BodyParameter @{ appId = $Application.AppId }
    
        Write-Host "Waiting 10 seconds for replication..." -ForegroundColor DarkGray
        Start-Sleep -Seconds 10
    
        # --- STEP 3: CONFIGURE & GRANT PERMISSIONS ---
        Write-Host "Configuring API Permissions & Granting Admin Consent..." -ForegroundColor Cyan
        $GraphSP = Get-MgServicePrincipal -Filter "AppId eq '$GraphAppId'" | Select-Object -First 1
    
        $ResourceAccessList = @()
    
        foreach ($key in $PermissionMap.Keys) {
            $RealRoleName = $PermissionMap[$key]
            $Role = $GraphSP.AppRoles | Where-Object { $_.Value -eq $RealRoleName }
    
            if ($Role) {
                $ResourceAccessList += @{ id = $Role.Id; type = "Role" }
    
                New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $NewServicePrincipal.Id -BodyParameter @{
                    principalId = $NewServicePrincipal.Id
                    resourceId  = $GraphSP.Id
                    appRoleId   = $Role.Id
                } | Out-Null
                Write-Host " - Granted: $RealRoleName" -ForegroundColor Gray
            }
        }
    
        Update-MgApplication -ApplicationId $Application.Id -RequiredResourceAccess @(@{
            resourceAppId  = $GraphAppId
            resourceAccess = $ResourceAccessList
        })
    
        # --- STEP 4: CREATE CLIENT SECRET ---
        Write-Host "Generating Client Secret..." -ForegroundColor Cyan
        $ExpiryDate = (Get-Date).AddYears(2).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
        $PasswordCred = Add-MgApplicationPassword -ApplicationId $Application.Id -BodyParameter @{
            passwordCredential = @{
                displayName = "MigrationToolSecret"
                endDateTime = $ExpiryDate
            }
        }
    
        # --- OUTPUT ---
        Write-Host "`n-------------------------------------------------------" -ForegroundColor Yellow
        Write-Host "        SETUP COMPLETE - SAVE THESE DETAILS" -ForegroundColor Yellow
        Write-Host "-------------------------------------------------------" -ForegroundColor Yellow
        Write-Host "Application Name        : $AppName"
        Write-Host "Application (Client) ID : $($Application.AppId)"
        Write-Host "Client Secret Value     : $($PasswordCred.SecretText)"
        Write-Host "Directory (Tenant) ID   : $TenantId"
        Write-Warning "IMPORTANT: Copy the Client Secret Value immediately."
    
    }
    catch {
        Write-Error "Operation failed: $_"
    }
    
    # --- FINAL DISCONNECT ---
    Disconnect-MgGraph
    Read-Host "`nPress Enter to close this window"
    
        
  4. Anteckna följande användaruppgifter och förvara dem på ett säkert ställe. Om användaruppgifterna läcker kan hackare få åtkomst till all din Exchange Online-data.
    • Klientlösenord
    • App-id (klient-id)
    • Katalog-id (klient)

Använda Azure för att konfigurera en manuell anslutning

De specifika Microsoft-stegen kan variera beroende på din Azure-portalversion och uppdateringar som Microsoft har gjort. I Microsofts dokumentation finns den senaste vägledningen om appregistrering och auktorisering.

Steg 1: Registrera en ny app

Av säkerhetsskäl rekommenderar vi att du registrerar den nya appen som en enskild klient.

  1. Logga in på Azure-portalen som administratör.
  2. Öppna App registrations i Azure Services.
  3. Klicka på New Registration och ange ett namn på appen (till exempel Advanced import app).
  4. Klicka på Endast konton i den här organisationskatalogen för Kontotyper som stöds för att skapa en app med en klient.
  5. Klicka på Registrera.

Steg 2: Konfigurera API-behörigheter

Välj ett av följande alternativ:

Alternativ 1: Lägg till behörigheter manuellt

  1. Klicka på API permissions under Manage på sidan.
  2. Klicka på Add a permission följt av Microsoft APIs följt av Microsoft Graph.
  3. Välj följande för appbehörigheter:
    • Calendars.Read
    • Contacts.Read
    • Directory.Read.All
    • Group-Conversation.Read.All
    • Mail.Read
    • MailboxFolder.Read.All
    • MailboxItem.Export.All
    • MailboxItem.Read.All
    • MailboxSettings.Read
    • Tasks.Read.All
    • User.Read.All
  4. Klicka på Ge administratörssamtycke för organisationen.

Alternativ 2: Redigera applikationsmanifestet

  1. Öppna appmanifestet.
  2. Gå till resourceAccess : [ ] och välj ett alternativ:
    • Om “resourceAccess” : [ ] redan har ett värde lägger du till ett kommatecken och klistrar sedan in följande kodblock.
    • Om “resourceAccess” : [ ] inte har ett värde kopierar och klistrar du in följande kodblock.

    { "id": "798ee544-9d2d-430c-a058-570e29e34338", "type": "Role" },

    { "id": "089fe4d0-434a-44c5-8827-41ba8a0b17f5", "type": "Role" },

    { "id": "7ab1d382-f21e-4acd-a863-ba3e13f7da61", "type": "Role" },

    { "id": "4f0a8235-6f6f-4ec7-9500-34b452a4a0c3", "type": "Role" },

    { "id": "810c84a8-4a9e-49e6-bf7d-12d183f40d01", "type": "Role" },

    { "id": "99280d24-a782-4793-93cc-0888549957f6", "type": "Role" },

    { "id": "937550e9-33a3-494b-88ae-d9cd394b1fbb", "type": "Role" },

    { "id": "7d9f353d-a7bd-4fbb-822a-26d5dd39a3ce", "type": "Role" },

    { "id": "40f97065-369a-49f4-947c-6a255697ae91", "type": "Role" },

    { "id": "f10e1f91-74ed-437f-a6fd-d6ae88e26c1f", "type": "Role" },

    { "id": "df021288-bdef-4463-88db-98f22de89214", "type": "Role" }

  3. Klicka på Ge administratörssamtycke för organisationen.

Steg 3: Generera klientlösenordet

  1. Klicka på Certifikat och hemligheter följt av Ny klienthemlighet för Hantera på sidan.
  2. Ange en beskrivning, välj en utgångsperiod och klicka på Lägg till.
  3. Kopiera värdet för klientlösenordet och lagra det på ett säkert sätt. Värdet visas bara en gång.

Steg 4: Samla in appuppgifterna

Viktigt! Spara appuppgifterna på ett säkert sätt. Om användaruppgifterna läcker kan hackare få åtkomst till all din Exchange-data.

Klicka på Översikt och anteckna följande användaruppgifter på ett säkert sätt:

  • App-id (klient-id)
  • Katalog-id (klient)

Lägga till behörigheter för avancerade användare för import av krypterad data (beta)

Om dataimporten innehåller krypterade e-postmeddelanden eller filer följer du de här stegen för att tillämpa superanvändarbehörigheter för Microsoft Information Protection (MIP) på klient-id:t för Azure-appen. Dataimportverktyget behöver behörigheten AipServiceSuperUser för att dekryptera data i Workspace.

Slutför de här stegen på en Windows-enhet som är inloggad som global administratör eller administratör med privilegierad roll.

  1. Öppna PowerShell i Windows och välj Kör som administratör.
  2. Installera AIPService-modulen genom att ange följande kommandon och sedan trycka på Retur:

    Install-Module -Name AIPService -Scope CurrentUser -Force

    Import-Module AIPService

  3. Anslut till AIP-tjänsten (Azure Information Protection) genom att ange följande kommando och trycka på Retur:

    Connect-AipService

  4. Om du vill lägga till AipServiceSuperUser-behörigheter i ditt klient-id anger du följande kommando och trycker på Retur:

    Add -AipServiceSuperUser -ServicePrincipalId "*application-client-id*"

  5. (Valfritt) Kontrollera att din status som avancerad användare är aktiverad genom att ange följande kommando och trycka på Retur:

    Get-AipServiceSuperUserFeature

  6. (Valfritt) Om du vill se vilka appar som har superanvändaråtkomst anger du följande kommando och trycker på Retur:

    Get-AipServiceSuperUser


Google, Google Workspace och tillhörande märken och logotyper är varumärken som tillhör Google LLC. Alla andra företags- och produktnamn är varumärken som tillhör de företag som de är kopplade till.