Condividi tramite


Configurare la fonte di autorità di gruppo (SOA)

Questo articolo illustra i prerequisiti e i passaggi per configurare l'origine del gruppo di autorità (SOA), come ripristinare le modifiche e le limitazioni. Per ulteriori informazioni sul gruppo SOA, vedere Adottare la strategia cloud-first: Convertire il Group Source of Authority nel cloud.

Prerequisiti

Requisito Descrizione
Ruoli L'amministratore ibrido deve chiamare le API Microsoft Graph per leggere e aggiornare SOA di gruppi.
Per concedere il consenso dell'utente alle autorizzazioni necessarie a Microsoft Graph Explorer o all'app usata per chiamare le API Di Microsoft Graph, è necessario l'amministratore dell'applicazione o l'amministratore di applicazioni cloud.
Autorizzazioni Per le app che chiamano nell'API Microsoft Graph onPremisesSyncBehavior, è necessario concedere l'ambito di autorizzazione Group-OnPremisesSyncBehavior.ReadWrite.All. Per altre informazioni, vedere come concedere questa autorizzazione a Graph Explorer o a un'app esistente nel tenant.
Licenza necessaria Licenza Microsoft Entra Free.
Client di sincronizzazione È possibile usare uno dei client di sincronizzazione per sincronizzare i gruppi convertiti SOA. Se si usa Connect Sync, eseguire l'aggiornamento alla versione minima 2.5.76.0. Se si usa Cloud Sync, eseguire l'aggiornamento alla versione minima 1.1.1370.0.
Distribuzione in Servizi di dominio Active Directory (facoltativo) Per effettuare il provisioning di un gruppo convertito in SOA da Microsoft Entra ID ad Active Directory Domain Services (AD DS), è necessario usare Cloud Sync. È anche necessario completare i passaggi per preparare i gruppi per il provisioning su Active Directory Domain Services, mantenendo il percorso originale dell'unità organizzativa. Per altre informazioni, vedere Preparare i gruppi per la conversione e il provisioning SOA del gruppo.

Scaricare il client connect sync

  1. Scaricare Connect Sync build 2.5.76.0 o versione successiva.

  2. Passare a Programmi nel Pannello di controllo e confermare la versione di Microsoft Entra Connect Sync.

Scaricare il client di sincronizzazione cloud

  1. Scaricare cloud sync build 1.1.1370.0 o versione successiva.

  2. Informazioni su come identificare la versione corrente dell'agente.

  3. Configurare il provisioning tra Active Directory Domain Services e Microsoft Entra ID secondo le istruzioni.

Concedere l'autorizzazione alle app

È possibile concedere l'autorizzazione nell'interfaccia di amministrazione di Microsoft Entra o in Graph Explorer. Questa operazione con privilegi elevati richiede il ruolo Amministratore applicazione o Amministratore applicazione cloud. È anche possibile concedere il consenso usando PowerShell. Per altre informazioni, vedere Concedere il consenso per conto di un singolo utente.

App personalizzate

Seguire questa procedura per concedere Group-OnPremisesSyncBehavior.ReadWrite.All l'autorizzazione all'app corrispondente. Per altre informazioni su come aggiungere nuove autorizzazioni alla registrazione dell'app e concedere il consenso, vedere Aggiornare le autorizzazioni richieste di un'app in Microsoft Entra ID.

Usare l'interfaccia di amministrazione di Microsoft Entra per concedere l'autorizzazione alle app

  1. Accedere all'interfaccia di amministrazione di Microsoft Entra come amministratore dell'applicazione o amministratore di applicazioni cloud.

  2. Passare a Nome> aziendali.

  3. Selezionare Autorizzazioni>Concedi consenso amministratore per il nome del tenant.

  4. Accedere di nuovo come amministratore dell'applicazione o amministratore di applicazioni cloud.

  5. Esaminare l'elenco delle autorizzazioni che richiedono il consenso e selezionare Accetta.

  6. È possibile visualizzare l'elenco delle autorizzazioni concesse:

    Screenshot di come concedere l'autorizzazione.

