Чтобы создать приложение Microsoft Azure на портале Azure, выполните следующие действия: Если вы используете расширенный метод импорта данных для копирования данных Microsoft Teams в аккаунты 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 = @{ "member.read.hidden" = "Member.Read.Hidden" "organization.read.all" = "Organization.Read.All" "channelmember.read.all" = "ChannelMember.Read.All" "channelmessage.read.all" = "ChannelMessage.Read.All" "channelsettings.read.all" = "ChannelSettings.Read.All" "group.read.all" = "Group.Read.All" "team.readbasic.all" = "Team.ReadBasic.All" "teammember.read.all" = "TeamMember.Read.All" "user.read.all" = "User.Read.All" “application.read.all” = “Application.Read.All” "chat.readbasic.all" = "Chat.ReadBasic.All" "chatmessage.read.all" = "ChatMessage.Read.All" "chatmember.read.all" = "ChatMember.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"
- Запишите приведенные ниже учетные данные и сохраните их в надежном месте. В случае их утечки хакеры смогут получить доступ ко всем вашим данным Teams.
- Секретный код клиента
- идентификатор приложения (клиента);
- идентификатор каталога (клиента).
Вариант 2. Использование Windows PowerShell
- В Windows создайте новый текстовый файл и назовите его migration_app_creator.ps1.
- Скопируйте приведенный ниже блок кода, вставьте его в новый файл и нажмите Выполнить с помощью PowerShell.
- Запишите приведенные ниже учетные данные и сохраните их в надежном месте. В случае их утечки хакеры смогут получить доступ ко всем вашим данным Teams.
- Секретный код клиента
- идентификатор приложения (клиента);
- идентификатор каталога (клиента).
<# .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 = @{ "member.read.hidden" = "Member.Read.Hidden" "organization.read.all" = "Organization.Read.All" "channelmember.read.all" = "ChannelMember.Read.All" "channelmessage.read.all" = "ChannelMessage.Read.All" "channelsettings.read.all" = "ChannelSettings.Read.All" "group.read.all" = "Group.Read.All" "team.readbasic.all" = "Team.ReadBasic.All" "teammember.read.all" = "TeamMember.Read.All" "user.read.all" = "User.Read.All" “application.read.all” = “Application.Read.All” "chat.readbasic.all" = "Chat.ReadBasic.All" "chatmessage.read.all" = "ChatMessage.Read.All" "chatmember.read.all" = "ChatMember.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 (Новая регистрация) и введите название приложения (например, "Приложение для расширенного импорта").
- В разделе Поддерживаемые типы аккаунтов нажмите Аккаунты только в этом каталоге организации, чтобы создать приложение с одним клиентом.
- Нажмите Регистрация.
Шаг 2. Настройте разрешения API
Выберите один из вариантов:
Вариант 1. Добавьте разрешения вручную
- Сбоку в разделе Управление нажмите Разрешения API.
- Нажмите Add a permission (Добавить разрешение)
Microsoft APIs (API Microsoft)
Microsoft Graph.
- Для разрешений приложений выберите:
- Application.Read.All
- ChannelMember.Read.All
- ChannelMessage.Read.All
- ChannelSettings.Read.All
- Chat.ReadBasic.All
- ChatMember.Read.All
- ChatMessage.Read.All
- Group.Read.All
- Member.Read.Hidden
- Organization.Read.All
- Team.ReadBasic.All
- TeamMember.Read.All
- User.Read.All
- Нажмите Grant admin consent for название организации (Предоставить согласие администратора).
Вариант 2. Измените манифест приложения
- Откройте манифест приложения.
- Перейдите к разделу resourceAccess : [ ] и выберите вариант:
- Если у “resourceAccess” : [ ] уже есть значение, добавьте запятую, а затем вставьте следующий блок кода.
- Если у параметра “resourceAccess” : [ ] нет значения, скопируйте и вставьте следующий блок кода.
{ "id": "658aa5d8-239f-45c4-aa12-864f4fc7e490", "type": "Role" },
{ "id": "498476ce-e0fe-48b0-b801-37ba7e2685c6", "type": "Role" },
{ "id": "3b55498e-47ec-484f-8136-9013221c06a9", "type": "Role" },
{ "id": "7b2449af-6ccd-4f4d-9f78-e550c193f0d1", "type": "Role" },
{ "id": "c97b873f-f59f-49aa-8a0e-52b32d762124", "type": "Role" },
{ "id": "5b567255-7703-4780-807c-7be8301ae99b", "type": "Role" },
{ "id": "2280dda6-0bfd-44ee-a2f4-cb867cfc4c1e", "type": "Role" },
{ "id": "660b7406-55f1-41ca-a0ed-0b035e182f3e", "type": "Role" },
{ "id": "df021288-bdef-4463-88db-98f22de89214", "type": "Role" },
{ "id": "9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30", "type": "Role" }
{ "id": "b2e060da-3baf-4687-9611-f4ebc0f0cbde", "type": "Role" }
{ "id": "a3410be2-8e48-4f32-8454-c29a7465209d", "type": "Role" }
{ "id": "b9bb2381-47a4-46cd-aafb-00cb12f68504", "type": "Role" }
- Нажмите Grant admin consent for название организации (Предоставить согласие администратора).
Шаг 3. Создайте секретный код клиента
- На боковой панели в разделе Manage (Управление) нажмите Certificates & secrets (Сертификаты и секреты)
New client secret (Новый секретный код клиента).
- Введите описание, выберите срок хранения и нажмите Добавить.
- Скопируйте значение секретного кода клиента и храните его в надежном месте. Это значение будет показано только один раз.
Шаг 4. Получите учетные данные приложения
Важно! Храните учетные данные для приложения в надежном месте. В случае их утечки хакеры смогут получить доступ ко всем вашим данным Teams.
Нажмите Обзор и запишите следующие учетные данные:
- идентификатор приложения (клиента);
- идентификатор каталога (клиента).
Google, Google Workspace и связанные наименования и логотипы являются товарными знаками компании Google LLC. Все другие названия компаний и продуктов являются товарными знаками соответствующих компаний.