Narzędzie do odnajdywania i usuwania MMA/OMS
Po przeprowadzeniu migracji maszyn do agenta usługi Azure Monitor (AMA) usuń starszego agenta usługi Log Analytics w zależności od systemów operacyjnych, aby uniknąć duplikowania dzienników. Starsze narzędzie odnajdywania i usuwania może usuwać rozszerzenia z maszyn wirtualnych platformy Azure, zestawów skalowania maszyn wirtualnych platformy Azure (VMSS) i serwerów usługi Azure Arc z jednej subskrypcji.
Narzędzie działa w dwóch krokach:
Odnajdywanie: narzędzie tworzy spis wszystkich maszyn, na których zainstalowano starszego agenta w prostym pliku CSV. Zalecamy, aby nie tworzyć żadnych nowych maszyn wirtualnych, gdy narzędzie jest uruchomione.
Usuwanie: narzędzie usuwa starszego agenta z maszyn wymienionych w pliku CSV. Należy edytować listę maszyn w pliku CSV, aby upewnić się, że istnieją tylko maszyny, z których agent ma zostać usunięty.
Uwaga
Usunięcie nie działa na agentach MMA zainstalowanych przy użyciu instalatora MSI. Działa tylko w przypadku rozszerzeń maszyn wirtualnych.
Wymagania wstępne
Wykonaj wszystkie kroki konfiguracji na komputerze połączonym z Internetem. Należy wykonać:
- Windows 10 lub nowszy albo Windows Server 2019 lub nowszy.
- Program PowerShell w wersji 7.0 lub nowszej umożliwia równoległe wykonywanie, które przyspiesza proces.
- Aby komunikować się z interfejsem API programu Azure Graph, należy zainstalować narzędzie Azcli.
- Otwórz program PowerShell jako administrator:
- Uruchom polecenie:
Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile AzureCLI.msi
. - Uruchom polecenie:
Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'
. - Najnowsza wersja interfejsu wiersza polecenia platformy Azure zostanie pobrana i zainstalowana.
Krok 1 Logowanie i ustawianie subskrypcji
Narzędzie działa pojedynczo w jednej subskrypcji. Musisz zalogować się i ustawić subskrypcję w celu usunięcia. Otwórz wiersz polecenia programu PowerShell jako administrator i zaloguj się.
az login
Następnie musisz ustawić subskrypcję.
Az account set --subscription {subscription_id or “subscription_name”}
Krok 2. Kopiowanie skryptu
Do usunięcia agenta należy użyć następującego skryptu. Otwórz plik w katalogu lokalnym o nazwie LogAnalyticsAgentUninstallUtilityScript.ps1 i skopiuj skrypt do pliku.
# 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 Pobieranie spisu
W ramach subskrypcji zbierasz listę wszystkich starszych agentów na wszystkich maszynach wirtualnych, zestawach skalowania maszyn wirtualnych i serwerze z obsługą usługi Arc. Skrypt został pobrany ze spisu starszych agentów w subskrypcji.
.\LogAnalyticsAgentUninstallUtilityScript.ps1 GetInventory
Skrypt zgłasza łączną liczbę maszyn wirtualnych, zestawów skalowania maszyn wirtualnych lub usługi Arc, co umożliwia korzystanie z serwerów widocznych w subskrypcji. Uruchomienie może potrwać kilka minut. W oknie konsoli zostanie wyświetlony pasek postępu. Po zakończeniu możesz zobaczyć plik CSV o nazwie "LogAnalyticsAgentExtensionInventory.csv w katalogu lokalnym z następującym formatem.
Resource_ID | Nazwisko | Resource_Group | Resource_Type | Install_Type | Extension_Name | AMA_Extension_Installed |
---|---|---|---|---|---|---|
012cb5cf-e1a8-49ee-a484-d40673167c9c | Linux-ama-e2e-debian9 | Linux-AMA-E2E | VM | Numer wewnętrzny | OmsAgentForLinux | Prawda |
8acae35a-454f-4869-bf4f-658189d98516 | test2012-r2-da | test2012-r2-daAMA-ADMIN | VM | Numer wewnętrzny | MicrosoftMonitorAgent | Fałsz |
Krok 4 Odinstalowuje spis
Ten skrypt iteruje listę maszyn wirtualnych, zestawów skalowania maszyn wirtualnych i serwerów z obsługą usługi Arc oraz odinstalowuje starszego agenta. Nie można usunąć agenta, jeśli nie jest uruchomiony.
.\LogAnalyticsAgentUninstallUtilityScript.ps1 UninstallExtension
Po zakończeniu skryptu będzie można zobaczyć stan usunięcia maszyny wirtualnej, zestawów skalowania maszyn wirtualnych i serwerów z obsługą usługi Arc w pliku "LogAnalyticsAgentExtensionInventory.csv.