Usare Graph Explorer per concedere l'autorizzazione alle app

  1. Aprire Graph Explorer e accedere come amministratore dell'applicazione o amministratore di applicazioni cloud.
  2. Selezionare l'icona del profilo e selezionare Consenti alle autorizzazioni.
  3. Cercare Group-OnPremisesSyncBehavior e selezionare Consent per l'autorizzazione.

Screenshot di come concedere il consenso all'autorizzazione Group-OnPremisesSyncBehavior.ReadWrite.

Preparare i gruppi per la conversione e il provisioning SOA del gruppo

Se si desidera eseguire il provisioning del gruppo su Servizi di dominio Active Directory (AD DS), pianificare di completare i passaggi seguenti per preservare il percorso dell'unità organizzativa e impostarlo nella configurazione Provisioning gruppo su Active Directory con il corretto mapping:

  1. Modificare l'ambito del gruppo per i gruppi di Active Directory Domain Services impostando Universale.
  2. Creare una proprietà dell'estensione della directory a livello di tenant per i gruppi.
  3. Eseguire il mapping di un valore locale, ad esempio il nome distinto (DN), direttamente nella proprietà di estensione.
  4. Verificare il valore della proprietà usando Microsoft Graph.
  5. Convertire la Fonte di Autorità (SOA) quando è pronta.
  6. Usare espressioni personalizzate per garantire che Cloud Sync effettui il provisioning dei gruppi in Active Directory Domain Services con gli stessi valori CN e OU.

Per altre informazioni, vedere Effettuare il provisioning di gruppi in Servizi di dominio Active Directory tramite Microsoft Entra Cloud Sync.

Convertire SOA per un gruppo di test

