Disinstallare l'agente Azure Connected Machine dai server abilitati per Arc

Se non si vuole più gestire un computer tramite server abilitati per Azure Arc, è necessario rimuovere le estensioni di macchina virtuale dal server, disconnettere l'agente e disinstallare il software dal server. È importante completare tutti questi passaggi per rimuovere completamente tutti i componenti software correlati dal sistema.

Rimuovere le estensioni della macchina virtuale

Se sono state distribuite estensioni di macchine virtuali di Azure in un server abilitato per Azure Arc, è necessario disinstallare tutte le estensioni prima di disconnettere l'agente o disinstallare il software. La disinstallazione dell'agente Azure Connected Machine non rimuove automaticamente le estensioni e queste estensioni non vengono riconosciute se si riconnette il server a Azure Arc.

Per indicazioni su come elencare e rimuovere le estensioni nel server abilitato per Azure Arc, vedere le risorse seguenti:

Disconnettere il server da Azure Arc

Dopo aver rimosso tutte le estensioni dal server abilitato per Arc, il passaggio successivo consiste nel disconnettere l'agente. Questa azione elimina la risorsa Azure corrispondente per il server e cancella lo stato locale dell'agente.

Per disconnettere l'agente, eseguire il azcmagent disconnect comando come amministratore nel server. Viene richiesto di accedere con un account Azure autorizzato a eliminare la risorsa nella sottoscrizione. Se la risorsa è già stata eliminata in Azure, passare un flag aggiuntivo per pulire lo stato locale: azcmagent disconnect --force-local-only.

Se gli account amministratore e Azure sono diversi, potrebbero verificarsi problemi, perché la richiesta di accesso predefinita è impostata sull'account amministratore. Per risolvere questi problemi, eseguire il azcmagent disconnect --use-device-code comando . Viene richiesto di accedere con un account Azure con l'autorizzazione per eliminare la risorsa.

Caution

Quando si disconnette l'agente dalle macchine virtuali abilitate per Arc in esecuzione in Azure Locale, usare solo il comando azcmagent disconnect --force-local-only. L'uso del comando senza il flag --force-local-only può causare l'eliminazione della macchina virtuale Arc in Azure Locale sia da Azure che in locale.

Disinstallazione dell'agente

Dopo aver disconnesso l'agente da Azure Arc, rimuovere l'agente Connected Machine dal server.

Entrambi i metodi seguenti rimuovono l'agente, ma non rimuovono la cartella C:\Programmi\AzureConnectedMachineAgent nel computer.

Eseguire la disinstallazione dal Pannello di controllo

Seguire questa procedura per disinstallare l'agente Windows dal computer:

  1. Accedere al computer con un account dotato di autorizzazioni di amministratore.
  2. Nel Pannello di controllo selezionare Programmi e funzionalità.
  3. In Programmi e funzionalità selezionare Azure Connected Machine Agent, selezionare Uninstall e quindi selezionare Yes.

È anche possibile eliminare l'agente di Windows direttamente dall'installazione guidata dell'agente. A tale scopo, eseguire il pacchetto del programma di installazione di AzureConnectedMachineAgent.msi.

Eseguire la disinstallazione dalla riga di comando

