Sdílet prostřednictvím


Nástroj pro zjišťování a odebrání MMA/OMS

Po migraci počítačů do agenta služby Azure Monitor (AMA) odeberte starší verzi agenta Log Analytics v závislosti na vašich operačních systémech, abyste se vyhnuli duplikaci protokolů. Starší verze nástroje zjišťování a odebrání může odebrat rozšíření z virtuálních počítačů Azure, škálovacích sad virtuálních počítačů Azure (VMSS) a serverů Azure Arc z jednoho předplatného.

Nástroj funguje ve dvou krocích:

  1. Zjišťování: Nástroj vytvoří inventář všech počítačů, které mají starší verzi agenta nainstalovaného v jednoduchém souboru CSV. Doporučujeme nevytvořit žádné nové virtuální počítače, když je nástroj spuštěný.

  2. Odebrání: Nástroj odebere starší verzi agenta z počítačů uvedených v souboru CSV. Měli byste upravit seznam počítačů v souboru CSV, abyste měli jistotu, že jsou k dispozici jenom počítače, ze kterého chcete agenta odebrat.

Poznámka:

Odebrání nefunguje u agentů MMA nainstalovaných pomocí instalačního programu MSI. Funguje jenom na rozšířeních virtuálních počítačů.

Požadavky

Proveďte všechny kroky nastavení na počítači připojeném k internetu. Potřebujete:

  • Windows 10 nebo novější nebo Windows Server 2019 nebo novější.
  • PowerShell 7.0 nebo novější, který umožňuje paralelní spouštění, které proces zrychluje.
  • Aby bylo možné komunikovat s rozhraním Azure Graph API, musí být nainstalovaný Azcli.
  1. Otevřete PowerShell jako správce:
  2. Spusťte příkaz: Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile AzureCLI.msi.
  3. Spusťte příkaz: Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'.
  4. Nejnovější verze Azure CLI se stáhne a nainstaluje.

Krok 1 : Přihlášení a nastavení předplatného

Nástroj funguje po jednom předplatném. Musíte se přihlásit a nastavit předplatné k odebrání. Otevřete příkazový řádek PowerShellu jako správce a přihlaste se.

az login

Dále musíte nastavit své předplatné.

Az account set --subscription {subscription_id or “subscription_name”}

Krok 2: Zkopírování skriptu

K odebrání agenta použijete následující skript. Otevřete soubor v místním adresáři s názvem LogAnalyticsAgentUninstallUtilityScript.ps1 a zkopírujte skript do souboru.

# This is per subscription, the customer has to set the az subscription before running this.
# az login
# az account set --subscription <subscription_id/subscription_name>
# This script uses parallel processing, modify the $parallelThrottleLimit parameter to either increase or decrease the number of parallel processes
# PS> .\LogAnalyticsAgentUninstallUtilityScript.ps1 GetInventory
# The above command will generate a csv file with the details of Vm's and Vmss and Arc servers that has log analyice Agent extension installed. 
# The customer can modify the the csv by adding/removing rows if needed
# Remove the log analytics agent by running the script again as shown below:
# PS> .\LogAnalyticsAgentUninstallUtilityScript.ps1 UninstallExtension

# This version of the script requires Powershell version >= 7 in order to improve performance via ForEach-Object -Parallel
# https://docs.microsoft.com/en-us/powershell/scripting/whats-new/migrating-from-windows-powershell-51-to-powershell-7?view=powershell-7.1
if ($PSVersionTable.PSVersion.Major -lt 7) 
{
 Write-Host "This script requires Powershell version 7 or newer to run. Please see https://docs.microsoft.com/en-us/powershell/scripting/whats-new/migrating-from-windows-powershell-51-to-powershell-7?view=powershell-7.1."
 exit 1
}

$parallelThrottleLimit = 16