Seguire questa procedura per convertire soA per un gruppo di test:

  1. Creare un gruppo di sicurezza o un gruppo di distribuzione abilitato alla posta elettronica in AD per testare e aggiungere membri del gruppo. È anche possibile usare un gruppo sincronizzato con Microsoft Entra ID usando Connect Sync.

  2. Eseguire il comando seguente per avviare Connetti sincronizzazione:

    Start-ADSyncSyncCycle
    
  3. Verificare che il gruppo venga visualizzato nell'interfaccia di amministrazione di Microsoft Entra come gruppo sincronizzato.

  4. Usare l'API Microsoft Graph per convertire l'oggetto SOA dell'oggetto gruppo (isCloudManaged=true). Aprire Microsoft Graph Explorer e accedere con un ruolo utente appropriato, ad esempio l'amministratore dei gruppi.

  5. Controllare lo stato SOA esistente. Il valore dell'attributo isCloudManaged non è ancora stato aggiornato, quindi il valore dell'attributo isCloudManaged deve essere false. Sostituire {ID} negli esempi seguenti con l'ID oggetto del gruppo. Per altre informazioni su questa API, vedere Get onPremisesSyncBehavior.

    GET https://graph.microsoft.com/v1.0/groups/{ID}/onPremisesSyncBehavior?$select=isCloudManaged
    

    Screenshot di come usare Microsoft Graph Explorer per ottenere il valore SOA di un gruppo.

  6. Verificare che il gruppo sincronizzato sia di sola lettura. Poiché il gruppo è gestito in locale, tutti i tentativi di scrittura nel gruppo nel cloud hanno esito negativo. Il messaggio di errore è diverso per i gruppi abilitati alla posta elettronica, ma gli aggiornamenti non sono ancora consentiti.

    Annotazioni

    Se l'API ha esito negativo con 403, usare la scheda Modifica autorizzazioni per concedere il consenso all'autorizzazione Group.ReadWrite.All richiesta.

    PATCH https://graph.microsoft.com/v1.0/groups/{ID}/
       {
         "DisplayName": "Group1 Name Updated"
       }   
    

    Screenshot di un tentativo di aggiornamento di un gruppo per verificare che sia di sola lettura.

  7. Cercare il gruppo nell'interfaccia di amministrazione di Microsoft Entra. Verificare che tutti i campi di gruppo siano disattivati e che l'origine sia Windows Server Active Directory Domain Services (AD DS).

    Screenshot delle proprietà di base del gruppo.

    Screenshot delle proprietà avanzate del gruppo.

  8. È ora possibile aggiornare l'account SOA del gruppo in modo che sia gestito dal cloud. Eseguire l'operazione seguente in Microsoft Graph Explorer per l'oggetto gruppo da convertire nel cloud. Per altre informazioni su questa API, vedere Update onPremisesSyncBehavior.

    PATCH https://graph.microsoft.com/v1.0/groups/{ID}/onPremisesSyncBehavior
       {
         "isCloudManaged": true
       }   
    

    Screenshot dell'operazione PATCH per aggiornare le proprietà del gruppo.

  9. Per convalidare la modifica, chiamare GET per verificare che isCloudManaged sia true.

    GET https://graph.microsoft.com/v1.0/groups/{ID}/onPremisesSyncBehavior?$select=isCloudManaged
    

    Screenshot della chiamata GET per verificare le proprietà del gruppo.

  10. Confermare la modifica nei log di controllo. Per accedere ai log di controllo nel portale di Azure, aprire Manage Microsoft Entra ID>Monitoring>Audit Logs o cercare i log di controllo. Selezionare Change Source of Authority from AD to cloud (Modifica origine dell'autorità da AD a cloud ) come attività.

    Screenshot della modifica alle proprietà del gruppo nei log di controllo.

  11. Verificare che il gruppo possa essere aggiornato nel cloud.

    PATCH https://graph.microsoft.com/v1.0/groups/{ID}/
       {
         "DisplayName": "Group1 Name Updated"
       }   
    

    Screenshot di un nuovo tentativo per modificare le proprietà del gruppo.

  12. Aprire l'interfaccia di amministrazione di Microsoft Entra e verificare che la proprietà Source del gruppo sia Cloud.

    Screenshot di come confermare la proprietà di origine del gruppo.

Connettere il client di sincronizzazione

  1. Eseguire il comando seguente per avviare Connetti sincronizzazione:

    Start-ADSyncSyncCycle
    
  2. Per esaminare l'oggetto gruppo con SOA convertito, in Synchronization Service Manager passare a Connettori:

    Screenshot dei connettori.

  3. Fare clic con il pulsante destro del mouse su Active Directory Domain Services Connector. Cercare il gruppo in base al nome di dominio relativo (RDN) impostazione "CN=<GroupName>":

    Screenshot di come cercare RDN.

  4. Fare doppio clic sulla voce cercata e selezionare DerivazioneMetaverse Object Properties (Proprietà oggetto Metaverse di >).

    Screenshot di come visualizzare la derivazione.

  5. Selezionare Connettori e fare doppio clic sull'oggetto Entra ID con "CN={<Caratteri> alfanumerici}".

  6. Si noterà che la proprietà blockOnPremisesSync è impostata su true nell'oggetto ENTRA ID. Questo valore della proprietà indica che tutte le modifiche apportate all'oggetto Ad DS corrispondente non vengono propagate all'oggetto Entra ID:

    Screenshot di come bloccare il flusso di dati.

  7. Si aggiornerà ora l'oggetto gruppo locale. Il nome del gruppo verrà modificato da SecGroup1 a SecGroup1.1:

    Screenshot di come modificare il nome dell'oggetto.

  8. Eseguire il comando seguente per avviare Connetti sincronizzazione:

    Start-ADSyncSyncCycle
    
  9. Aprire il Visualizzatore eventi e filtrare il registro applicazioni per l'ID evento 6956. Questo ID evento è riservato per informare i clienti che l'oggetto non è sincronizzato con il cloud perché il SOA dell'oggetto si trova nel cloud.

    Screenshot dell'ID evento 6956.

Aggiornamenti in blocco per SOA di gruppo

È possibile usare lo script di PowerShell seguente per automatizzare gli aggiornamenti SOA di gruppo usando l'autenticazione basata su app.

<#
.SYNOPSIS
    Updates groups to set isCloudManaged parameter to true for on-premises synchronized groups.

.DESCRIPTION
    This script reads a file containing group Ids, checks each group's OnPremisesSyncEnabled property,
    and if true, calls the onPremisesSyncBehavior API to set isCloudManaged to true.

.PARAMETER FilePath
    Mandatory. Path to the file containing group Ids (one per line).

.PARAMETER WhatIf
    Boolean parameter. When true (default), shows what would be done without making actual changes.

.EXAMPLE
    .\Update-GroupSoA.ps1 -FilePath "C:\temp\groups.txt"
    .\Update-GroupSoA.ps1 -FilePath "C:\temp\groups.txt" -WhatIf $false

.NOTES
    Requires Microsoft.Graph PowerShell module to be installed and appropriate permissions.
    Required Graph permissions: Group.ReadWrite.All, Group-OnPremisesSyncBehavior.ReadWrite.All

    Input file should contain one group Id (GUID) per line.
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [string]$FilePath,

    [Parameter(Mandatory = $false)]
    [bool]$WhatIf = $true
)

