Удаление агента подключенного к Azure компьютера с Arc-совместимых серверов

Если вы больше не хотите управлять компьютером с помощью серверов с поддержкой Azure Arc, необходимо удалить все расширения виртуальных машин с сервера, отключить агент и удалить программное обеспечение с сервера. Важно выполнить все эти действия, чтобы полностью удалить все связанные компоненты программного обеспечения из системы.

Удаление расширений виртуальных машин

При развертывании расширений виртуальной машины Azure на сервере с поддержкой Azure Arc необходимо удалить все расширения перед отключением агента или удалением программного обеспечения. Удаление агента подключенного компьютера Azure не удаляет расширения автоматически, и эти расширения не распознают при повторном подключении сервера к Azure Arc.

Инструкции по перечислению и удалению расширений на сервере с поддержкой Azure Arc см. в следующих ресурсах:

Отключение сервера от Azure Arc

После удаления всех расширений с сервера с поддержкой Arc следующий шаг — отключить агент. Это действие удаляет соответствующий ресурс Azure для сервера и очищает локальное состояние агента.

Чтобы отключить агент, выполните azcmagent disconnect команду от имени администратора на сервере. Вам будет предложено войти с помощью учетной записи Azure с разрешением на удаление ресурса в подписке. Если ресурс уже удален в Azure, передайте дополнительный флаг для очистки локального состояния: azcmagent disconnect --force-local-only.

Если учетные записи администратора и Azure отличаются, вам может быть предложено использовать учетную запись администратора по умолчанию при входе в систему, что может вызвать проблемы. Чтобы устранить эти проблемы, выполните azcmagent disconnect --use-device-code команду. Вам будет предложено войти с помощью учетной записи Azure, которая имеет разрешение на удаление ресурса.

Предостережение

При отключении агента от виртуальных машин с поддержкой Arc, работающих на Azure Local, используйте только команду azcmagent disconnect --force-local-only. Использование команды без флага --force-local-only может привести к удалению виртуальной машины Arc в Azure Local как из Azure, так и из локальной среды.

Удалите агента

После отключения агента от Azure Arc удалите агент подключенного компьютера с сервера.

Оба следующих метода удаляют агент, но они не удаляют папку C:\Program Files\AzureConnectedMachineAgent на компьютере.

Удалить из Панели управления

Выполните следующие действия, чтобы удалить агент Windows с компьютера:

  1. Войдите в систему компьютера, используя учетную запись с правами администратора.
  2. На панели управления выберите "Программы и компоненты".
  3. В Programs and Features, выберите Агент подключенного компьютера Azure, выберите Удалить, и затем выберите Да.

Вы также можете удалить агент Windows непосредственно из мастера установки агента. Выполните пакет установщика AzureConnectedMachineAgent.msi , чтобы сделать это.

Удалить из командной строки

Агент можно удалить вручную из командной строки или с помощью автоматизированного метода (например, скрипта), выполнив приведенный ниже пример. Сначала необходимо получить код продукта, который является основным GUID-идентификатором пакета приложения, из операционной системы. Удаление выполняется с помощью командной строки Msiexec.exe . msiexec /x {Product Code}

  1. Откройте редактор реестра.

  2. В разделе реестра HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall найдите и скопируйте код продукта GUID.

  3. Удалите агент с помощью Msiexec, как показано в следующих примерах:

    • В командной строке введите следующую команду:

      msiexec.exe /x {product code GUID} /qn
      
    • Вы можете выполнить те же действия с помощью 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}
      

Удаление устаревших ресурсов сервера

Если вы удаляете или отключаете сервер, не удаляя агент, ресурс обычно остается на портале Azure с состоянием Disconnected. Со временем эти устаревшие ресурсы могут загромождать среду.

Следующий сценарий PowerShell помогает определить и удалить серверы с поддержкой Azure Arc, которые были отключены в течение указанного количества дней.

Prerequisites

  • Azure PowerShell: установленный Az модуль.
  • Permissions: доступ читателя к запросу через Azure Resource Graph, а также доступ участника или владельца (или Microsoft.HybridCompute/machines/delete) для удаления ресурсов.

Скрипт очистки

Этот скрипт использует Azure Resource Graph для запроса Microsoft.HybridCompute/machines ресурсов, где состояние Disconnected и метка времени lastStatusChange более ранняя, чем заданное пороговое значение.

Сохраните следующий код как 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

Использование скрипта

Prerequisites

Для скрипта требуются следующие модули PowerShell:

  • Az.ResourceGraph
  • Az.Resources

Если они не установлены, выполните следующую команду:

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

Steps

  1. Вход в Azure

    Откройте терминал PowerShell и войдите.

    Connect-AzAccount
    
  2. Выполнение анализа What-If

    Сначала запустите скрипт с переключателем -WhatIf. На этом шаге перечислены серверы, соответствующие критериям, без фактического их удаления. Эта команда проверяет серверы, которые были отключены в течение 60 дней или более.

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

    Чтобы задать область запроса к определенной подписке, используйте -Subscription параметр:

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

    Чтобы применить запрос к группе управления, используйте -ManagementGroup параметр:

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

    Проверьте результат, чтобы убедиться, что он содержит только предполагаемые серверы.

  3. Выполните очистку

    Когда вы уверены в списке серверов для удаления, запустите скрипт без -WhatIf переключателя.

    .\Cleanup-StaleArcServers.ps1 -DaysDisconnected 60
    

    Чтобы очистить серверы, отключенные в течение более длительного периода (например, шесть месяцев), увеличьте число дней:

    .\Cleanup-StaleArcServers.ps1 -DaysDisconnected 180
    

    Скрипт запрашивает подтверждение перед каждым удалением. Чтобы пропустить запросы, добавьте -Confirm:$false.