function GetArcServersWithLogAnalyticsAgentExtensionInstalled {
 param (
     $fileName
 )
 
 $serverList = az connectedmachine list --query "[].{ResourceId:id, ResourceGroup:resourceGroup, ServerName:name}" | ConvertFrom-Json
 if(!$serverList)
 {
     Write-Host "Cannot get the Arc server list"
     return
 }

 $serversCount = $serverList.Length
 $vmParallelThrottleLimit = $parallelThrottleLimit
 if ($serversCount -lt $vmParallelThrottleLimit) 
 {
     $serverParallelThrottleLimit = $serversCount
 }

 $serverGroups = @()

 if($serversCount -eq 1)
 {
     $serverGroups += ,($serverList[0])
 }
 else
 {
     # split the list into batches to do parallel processing
     for ($i = 0; $i -lt $serversCount; $i += $vmParallelThrottleLimit) 
     { 
         $serverGroups += , ($serverList[$i..($i + $serverParallelThrottleLimit - 1)]) 
     }
 }

 Write-Host "Detected $serversCount Arc servers in this subscription."
 $hash = [hashtable]::Synchronized(@{})
 $hash.One = 1

 $serverGroups | Foreach-Object -ThrottleLimit $parallelThrottleLimit -Parallel {
     $len = $using:serversCount
     $hash = $using:hash
     $_ | ForEach-Object {
         $percent = 100 * $hash.One++ / $len
         Write-Progress -Activity "Getting Arc server extensions Inventory" -PercentComplete $percent
         $serverName = $_.ServerName
         $resourceGroup = $_.ResourceGroup
         $resourceId = $_.ResourceId
         Write-Debug "Getting extensions for Arc server: $serverName"
         $extensions = az connectedmachine extension list -g $resourceGroup --machine-name $serverName --query "[?contains(['MicrosoftMonitoringAgent', 'OmsAgentForLinux', 'AzureMonitorLinuxAgent', 'AzureMonitorWindowsAgent'], properties.type)].{type: properties.type, name: name}" | ConvertFrom-Json

         if (!$extensions) {
             return
         }
         $extensionMap = @{}
         foreach ($ext in $extensions) {
             $extensionMap[$ext.type] = $ext.name
         }
         $extensionName = ""
         if ($extensionMap.ContainsKey("MicrosoftMonitoringAgent")) {
             $extensionName = $extensionMap["MicrosoftMonitoringAgent"]
         }
         elseif ($extensionMap.ContainsKey("OmsAgentForLinux")) {
             $extensionName = $extensionMap["OmsAgentForLinux"]
         }
         if ($extensionName) {
             $amaExtensionInstalled = "False"
             if ($extensionMap.ContainsKey("AzureMonitorWindowsAgent") -or $extensionMap.ContainsKey("AzureMonitorLinuxAgent")) {
                 $amaExtensionInstalled = "True"
             }
             $csvObj = New-Object -TypeName PSObject -Property @{
                 'ResourceId'              = $resourceId
                 'Name'                    = $serverName
                 'Resource_Group'          = $resourceGroup
                 'Resource_Type'           = "ArcServer"
                 'Install_Type'            = "Extension"
                 'Extension_Name'          = $extensionName
                 'AMA_Extension_Installed' = $amaExtensionInstalled
             }
             $csvObj | Export-Csv $using:fileName -Append -Force | Out-Null
         }
         # az cli sometime cannot handle many requests at same time, so delaying next request by 2 milliseconds
         Start-Sleep -Milliseconds 2
     }
 }
}

function GetVmsWithLogAnalyticsAgentExtensionInstalled
{
 param(
     $fileName
 )
 
 $vmList = az vm list --query "[].{ResourceId:id, ResourceGroup:resourceGroup, VmName:name}" | ConvertFrom-Json
  
 if(!$vmList)
 {
     Write-Host "Cannot get the VM list"
     return
 }

 $vmsCount = $vmList.Length
 $vmParallelThrottleLimit = $parallelThrottleLimit
 if ($vmsCount -lt $vmParallelThrottleLimit) 
 {
     $vmParallelThrottleLimit = $vmsCount
 }

 if($vmsCount -eq 1)
 {
     $vmGroups += ,($vmList[0])
 }
 else
 {
     # split the vm's into batches to do parallel processing
     for ($i = 0; $i -lt $vmsCount; $i += $vmParallelThrottleLimit) 
     { 
         $vmGroups += , ($vmList[$i..($i + $vmParallelThrottleLimit - 1)]) 
     }
 }

 Write-Host "Detected $vmsCount Vm's in this subscription."
 $hash = [hashtable]::Synchronized(@{})
 $hash.One = 1

 $vmGroups | Foreach-Object -ThrottleLimit $parallelThrottleLimit -Parallel {
     $len = $using:vmsCount
     $hash = $using:hash
     $_ | ForEach-Object {
         $percent = 100 * $hash.One++ / $len
         Write-Progress -Activity "Getting VM extensions Inventory" -PercentComplete $percent
         $resourceId = $_.ResourceId
         $vmName = $_.VmName
         $resourceGroup = $_.ResourceGroup
         Write-Debug "Getting extensions for VM: $vmName"
         $extensions = az vm extension list -g $resourceGroup --vm-name $vmName --query "[?contains(['MicrosoftMonitoringAgent', 'OmsAgentForLinux', 'AzureMonitorLinuxAgent', 'AzureMonitorWindowsAgent'], typePropertiesType)].{type: typePropertiesType, name: name}" | ConvertFrom-Json
         
         if (!$extensions) {
             return
         }
         $extensionMap = @{}
         foreach ($ext in $extensions) {
             $extensionMap[$ext.type] = $ext.name
         }
         $extensionName = ""
         if ($extensionMap.ContainsKey("MicrosoftMonitoringAgent")) {
             $extensionName = $extensionMap["MicrosoftMonitoringAgent"]
         }
         elseif ($extensionMap.ContainsKey("OmsAgentForLinux")) {
             $extensionName = $extensionMap["OmsAgentForLinux"]
         }
         if ($extensionName) {
             $amaExtensionInstalled = "False"
             if ($extensionMap.ContainsKey("AzureMonitorWindowsAgent") -or $extensionMap.ContainsKey("AzureMonitorLinuxAgent")) {
                 $amaExtensionInstalled = "True"
             }
             $csvObj = New-Object -TypeName PSObject -Property @{
                 'ResourceId'              = $resourceId
                 'Name'                    = $vmName
                 'Resource_Group'          = $resourceGroup
                 'Resource_Type'           = "VM"
                 'Install_Type'            = "Extension"
                 'Extension_Name'          = $extensionName
                 'AMA_Extension_Installed' = $amaExtensionInstalled
             }
             $csvObj | Export-Csv $using:fileName -Append -Force | Out-Null
         }
         # az cli sometime cannot handle many requests at same time, so delaying next request by 2 milliseconds
         Start-Sleep -Milliseconds 2
     }
 }
}