# Import Groups module
try {
    $moduleName = "Microsoft.Graph.Groups"
    if (-not (Get-Module -Name $moduleName)) {
        Import-Module -Name $moduleName
    }
    Write-Host "Successfully imported Microsoft Graph modules."
}
catch {
    Write-Error "Failed to import Microsoft Graph modules. Please ensure Microsoft.Graph PowerShell SDK is installed."
    Write-Host "Install with: Install-Module Microsoft.Graph -Scope CurrentUser"
    exit 1
}

# Connect to MS Graph
$context = Get-MgContext
if (-not $context) {
    Connect-MgGraph -Scopes 'Group.ReadWrite.All', 'Group-OnPremisesSyncBehavior.ReadWrite.All'
}

# Validate input file
if (-not (Test-Path $FilePath)) {
    Write-Error "Input file not found: $FilePath"
    exit 1
}

Write-Host "Starting group update process using $FilePath (WhatIf: $WhatIf)..."
Write-Host "-----------------------------------"

# Read group Ids from file
$groupGuids = Get-Content $FilePath

if ($groupGuids.Count -eq 0) {
    Write-Error "No group Ids found in the input file."
    exit 1
}

Write-Host "Found $($groupGuids.Count) group Ids to process."

# Initialize counters for summary
$totalGroups = $groupGuids.Count
$processedCount = 0
$updatedCount = 0
$skippedCount = 0
$errorCount = 0

# Process each group
foreach ($groupId in $groupGuids) {
    $processedCount++
    Write-Host "`nProcessing $groupId ($processedCount/$totalGroups)"

    try {
        $group = Get-MgGroup -GroupId $groupId -Property "Id,DisplayName,OnPremisesSyncEnabled"

        Write-Host "Group Name: $($group.DisplayName)"
        Write-Host "OnPremisesSyncEnabled: $($group.OnPremisesSyncEnabled)"

        if ($group.OnPremisesSyncEnabled -eq $true) {
            $actionDescription = "Set isCloudManaged to true for group '$($group.DisplayName)'"

            if ($WhatIf) {
                Write-Host "Skipping since WhatIf is enabled: $actionDescription"
                $skippedCount++
            }
            else {
                try {
                    # Call the onPremisesSyncBehavior API to set isCloudManaged to true
                    $body = @{
                        isCloudManaged = $true
                    }

                    $uri = "https://graph.microsoft.com/v1.0/groups/$groupId/onPremisesSyncBehavior"
                    Invoke-MgGraphRequest -Uri $uri -Method PATCH -Body ($body | ConvertTo-Json) -ContentType "application/json"

                    Write-Host "SUCCESS: Updated group to cloud-managed"
                    $updatedCount++
                }
                catch {
                    Write-Host "ERROR: Failed to update group: $_"
                    $errorCount++
                }
            }
        }
        else {
            Write-Host "SKIPPED: Group is not on-premises synchronized"
            $skippedCount++
        }
    }
    catch {
        Write-Host "ERROR: Failed to retrieve group information: $_"
        $errorCount++
    }
}