È possibile disinstallare manualmente l'agente dal prompt dei comandi o usando un metodo automatizzato (ad esempio uno script) seguendo l'esempio seguente. Prima di tutto è necessario recuperare il codice prodotto, ovvero un GUID che è l'identificatore principale del pacchetto dell'applicazione, dal sistema operativo. La disinstallazione viene eseguita usando la riga di comando Msiexec.exe - msiexec /x {Product Code}.

  1. Aprire l'Editor del Registro di sistema.

  2. Nella chiave del Registro di sistema HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall, cercare e copiare il GUID del codice prodotto.

  3. Disinstallare l'agente usando Msiexec, come negli esempi seguenti:

    • Dalla riga di comando immettere il comando seguente:

      msiexec.exe /x {product code GUID} /qn
      
    • È possibile eseguire gli stessi passaggi usando PowerShell:

      Get-ChildItem -Path HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall | `
      Get-ItemProperty | `
      Where-Object {$_.DisplayName -eq "Azure Connected Machine Agent"} | `
      ForEach-Object {MsiExec.exe /x "$($_.PsChildName)" /qn}
      

Rimuovere le risorse server non aggiornati

Se si rimuove o si disconnette un server senza rimuovere correttamente l'agente, la risorsa rimane in genere nel portale di Azure con uno stato Disconnected. Nel corso del tempo, queste risorse non aggiornate possono ingombrare l'ambiente.

Lo script di PowerShell seguente consente di identificare ed eliminare server abilitati ad Azure Arc che sono stati disconnessi per un numero specificato di giorni.

Prerequisites

  • Azure PowerShell: modulo Az installato.
  • Autorizzazioni: accesso come lettore alle query tramite Azure Resource Graph e Collaboratore o Proprietario (o Microsoft.HybridCompute/machines/delete) per eliminare le risorse.

Script di pulizia

Questo script utilizza Azure Resource Graph per eseguire query Microsoft.HybridCompute/machines sulle risorse dove lo stato è Disconnected e il lastStatusChange timestamp è precedente alla soglia configurata.

Salvare il codice seguente come Cleanup-StaleArcServers.ps1.

<#
.SYNOPSIS
    Identifies and removes stale Azure Arc-enabled servers that have been disconnected for a specified number of days.

.DESCRIPTION
    This script queries Azure Resource Graph to find Azure Arc-enabled servers (Microsoft.HybridCompute/machines)
    that have a status of 'Disconnected' and have not updated their status for more than the specified number of days.
    Supports -WhatIf and -Confirm via SupportsShouldProcess.

.PARAMETER DaysDisconnected
    The number of days a server must be disconnected to be considered stale. Default is 60.

.PARAMETER Subscription
    Optional. One or more Subscription IDs to scope the query to.
    If not specified, queries all subscriptions the current context has access to.

.PARAMETER ManagementGroup
    Optional. A Management Group name to scope the query to.
    Cannot be used together with -Subscription.

.EXAMPLE
    .\Cleanup-StaleArcServers.ps1 -DaysDisconnected 60 -WhatIf
    Lists Arc servers disconnected for more than 60 days across all subscriptions.

.EXAMPLE
    .\Cleanup-StaleArcServers.ps1 -DaysDisconnected 90 -Subscription 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
    Permanently deletes Arc servers disconnected for more than 90 days in the specified subscription.

.NOTES
    Author: Microsoft
    Date: 2026-01-12
    Requires: Az.ResourceGraph, Az.Resources
#>

[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
param (
    [int]$DaysDisconnected = 60,
    
    [ValidateNotNullOrEmpty()]
    [string[]]$Subscription,

    [ValidateNotNullOrEmpty()]
    [string]$ManagementGroup
)

# Check required modules
foreach ($mod in @('Az.ResourceGraph', 'Az.Resources')) {
    if (-not (Get-Module -Name $mod -ListAvailable -ErrorAction SilentlyContinue)) {
        Write-Error "Required module '$mod' is not installed. Run: Install-Module $mod -Scope CurrentUser"
        return
    }
}

# Check for Azure connection
try {
    $context = Get-AzContext -ErrorAction Stop
    Write-Host "Connected to Azure context: $($context.Name)" -ForegroundColor Cyan
}
catch {
    Write-Error "Not connected to Azure. Please run 'Connect-AzAccount' first."
    return
}

# Construct the KQL query
# We look for resources of type hybridcompute/machines
# Status must be Disconnected
# lastStatusChange must be older than $DaysDisconnected
$kqlQuery = @"
Resources
| where type == 'microsoft.hybridcompute/machines'
| where properties.status == 'Disconnected'
| where properties.lastStatusChange < ago($($DaysDisconnected)d)
| project id, name, resourceGroup, subscriptionId, location, status = properties.status, lastStatusChange = properties.lastStatusChange
"@

Write-Host "Searching for Arc servers disconnected for more than $DaysDisconnected days..." -ForegroundColor Yellow

# Execute Search with pagination (Search-AzGraph returns max 1000 results per call)
$staleServers = [System.Collections.Generic.List[object]]::new()
$skipToken = $null

try {
    do {
        $params = @{
            Query = $kqlQuery
            First = 1000
        }
        if ($skipToken) {
            $params['SkipToken'] = $skipToken
        }
        if ($Subscription) {
            $params['Subscription'] = $Subscription
        }
        if ($ManagementGroup) {
            $params['ManagementGroup'] = $ManagementGroup
        }

        $result = Search-AzGraph @params -ErrorAction Stop
        if ($result) {
            $staleServers.AddRange([object[]]$result)
            $skipToken = $result.SkipToken
        }
    } while ($skipToken)
}
catch {
    Write-Error "Failed to query Azure Resource Graph. Ensure resource graph module is installed and you have read permissions.`nError: $_"
    return
}

