Чтобы создать приложение Microsoft Azure на портале Azure, выполните следующие действия: Если вы используете расширенный метод импорта данных для копирования данных Exchange Online в аккаунты Google Workspace, вам понадобится приложение Azure, чтобы обеспечить безопасный импорт данных. Вы можете выбрать один из двух способов:
- Как настроить автоматическое подключение с помощью скрипта PowerShell
- Как настроить подключение вручную с помощью Azure
Как настроить автоматическое подключение с помощью скрипта PowerShell
Чтобы выполнить эти действия, вы должны быть глобальным администратором или администратором привилегированных ролей.
Вариант 1. Используйте Azure Cloud Shell
- Войдите на портал Azure как администратор.
- Нажмите Cloud Shell
Powershell.
- Если появится запрос, создайте аккаунт хранилища и примите настройки по умолчанию.
- Чтобы создать приложение, введите следующую команду
нажмите Ввод:
Install-Module Microsoft.Graph -Scope CurrentUser
- Если появится запрос на установку из ненадежного хранилища, введите Y
нажмите Ввод.
- Скопируйте следующий блок кода, вставьте его в PowerShell и нажмите Ввод.
<# .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"
- Запишите следующие учетные данные и сохраните их в надежном месте. В случае их утечки хакеры смогут получить доступ ко всем вашим данным Exchange Online.
- Секретный код клиента
- идентификатор приложения (клиента);
- идентификатор каталога (клиента).
Вариант 2. Использование Windows PowerShell
- В Windows создайте новый файл обычного текста и назовите его migration_app_creator.ps1.
- Скопируйте блок кода ниже, вставьте его в новый файл и нажмите Run with Powershell (Запустить с помощью Powershell).
- Запишите следующие учетные данные и сохраните их в надежном месте. В случае их утечки хакеры смогут получить доступ ко всем вашим данным Exchange Online.
- Секретный код клиента
- идентификатор приложения (клиента);
- идентификатор каталога (клиента).
<# .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"
Как настроить подключение вручную с помощью Azure
Конкретные действия, связанные с продуктом Microsoft, зависят от версии портала Azure и изменений, которые может внести Microsoft. Актуальные инструкции по регистрации и авторизации приложения можно найти в документации Microsoft.
Шаг 1. Зарегистрируйте новое приложение
Для обеспечения безопасности мы рекомендуем зарегистрировать новое приложение как один клиент.
- Войдите на портал Azure как администратор.
- В разделе Azure Services (Сервисы Azure) перейдите на страницу App registrations (Регистрация приложений).
- Нажмите New Registration (Новая регистрация) и введите название приложения, например "Приложение для расширенного импорта".
- В разделе Supported account types (Поддерживаемые типы аккаунтов) нажмите Accounts in this organizational directory only (Только аккаунты в этом каталоге организации), чтобы создать приложение с одним клиентом.
- Нажмите Регистрация.
Шаг 2. Настройте разрешения API
Выберите один из вариантов:
Вариант 1. Добавьте разрешения вручную
- На боковой панели в разделе Manage (Управление) нажмите API permissions (Разрешения API).
- Нажмите Add a permission (Добавить разрешение)
Microsoft APIs (API Microsoft)
Microsoft Graph.
- В разделе Application permissions (Разрешения приложения) выберите:
- 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
- Нажмите Grant admin consent for название организации (Предоставить согласие администратора).
Вариант 2. Измените манифест приложения
- Откройте манифест приложения.
- Перейдите к разделу "resourceAccess" : [ ] и выберите один из вариантов:
- Если в "resourceAccess" : [ ] уже есть значение, добавьте запятую и вставьте следующий блок кода:
- Если у "resourceAccess" : [ ] нет значения, скопируйте и вставьте следующий блок кода:
{ "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" }
- Нажмите Grant admin consent for название организации (Предоставить согласие администратора).
Шаг 3. Создайте секретный код клиента
- На боковой панели в разделе Manage (Управление) нажмите Certificates & secrets (Сертификаты и секреты)
New client secret (Новый секретный код клиента).
- Введите описание, выберите срок хранения и нажмите Добавить.
- Скопируйте значение секретного кода клиента и храните его в надежном месте. Это значение будет показано только один раз.
Шаг 4. Получите учетные данные для приложения
Важно! Храните учетные данные для приложения в надежном месте. В случае их утечки хакеры смогут получить доступ ко всем вашим данным Exchange.
Нажмите Обзор и запишите следующие учетные данные:
- идентификатор приложения (клиента);
- идентификатор каталога (клиента).
Как добавить права суперадминистратора для импорта зашифрованных данных (бета-версия)
Если импортируемые данные включают зашифрованные письма или файлы, выполните описанные ниже действия, чтобы предоставить идентификатору клиента для приложения Azure права суперпользователя Microsoft Information Protection (MIP). Инструменту импорта данных требуется право AipServiceSuperUser для расшифровки данных в Workspace.
Выполните эти действия на устройстве Windows, войдя в систему как глобальный администратор или администратор привилегированных ролей.
- В Windows откройте PowerShell и выберите Запуск от имени администратора.
Чтобы установить модуль AIPService, введите следующие команды и нажмите Ввод:
Install-Module -Name AIPService -Scope CurrentUser -ForceImport-Module AIPServiceЧтобы подключиться к сервису Azure Information Protection (AIP), введите следующую команду и нажмите Ввод:
Connect-AipServiceЧтобы добавить права AipServiceSuperUser для идентификатора клиента, введите следующую команду и нажмите Ввод:
Add -AipServiceSuperUser -ServicePrincipalId "*application-client-id*"Чтобы убедиться, что у вас есть права суперпользователя, введите следующую команду и нажмите Ввод:
Get-AipServiceSuperUserFeatureЧтобы посмотреть, у каких приложений есть доступ суперпользователя, введите следующую команду и нажмите Ввод:
Get-AipServiceSuperUser
Google, Google Workspace и связанные наименования и логотипы являются товарными знаками компании Google LLC. Все другие названия компаний и продуктов являются товарными знаками соответствующих компаний.