function GetVmssWithLogAnalyticsAgentExtensionInstalled
{
 param(
     $fileName
 )

 # get the vmss list which are successfully provisioned
 $vmssList = az vmss list --query "[?provisioningState=='Succeeded'].{ResourceId:id, ResourceGroup:resourceGroup, VmssName:name}" | ConvertFrom-Json   

 $vmssCount = $vmssList.Length
 Write-Host "Detected $vmssCount Vmss in this subscription."
 $hash = [hashtable]::Synchronized(@{})
 $hash.One = 1

 $vmssList | Foreach-Object -ThrottleLimit $parallelThrottleLimit -Parallel {
     $len = $using:vmssCount
     $hash = $using:hash
     $percent = 100 * $hash.One++ / $len
     Write-Progress -Activity "Getting VMSS extensions Inventory" -PercentComplete $percent
     $resourceId = $_.ResourceId
     $vmssName = $_.VmssName
     $resourceGroup = $_.ResourceGroup
     Write-Debug "Getting extensions for VMSS: $vmssName"
     $extensions = az vmss extension list -g $resourceGroup --vmss-name $vmssName --query "[?contains(['MicrosoftMonitoringAgent', 'OmsAgentForLinux', 'AzureMonitorLinuxAgent', 'AzureMonitorWindowsAgent'], typePropertiesType)].{type: typePropertiesType, name: name}" | ConvertFrom-Json
     
     if (!$extensions) {
         return
     }
     $extensionMap = @{}
     foreach ($ext in $extensions) {
         $extensionMap[$ext.type] = $ext.name
     }
     $extensionName = ""
     if ($extensionMap.ContainsKey("MicrosoftMonitoringAgent")) {
         $extensionName = $extensionMap["MicrosoftMonitoringAgent"]
     }
     elseif ($extensionMap.ContainsKey("OmsAgentForLinux")) {
         $extensionName = $extensionMap["OmsAgentForLinux"]
     }
     if ($extensionName) {
         $amaExtensionInstalled = "False"
         if ($extensionMap.ContainsKey("AzureMonitorWindowsAgent") -or $extensionMap.ContainsKey("AzureMonitorLinuxAgent")) {
             $amaExtensionInstalled = "True"
         }
         $csvObj = New-Object -TypeName PSObject -Property @{
             'ResourceId'              = $resourceId
             'Name'                    = $vmssName
             'Resource_Group'          = $resourceGroup
             'Resource_Type'           = "VMSS"
             'Install_Type'            = "Extension"
             'Extension_Name'          = $extensionName
             'AMA_Extension_Installed' = $amaExtensionInstalled
         }
         $csvObj | Export-Csv $using:fileName -Append -Force | Out-Null
     }
     # az cli sometime cannot handle many requests at same time, so delaying next request by 2 milliseconds
     Start-Sleep -Milliseconds 2
 }
}