Write-Host "`n-----------------------------------"
Write-Host "SUMMARY"
Write-Host "-----------------------------------"
Write-Host "Total groups processed: $totalGroups"
Write-Host "Successfully updated: $updatedCount"
Write-Host "Skipped (not sync-enabled or WhatIf): $skippedCount"
Write-Host "Errors encountered: $errorCount"

Write-Host "`nScript completed."

Stato degli attributi dopo la conversione di SOA

La tabella seguente illustra lo stato per gli attributi isCloudManaged e onPremisesSyncEnabled dopo aver convertito l'SOA di un oggetto.

Passaggio amministratore isCloudManaged valore Valore di onPremisesSyncEnabled Descrizione
L'amministratore sincronizza un oggetto da Active Directory Domain Services a Microsoft Entra ID false true Quando un oggetto è originariamente sincronizzato con Microsoft Entra ID, l'attributo onPremisesSyncEnabled è impostato su true e isCloudManaged è impostato su false. 
L'amministratore converte l'origine dell'autorità (SOA) dell'oggetto nel cloud true null Dopo che un amministratore converte il SOA di un oggetto nel cloud, l'attributo isCloudManaged diventa impostato su true e il valore dell'attributo onPremisesSyncEnabled è impostato su null. 
L'amministratore esegue il rollback dell'operazione SOA false null Se un amministratore converte nuovamente soA in AD, isCloudManaged è impostato su e false viene impostato su null fino a quando il client di sincronizzazione non acquisisce l'oggetto.   
L'amministratore crea un oggetto nativo del cloud in Microsoft Entra ID false null Se un amministratore crea un nuovo oggetto nativo del cloud in Microsoft Entra ID, isCloudManaged è impostato su e false è impostato su null.

Eseguire il rollback dell'aggiornamento SOA

Importante

Assicurarsi che i gruppi di cui si esegue il rollback non dispongano di riferimenti al cloud. Rimuovere gli utenti cloud dai gruppi convertiti SOA e rimuovere questi gruppi dai pacchetti di accesso prima di eseguire il rollback del gruppo in Servizi di dominio Active Directory. Il client di sincronizzazione acquisisce l'oggetto nel ciclo di sincronizzazione successivo. Per uno script di PowerShell di esempio per identificare e rimuovere gli utenti cloud dai gruppi, vedere Script per identificare i membri cloud (utenti) di un gruppo.

È possibile eseguire questa operazione per eseguire il rollback dell'aggiornamento SOA e ripristinare l'ambiente SOA in locale.

PATCH https://graph.microsoft.com/v1.0/groups/{ID}/onPremisesSyncBehavior
   {
     "isCloudManaged": false
   }   

Screenshot della chiamata API per ripristinare SOA.

Annotazioni

La modifica di isCloudManaged per consente a false un oggetto di Active Directory Domain Services nell'ambito della sincronizzazione di essere acquisito da Connect Sync alla successiva esecuzione. Fino alla successiva esecuzione di Connect Sync, l'oggetto può essere modificato nel cloud. Il rollback di SOA viene completato solo dopo che entrambe le chiamate API e la successiva esecuzione pianificata o forzata di Connect Sync sono state completate.

Convalidare la modifica nei log di controllo

Selezionare l'attività Annulla modifiche all'origine dell'autorità da Servizi di dominio Active Directory al cloud:

Screenshot delle modifiche di annullamento nei log di controllo.