if ($staleServers.Count -eq 0) {
    Write-Host "No stale Arc servers found matching the criteria." -ForegroundColor Green
    return
}

Write-Host "Found $($staleServers.Count) stale servers." -ForegroundColor Yellow

# Process results
$successCount = 0
$failCount = 0

foreach ($server in $staleServers) {
    if ($PSCmdlet.ShouldProcess($server.id, "Delete stale Arc server '$($server.name)' (Disconnected since: $($server.lastStatusChange))")) {
        try {
            Remove-AzResource -ResourceId $server.id -Force -ErrorAction Stop
            Write-Host "Successfully deleted '$($server.name)'." -ForegroundColor Green
            $successCount++
        }
        catch {
            Write-Error "Failed to delete '$($server.name)'. Error: $_"
            $failCount++
        }
    }
}

Write-Host "`nCleanup completed. Deleted: $successCount, Failed: $failCount, Total: $($staleServers.Count)" -ForegroundColor Green

Come usare lo script

Prerequisites

Lo script richiede i moduli di PowerShell seguenti:

  • Az.ResourceGraph
  • Az.Resources

Se non sono installati, eseguire:

Install-Module Az.ResourceGraph, Az.Resources -Scope CurrentUser

Steps

  1. Accedere ad Azure

    Aprire il terminale di PowerShell e accedere.

    Connect-AzAccount
    
  2. Eseguire un'analisi What-If

    Per prima cosa, eseguire lo script con l'opzione -WhatIf. Questo passaggio elenca i server che soddisfano i criteri senza eliminarli effettivamente. Questo comando controlla i server disconnessi per 60 giorni o più.

    .\Cleanup-StaleArcServers.ps1 -DaysDisconnected 60 -WhatIf
    

    Per definire l'ambito della query a una sottoscrizione specifica, usare il -Subscription parametro :

    .\Cleanup-StaleArcServers.ps1 -DaysDisconnected 60 -Subscription 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' -WhatIf
    

    Per definire invece l'ambito della query in un gruppo di gestione, usare il -ManagementGroup parametro :

    .\Cleanup-StaleArcServers.ps1 -DaysDisconnected 60 -ManagementGroup 'MyManagementGroup' -WhatIf
    

    Esaminare l'output per assicurarsi che elenca solo i server desiderati.

  3. Eseguire la pulizia

    Quando si è certi dell'elenco dei server da rimuovere, eseguire lo script senza l'opzione -WhatIf .

    .\Cleanup-StaleArcServers.ps1 -DaysDisconnected 60
    

    Per pulire i server disconnessi per un periodo più lungo (ad esempio, sei mesi), aumentare il numero di giorni:

    .\Cleanup-StaleArcServers.ps1 -DaysDisconnected 180
    

    Lo script richiede la conferma prima di ogni eliminazione. Per ignorare le richieste, aggiungere -Confirm:$false.