function GetInventory
{
 param(
     $fileName = "LogAnalyticsAgentExtensionInventory.csv"
 )

 # create a new file 
 New-Item -Name $fileName -ItemType File -Force

 Start-Transcript -Path $logFileName -Append
 GetVmsWithLogAnalyticsAgentExtensionInstalled $fileName
 GetVmssWithLogAnalyticsAgentExtensionInstalled $fileName
 GetArcServersWithLogAnalyticsAgentExtensionInstalled $fileName
 Stop-Transcript
}

function UninstallExtension
{
 param(
     $fileName = "LogAnalyticsAgentExtensionInventory.csv"
 )
 Start-Transcript -Path $logFileName -Append
 Import-Csv $fileName | ForEach-Object -ThrottleLimit $parallelThrottleLimit -Parallel {
     if ($_.Install_Type -eq "Extension") 
     {
         $extensionName = $_.Extension_Name
         $resourceName = $_.Name
         Write-Debug "Uninstalling extension: $extensionName from $resourceName"
         if ($_.Resource_Type -eq "VMSS") 
         {
             # if the extension is installed with a custom name, provide the name using the flag: --extension-instance-name <extension name>
             az vmss extension delete --name $extensionName --vmss-name $resourceName --resource-group $_.Resource_Group --output none --no-wait
         }
         elseif($_.Resource_Type -eq "VM")
         {
             # if the extension is installed with a custom name, provide the name using the flag: --extension-instance-name <extension name>
             az vm extension delete --name $extensionName --vm-name $resourceName --resource-group $_.Resource_Group --output none --no-wait
         }
         elseif($_.Resource_Type -eq "ArcServer")
         {
             az connectedmachine extension delete --name $extensionName --machine-name $resourceName --resource-group $_.Resource_Group --no-wait --output none --yes -y
         }
         # az cli sometime cannot handle many requests at same time, so delaying next delete request by 2 milliseconds
         Start-Sleep -Milliseconds 2
     }
 }
 Stop-Transcript
}

$logFileName = "LogAnalyticsAgentUninstallUtilityScriptLog.log"

switch ($args.Count)
{
 0 {
     Write-Host "The arguments provided are incorrect."
     Write-Host "To get the Inventory: Run the script as: PS> .\LogAnalyticsAgentUninstallUtilityScript.ps1 GetInventory"
     Write-Host "To uninstall Log Analytics Agent from Inventory: Run the script as: PS> .\LogAnalyticsAgentUninstallUtilityScript.ps1 UninstallExtension"
 }
 1 {
     if (-Not (Test-Path $logFileName)) {
         New-Item -Path $logFileName -ItemType File
     }
     $funcname = $args[0]
     Invoke-Expression "& $funcname"
 }
 2 {
     if (-Not (Test-Path $logFileName)) {
         New-Item -Path $logFileName -ItemType File
     }
     $funcname = $args[0]
     $funcargs = $args[1]
     Invoke-Expression "& $funcname $funcargs"
 }
}

Krok 3 Získá inventář

Shromáždíte seznam všech starších agentů na všech virtuálních počítačích, VMSS a serveru s podporou Arc v předplatném. Ve svém předplatném spustíte skript, který jste stáhli do inventáře starších agentů.

.\LogAnalyticsAgentUninstallUtilityScript.ps1 GetInventory

Skript hlásí celkový počet virtuálních počítačů, VMSS nebo Arc, které umožňují servery v předplatném. Spuštění trvá několik minut. V okně konzoly se zobrazí indikátor průběhu. Po dokončení uvidíte soubor CSV s názvem "LogAnalyticsAgentExtensionInventory.csv v místním adresáři s následujícím formátem.

Resource_ID Název Resource_Group Resource_Type Install_Type Extension_Name AMA_Extension_Installed
012cb5cf-e1a8-49ee-a484-d40673167c9c Linux-ama-e2e-debian9 Linux-AMA-E2E Virtuální počítač Rozšíření OmsAgentForLinux True
8acae35a-454f-4869-bf4f-658189d98516 test2012-r2-da test2012-r2-daAMA-ADMIN Virtuální počítač Rozšíření MicrosoftMonitorAgent False

Krok 4 Odinstaluje inventář

Tento skript prochází seznamem virtuálních počítačů, škálovacích sad virtuálních počítačů a serverů s podporou arc a odinstaluje starší verzi agenta. Agenta nemůžete odebrat, pokud není spuštěný.

.\LogAnalyticsAgentUninstallUtilityScript.ps1 UninstallExtension

Po dokončení skriptu uvidíte stav odebrání pro váš virtuální počítač, škálovací sady virtuálních počítačů a servery s podporou arc v souboru LogAnalyticsAgentExtensionInventory.csv.