Convalidare nel client di sincronizzazione connetti

  1. Eseguire il comando seguente per avviare Connetti sincronizzazione:

    Start-ADSyncSyncCycle
    
  2. Aprire l'oggetto in Synchronization Server Manager (i dettagli sono nella sezione Connetti client di sincronizzazione ). È possibile visualizzare lo stato dell'oggetto connettore Microsoft Entra ID è Awaiting Export Confirmation e blockOnPremisesSync = false, il che significa che l'oggetto SOA viene nuovamente acquisito dall'ambiente locale.

    Screenshot di un oggetto in attesa dell'esportazione.

Limitazioni

  • Nessun supporto per la riconciliazione per i gruppi di Active Directory Domain Services: un amministratore di Active Directory Domain Services (o un'applicazione con autorizzazioni sufficienti) può modificare direttamente un gruppo di Active Directory Domain Services. Se il gruppo SOA viene convertito per il gruppo o se il provisioning del gruppo di sicurezza cloud in Servizi di dominio Active Directory è abilitato, tali modifiche di Active Directory locali non vengono riflesse nell'ID Microsoft Entra. Quando viene apportata una modifica al gruppo di sicurezza cloud, tutte le modifiche locali di Active Directory Domain Services vengono sovrascritte durante l'esecuzione del provisioning dei gruppi in Servizi di dominio Active Directory.

  • Nessuna doppia scrittura consentita: dopo aver iniziato a gestire le appartenenze per il gruppo convertito (ad esempio il gruppo cloud A) da Microsoft Entra ID e si effettua il provisioning di questo gruppo in AD come gruppo annidato in un altro gruppo di Active Directory Domain Services (OnPremGroupB) nell'ambito della sincronizzazione con Microsoft Entra ID, i riferimenti di appartenenza del gruppo A non vengono sincronizzati quando si verifica la sincronizzazione per OnPremGroupB. I riferimenti all'appartenenza non vengono sincronizzati perché il client di sincronizzazione non conosce i riferimenti all'appartenenza al gruppo cloud. Questo comportamento è predefinito.

  • Nessuna conversione SOA di gruppi annidati: se sono presenti gruppi annidati in Servizi di dominio Active Directory e si vuole convertire l'soA del gruppo padre o del gruppo principale in ID Microsoft Entra, viene convertito solo il gruppo padre SOA. I gruppi annidati nel gruppo padre continuano a essere gruppi di Active Directory Domain Services. È necessario convertire l'soA di tutti i gruppi annidati uno per uno. È consigliabile iniziare con il gruppo più basso nella gerarchia e spostarsi verso l'alto nell'albero.

  • Nessun supporto per gli attributi di estensione (1-15): gli attributi di estensione da 1 a 15 non sono supportati nei gruppi di sicurezza cloud e non sono supportati dopo la conversione di SOA.

Script per identificare i membri cloud (utenti) di un gruppo

Lo script seguente può essere usato per identificare e rimuovere gli utenti cloud dai gruppi:

<#
.SYNOPSIS
    Finds cloud users in an Entra ID group and optionally removes them.

.DESCRIPTION
    This script pages through all users in a specified Entra ID group, identifies cloud users
    (users where onPremisesSyncEnabled is not set to true), and prints their details.
    Optionally removes these users from the group if removeUsers is set to true.

.PARAMETER GroupId
    The GUID of the Entra ID group to process. This parameter is required.

.PARAMETER RemoveUsers
    Boolean flag to indicate whether to remove cloud users from the group. 
    Default is false (optional parameter).

.EXAMPLE
    .\Find-CloudUsersInGroup.ps1 -GroupId "12345678-1234-1234-1234-123456789012"
    .\Find-CloudUsersInGroup.ps1 -GroupId "12345678-1234-1234-1234-123456789012" -RemoveUsers $true

.NOTES
    Requires Microsoft.Graph PowerShell module to be installed and appropriate permissions.
    Required Graph permissions: Group.Read.All, GroupMember.Read.All, User.Read.All and GroupMember.ReadWrite.All (if removing users)
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [System.Guid]$GroupId,

    [Parameter(Mandatory = $false)]
    [bool]$RemoveUsers = $false
)

