Gelişmiş taşıma için Azure uygulamasını ayarlama

Azure portalında Microsoft Azure uygulaması oluşturmak için aşağıdaki adımları uygulayın. Microsoft Exchange Online'dan Google Workspace hesaplarınıza güvenli bir veri taşıma işlemi gerçekleştirmek için uygulamayı oluşturmanız gerekir. 2 yöntemden birini seçebilirsiniz:

Otomatik bağlantı oluşturmak için PowerShell komut dosyası kullanma

Bu adımları tamamlamak için genel yönetici veya ayrıcalıklı rol yöneticisi olmanız gerekir.

1. seçenek: Azure Cloud Shell'i kullanma

  1. Yönetici olarak Azure portalınızda oturum açın.
  2. Cloud ShellardındanPowershell'i tıklayın.
  3. İstenirse bir depolama hesabı oluşturun ve varsayılan ayarları kabul edin.
  4. Uygulamayı oluşturmak için aşağıdaki komutu girin ve Enter'ı tıklayın:

    Install-Module Microsoft.Graph -Scope CurrentUser

  5. Güvenilmeyen bir depodan yükleme yapmanızı isteyen bir istem görürseniz Y yazıp Enter'ı tıklayın.
  6. Aşağıdaki kod blokunu kopyalayın, PowerShell'e yapıştırın ve Enter'ı tıklayın.
        <#
        .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 ---
        $PermissionMap = @{
        "calendar.read"  = "Calendars.Read"     
        "mail.read"      = "Mail.Read"
        "contacts.read"  = "Contacts.Read"
        "directory.read" = "Directory.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. Aşağıdaki kimlik bilgilerini not edin ve güvenli bir şekilde saklayın. Kimlik bilgileri sızdırılırsa bilgisayar korsanları Exchange Online verilerinizin tamamına erişebilir.
    • İstemci gizli anahtarı
    • Uygulama (istemci) kimliği
    • Dizin (kiracı) kimliği

2. seçenek: Windows PowerShell'i kullanma

  1. Windows'da yeni bir düz metin dosyası oluşturun ve dosyayı migration_app_creator.ps1 olarak adlandırın.
  2. Aşağıdaki kod blokunu kopyalayın, yeni dosyaya yapıştırın ve Run with Powershell'i (Powershell ile çalıştır) tıklayın.
    <#
    .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 ---
    $PermissionMap = @{
    "calendar.read"  = "Calendars.Read"     
    "mail.read"      = "Mail.Read"
    "contacts.read"  = "Contacts.Read"
    "directory.read" = "Directory.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"
    
  • Aşağıdaki kimlik bilgilerini not edin ve güvenli bir şekilde saklayın. Kimlik bilgileri sızdırılırsa bilgisayar korsanları Exchange Online verilerinizin tamamına erişebilir.
    • İstemci gizli anahtarı
    • Uygulama (istemci) kimliği
    • Dizin (kiracı) kimliği
  • Manuel bağlantı oluşturmak için Azure Active Directory'yi kullanma

    Belirli Microsoft adımları, Azure portal sürümünüze ve Microsoft tarafından yapılan güncellemelere bağlı olarak değişiklik gösterebilir. Uygulama kaydı ve yetkilendirmeyle ilgili en son yönergeler için Microsoft'un belgelerine bakın.

    1. adım: Yeni bir uygulama kaydedin

    Güvenlik nedeniyle yeni uygulamayı tek kiracılı olarak kaydetmenizi öneririz.

    1. Yönetici olarak Azure portalınızda oturum açın.
    2. Azure Active Directory (Azure AD)'de App registrations'a (Uygulama kayıtları) gidin.
    3. New Registration'ı (Yeni Kayıt) tıklayın ve uygulamanız için bir ad girin (örneğin, Advanced migration app).
    4. Desteklenen hesap türleri için tek kiracılı bir uygulama oluşturmak üzere Yalnızca bu kuruluş dizinindeki hesaplar'ı tıklayın.
    5. Kaydol'u tıklayın.

    2. adım: API izinlerini yapılandırın

    Aşağıdaki seçeneklerden birini belirleyin:

    1. seçenek: İzinleri manuel olarak ekleme

    1. Yan tarafta, Yönet bölümünde API izinleri'ni tıklayın.
    2. İzin ekleardındanMicrosoft API'leriardındanMicrosoft Graph'ı tıklayın.
    3. Uygulama izinleri için aşağıdakilerden birini seçin:
      • calendars.read
      • mail.read
      • contacts.read
      • Directory.read.all
    4. Grant admin consent for your organization'ı (Kuruluşunuz için yönetici izni ver) tıklayın.

    2. seçenek: Uygulama manifestini düzenleme

    1. Uygulama manifestini açın.
    2. “resourceAccess” : [ ] bölümüne gidip bir seçenek belirleyin:
      • “resourceAccess” : [ ] içinde zaten bir değer varsa virgül ekleyip aşağıdaki kod bloğunu yapıştırın.
      • “resourceAccess” : [ ] değer içermiyorsa aşağıdaki kod bloğunu kopyalayıp yapıştırın.

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

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

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

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

    3. Grant admin consent for your organization'ı (Kuruluşunuz için yönetici izni ver) tıklayın.

    3. adım: İstemci gizli anahtarını oluşturun

    1. Yanda, Yönet bölümünde Sertifikalar ve gizli anahtarlarardındanYeni istemci gizli anahtarı'nı tıklayın.
    2. Açıklama girin, süre sonu seçin ve Ekle'yi tıklayın.
    3. İstemci gizli anahtarı değerini kopyalayın ve güvenli bir şekilde saklayın. Değer yalnızca bir kez gösterilir.

    4. adım: Uygulama kimlik bilgilerini toplayın

    Önemli: Uygulama kimlik bilgilerini güvenli bir şekilde saklayın. Kimlik bilgileri sızdırılırsa bilgisayar korsanları Exchange verilerinizin tamamına erişebilir.

    Overview'ı (Genel Bakış) tıklayın ve aşağıdaki kimlik bilgilerini güvenli bir şekilde not edin:

    • Uygulama (istemci) kimliği
    • Dizin (kiracı) kimliği


    Google, Google Workspace ve ilgili markalar ile logolar, Google LLC şirketinin ticari markalarıdır. Diğer tüm şirket ve ürün adları, ilişkili oldukları şirketlerin ticari markalarıdır.