Exchange Online'dan (Microsoft 365) Google Workspace hesabınıza güvenli veri taşıma işlemini destekleyen bir Microsoft Azure uygulamasını Azure portalında oluşturmak için aşağıdaki adımları uygulayın. İki yöntemden birini seçebilirsiniz:
- Otomatik bağlantı oluşturmak için PowerShell komut dosyası kullanma
- Manuel bağlantı oluşturmak için Azure AD'yi kullanma
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.
Başlamadan önce: Install-Module Microsoft.Graph -Scope CurrentUser uygulamasını yüklemeniz gerekir.
1. seçenek: Azure Cloud Shell'i kullanma
- Yönetici olarak Microsoft Azure portalınızda oturum açın.
- Cloud Shell
Powershell'i tıklayın.
- İstenirse bir depolama hesabı oluşturun ve varsayılan ayarları kabul edin.
- Install-Module Microsoft.Graph -Scope CurrentUser komutunu yapıştırın ve Enter'ı (Giriş) tıklayın.
- Güvenilmeyen bir depodan yükleme yapmanızı isteyen bir istem görürseniz Y yazıp Enter'ı tıklayın.
- Aşağıdaki kod bloğunu 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"
- 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
- Windows'da migration_app_creator.ps1 adlı yeni bir düz metin dosyası oluşturun.
- Aşağıdaki kod bloğunu kopyalayın, yeni dosyaya yapıştırın ve Run with Powershell'i (Powershell ile çalıştır) tıklayın.
- 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
<# .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"
Manuel bağlantı oluşturmak için Azure AD'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.
- Yönetici olarak Microsoft Azure portalınızda oturum açın.
- Azure Active Directory'de (Azure AD) App registrations'a (Uygulama kayıtları) gidin.
- New Registration'ı (Yeni Kayıt) tıklayın ve uygulamanız için bir ad girin (örneğin, Enterprise Migration App).
- Desteklenen hesap türleri için tek kiracılı bir uygulama oluşturmak üzere Yalnızca bu kuruluş dizinindeki hesaplar'ı tıklayın.
- 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
- Sol gezinme menüsündeki Yönet bölümünde API izinleri'ni tıklayın.
- İzin ekle
Microsoft API'leri
Microsoft Graph'ı tıklayın.
- Uygulama izinleri için aşağıdakilerden birini seçin:
- calendars.read
- mail.read
- contacts.read
- Directory.read.all
- [Kuruluşunuz]için yönetici izni ver'i tıklayın.
2. seçenek: Uygulama manifestini düzenleme
- Uygulama manifestini açın.
- “resourceAccess” : [ ] için aşağıdaki kod bloğunu kopyalayıp yapıştırın.
“resourceAccess” : [ ] zaten bir değere sahipse virgül ekleyin ve kod bloğunu 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" } - [Kuruluşunuz]için yönetici izni ver'i tıklayın.
3. adım: İstemci gizli anahtarını oluşturun
- Sol gezinme menüsünde, Yönet bölümünde Sertifikalar ve gizli anahtarlar
Yeni istemci gizli anahtarı'nı tıklayın.
- Açıklama girin, süre sonu seçin ve Ekle'yi tıklayın.
- İ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
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.