# Import required modules
try {
    $moduleName = "Microsoft.Graph.Groups"
    if (-not (Get-Module -Name $moduleName)) {
        Import-Module -Name $moduleName
    }
    $moduleName = "Microsoft.Graph.Users"
    if (-not (Get-Module -Name $moduleName)) {
        Import-Module -Name $moduleName
    }
    Write-Host "Microsoft Graph modules imported successfully"
}
catch {
    Write-Error "Failed to import Microsoft Graph modules. Please install Microsoft.Graph PowerShell module."
    Write-Error "Run: Install-Module Microsoft.Graph -Scope CurrentUser"
    exit 1
}

# Connect to MS Graph and verify the group exists
$context = Get-MgContext
if (-not $context) {
    Connect-MgGraph -Scopes 'Group.Read.All','GroupMember.Read.All','GroupMember.ReadWrite.All','User.Read.All'
}

$group = Get-MgGroup -GroupId $GroupId -Property "Id,DisplayName,MailEnabled"
Write-Host "Processing group: $($group.DisplayName) (ID: $GroupId)"

if ($group.MailEnabled -eq $true) {
    Write-Warning "The specified group is mail-enabled. Users can only be identified using this script. To remove users, use Exchange."
}

# Initialize counters
$totalUsers = 0
$cloudUsers = 0
$removedUsers = 0

Write-Host "`nStarting to process group users..."

try {
    # Get all group members that are users
    $usersInGroup = Get-MgGroupMemberAsUser -GroupId $GroupId -All -Property "Id"

    if ($usersInGroup.Count -ge 1) {
        $totalUsers = $usersInGroup.Count
        Write-Host "Found $totalUsers total users in the group"
    }
    else {
        Write-Host "No users found in the group"
        exit 0
    }
}
catch {
    Write-Error "Failed to retrieve group users: $($_.Exception.Message)"
    exit 1
}

Write-Host "`nProcessing each user to identify cloud users..."
Write-Host "-----------------"

# Process each user
foreach ($user in $usersInGroup) {
    try {
        # Get detailed user information
        $user = Get-MgUser -UserId $user.Id -Property "Id,DisplayName,UserPrincipalName,OnPremisesSyncEnabled"

        # Check if user is a cloud user
        $isCloudUser = -not $user.OnPremisesSyncEnabled

        if ($isCloudUser) {
            $cloudUsers++

            # Print cloud user details
            Write-Host "Cloud User Found:"
            Write-Host "  Object ID: $($user.Id)"
            Write-Host "  Display Name: $($user.DisplayName)"
            Write-Host "  User Principal Name: $($user.UserPrincipalName)"
            Write-Host "  OnPremisesSyncEnabled: $($user.OnPremisesSyncEnabled)"

            # Remove user from group if requested
            if ($RemoveUsers) {
                Remove-MgGroupMemberByRef -GroupId $GroupId -DirectoryObjectId $user.Id -ErrorAction Stop
                Write-Host "REMOVED from group"
                $removedUsers++
            }
        }
    }
    catch {
        Write-Warning "Failed to process User ID $($user.Id): $($_.Exception.Message)"
    }
}

# Summary
Write-Host "-----------------"
Write-Host "SUMMARY:"
Write-Host "-----------------"
Write-Host "Total group users processed: $totalUsers"
Write-Host "Cloud users identified: $cloudUsers"
if ($RemoveUsers) {
    Write-Host "Cloud users successfully removed: $removedUsers"
}

if ($cloudUsers -eq 0) {
    Write-Host "No cloud users found in this group."
}

Write-Host "`nScript completed."

Questo script viene fornito come esempio e non deve essere considerato come materiale sussidiario ufficiale su come identificare e rimuovere gli utenti cloud dalle appartenenze ai gruppi.