@@ -50,11 +50,11 @@ You'll use the following script for agent removal. Open a file in your local dir
50
50
# az login
51
51
# az account set --subscription <subscription_id/subscription_name>
52
52
# This script uses parallel processing, modify the $parallelThrottleLimit parameter to either increase or decrease the number of parallel processes
53
- # PS> .\MMAUnistallUtilityScript .ps1 GetInventory
54
- # The above command will generate a csv file with the details of Vm's and Vmss that has MMA extension installed.
53
+ # PS> .\LogAnalyticsAgentUninstallUtilityScript .ps1 GetInventory
54
+ # The above command will generate a csv file with the details of Vm's and Vmss and Arc servers that has MMA/OMS extension installed.
55
55
# The customer can modify the the csv by adding/removing rows if needed
56
- # Remove the MMA by running the script again as shown below:
57
- # PS> .\MMAUnistallUtilityScript .ps1 UninstallMMAExtension
56
+ # Remove the MMA/OMS by running the script again as shown below:
57
+ # PS> .\LogAnalyticsAgentUninstallUtilityScript .ps1 UninstallExtension
58
58
59
59
# This version of the script requires Powershell version >= 7 in order to improve performance via ForEach-Object -Parallel
60
60
# https://docs.microsoft.com/en-us/powershell/scripting/whats-new/migrating-from-windows-powershell-51-to-powershell-7?view=powershell-7.1
@@ -66,13 +66,96 @@ if ($PSVersionTable.PSVersion.Major -lt 7)
66
66
67
67
$parallelThrottleLimit = 16
68
68
69
- function GetVmsWithMMAExtensionInstalled
69
+ function GetArcServersWithLogAnalyticsAgentExtensionInstalled {
70
+ param (
71
+ $fileName
72
+ )
73
+
74
+ $serverList = az connectedmachine list --query "[].{ResourceId:id, ResourceGroup:resourceGroup, ServerName:name}" | ConvertFrom-Json
75
+ if(!$serverList)
76
+ {
77
+ Write-Host "Cannot get the Arc server list"
78
+ return
79
+ }
80
+
81
+ $serversCount = $serverList.Length
82
+ $vmParallelThrottleLimit = $parallelThrottleLimit
83
+ if ($serversCount -lt $vmParallelThrottleLimit)
84
+ {
85
+ $serverParallelThrottleLimit = $serversCount
86
+ }
87
+
88
+ if($serversCount -eq 1)
89
+ {
90
+ $serverGroups += ,($serverList[0])
91
+ }
92
+ else
93
+ {
94
+ # split the list into batches to do parallel processing
95
+ for ($i = 0; $i -lt $serversCount; $i += $vmParallelThrottleLimit)
96
+ {
97
+ $serverGroups += , ($serverList[$i..($i + $serverParallelThrottleLimit - 1)])
98
+ }
99
+ }
100
+
101
+ Write-Host "Detected $serversCount Arc servers in this subscription."
102
+ $hash = [hashtable]::Synchronized(@{})
103
+ $hash.One = 1
104
+
105
+ $serverGroups | Foreach-Object -ThrottleLimit $parallelThrottleLimit -Parallel {
106
+ $len = $using:serversCount
107
+ $hash = $using:hash
108
+ $_ | ForEach-Object {
109
+ $percent = 100 * $hash.One++ / $len
110
+ Write-Progress -Activity "Getting Arc server extensions Inventory" -PercentComplete $percent
111
+ $serverName = $_.ServerName
112
+ $resourceGroup = $_.ResourceGroup
113
+ $resourceId = $_.ResourceId
114
+ Write-Debug "Getting extensions for Arc server: $serverName"
115
+ $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
116
+
117
+ if (!$extensions) {
118
+ return
119
+ }
120
+ $extensionMap = @{}
121
+ foreach ($ext in $extensions) {
122
+ $extensionMap[$ext.type] = $ext.name
123
+ }
124
+ if ($extensionMap.ContainsKey("MicrosoftMonitoringAgent")) {
125
+ $extensionName = $extensionMap["MicrosoftMonitoringAgent"]
126
+ }
127
+ elseif ($extensionMap.ContainsKey("OmsAgentForLinux")) {
128
+ $extensionName = $extensionMap["OmsAgentForLinux"]
129
+ }
130
+ if ($extensionName) {
131
+ $amaExtensionInstalled = "False"
132
+ if ($extensionMap.ContainsKey("AzureMonitorWindowsAgent") -or $extensionMap.ContainsKey("AzureMonitorLinuxAgent")) {
133
+ $amaExtensionInstalled = "True"
134
+ }
135
+ $csvObj = New-Object -TypeName PSObject -Property @{
136
+ 'ResourceId' = $resourceId
137
+ 'Name' = $serverName
138
+ 'Resource_Group' = $resourceGroup
139
+ 'Resource_Type' = "ArcServer"
140
+ 'Install_Type' = "Extension"
141
+ 'Extension_Name' = $extensionName
142
+ 'AMA_Extension_Installed' = $amaExtensionInstalled
143
+ }
144
+ $csvObj | Export-Csv $using:fileName -Append -Force | Out-Null
145
+ }
146
+ # az cli sometime cannot handle many requests at same time, so delaying next request by 2 milliseconds
147
+ Start-Sleep -Milliseconds 2
148
+ }
149
+ }
150
+ }
151
+
152
+ function GetVmsWithLogAnalyticsAgentExtensionInstalled
70
153
{
71
154
param(
72
155
$fileName
73
156
)
74
157
75
- $vmList = az vm list --query "[].{ResourceGroup:resourceGroup, VmName:name}" | ConvertFrom-Json
158
+ $vmList = az vm list --query "[].{ResourceId:id, ResourceGroup:resourceGroup, VmName:name}" | ConvertFrom-Json
76
159
77
160
if(!$vmList)
78
161
{
@@ -81,7 +164,6 @@ function GetVmsWithMMAExtensionInstalled
81
164
}
82
165
83
166
$vmsCount = $vmList.Length
84
-
85
167
$vmParallelThrottleLimit = $parallelThrottleLimit
86
168
if ($vmsCount -lt $vmParallelThrottleLimit)
87
169
{
@@ -101,7 +183,7 @@ function GetVmsWithMMAExtensionInstalled
101
183
}
102
184
}
103
185
104
- Write-Host "Detected $vmsCount Vm's running in this subscription."
186
+ Write-Host "Detected $vmsCount Vm's in this subscription."
105
187
$hash = [hashtable]::Synchronized(@{})
106
188
$hash.One = 1
107
189
@@ -110,109 +192,164 @@ function GetVmsWithMMAExtensionInstalled
110
192
$hash = $using:hash
111
193
$_ | ForEach-Object {
112
194
$percent = 100 * $hash.One++ / $len
113
- Write-Progress -Activity "Getting VM Inventory" -PercentComplete $percent
195
+ Write-Progress -Activity "Getting VM extensions Inventory" -PercentComplete $percent
196
+ $resourceId = $_.ResourceId
114
197
$vmName = $_.VmName
115
198
$resourceGroup = $_.ResourceGroup
116
- $extensionName = az vm extension list -g $resourceGroup --vm-name $vmName --query "[?name == 'MicrosoftMonitoringAgent' || name == 'OmsAgentForLinux'].name" | ConvertFrom-Json
117
- if ($extensionName)
118
- {
199
+ Write-Debug "Getting extensions for VM: $vmName"
200
+ $extensions = az vm extension list -g $resourceGroup --vm-name $vmName --query "[?contains(['MicrosoftMonitoringAgent', 'OmsAgentForLinux', 'AzureMonitorLinuxAgent', 'AzureMonitorWindowsAgent'], typePropertiesType)].{type: typePropertiesType, name: name}" | ConvertFrom-Json
201
+
202
+ if (!$extensions) {
203
+ return
204
+ }
205
+ $extensionMap = @{}
206
+ foreach ($ext in $extensions) {
207
+ $extensionMap[$ext.type] = $ext.name
208
+ }
209
+ if ($extensionMap.ContainsKey("MicrosoftMonitoringAgent")) {
210
+ $extensionName = $extensionMap["MicrosoftMonitoringAgent"]
211
+ }
212
+ elseif ($extensionMap.ContainsKey("OmsAgentForLinux")) {
213
+ $extensionName = $extensionMap["OmsAgentForLinux"]
214
+ }
215
+ if ($extensionName) {
216
+ $amaExtensionInstalled = "False"
217
+ if ($extensionMap.ContainsKey("AzureMonitorWindowsAgent") -or $extensionMap.ContainsKey("AzureMonitorLinuxAgent")) {
218
+ $amaExtensionInstalled = "True"
219
+ }
119
220
$csvObj = New-Object -TypeName PSObject -Property @{
120
- 'Name' = $vmName
121
- 'Resource_Group' = $resourceGroup
122
- 'Resource_Type' = "VM"
123
- 'Install_Type' = "Extension"
124
- 'Extension_Name' = $extensionName
221
+ 'ResourceId' = $resourceId
222
+ 'Name' = $vmName
223
+ 'Resource_Group' = $resourceGroup
224
+ 'Resource_Type' = "VM"
225
+ 'Install_Type' = "Extension"
226
+ 'Extension_Name' = $extensionName
227
+ 'AMA_Extension_Installed' = $amaExtensionInstalled
125
228
}
126
229
$csvObj | Export-Csv $using:fileName -Append -Force | Out-Null
127
230
}
231
+ # az cli sometime cannot handle many requests at same time, so delaying next request by 2 milliseconds
232
+ Start-Sleep -Milliseconds 2
128
233
}
129
234
}
130
235
}
131
236
132
- function GetVmssWithMMAExtensionInstalled
237
+ function GetVmssWithLogAnalyticsAgentExtensionInstalled
133
238
{
134
239
param(
135
240
$fileName
136
241
)
137
242
138
243
# get the vmss list which are successfully provisioned
139
- $vmssList = az vmss list --query "[?provisioningState=='Succeeded'].{ResourceGroup:resourceGroup, VmssName:name}" | ConvertFrom-Json
244
+ $vmssList = az vmss list --query "[?provisioningState=='Succeeded'].{ResourceId:id, ResourceGroup:resourceGroup, VmssName:name}" | ConvertFrom-Json
140
245
141
246
$vmssCount = $vmssList.Length
142
- Write-Host "Detected $vmssCount Vmss running in this subscription."
247
+ Write-Host "Detected $vmssCount Vmss in this subscription."
143
248
$hash = [hashtable]::Synchronized(@{})
144
249
$hash.One = 1
145
250
146
251
$vmssList | Foreach-Object -ThrottleLimit $parallelThrottleLimit -Parallel {
147
252
$len = $using:vmssCount
148
253
$hash = $using:hash
149
254
$percent = 100 * $hash.One++ / $len
150
- Write-Progress -Activity "Getting VMSS Inventory" -PercentComplete $percent
255
+ Write-Progress -Activity "Getting VMSS extensions Inventory" -PercentComplete $percent
256
+ $resourceId = $_.ResourceId
151
257
$vmssName = $_.VmssName
152
258
$resourceGroup = $_.ResourceGroup
153
-
154
- $extensionName = az vmss extension list -g $resourceGroup --vmss-name $vmssName --query "[?name == 'MicrosoftMonitoringAgent' || name == 'OmsAgentForLinux'].name" | ConvertFrom-Json
155
- if ($extensionName)
156
- {
259
+ Write-Debug "Getting extensions for VMSS: $vmssName"
260
+ $extensions = az vmss extension list -g $resourceGroup --vmss-name $vmssName --query "[?contains(['MicrosoftMonitoringAgent', 'OmsAgentForLinux', 'AzureMonitorLinuxAgent', 'AzureMonitorWindowsAgent'], typePropertiesType)].{type: typePropertiesType, name: name}" | ConvertFrom-Json
261
+
262
+ if (!$extensions) {
263
+ return
264
+ }
265
+ $extensionMap = @{}
266
+ foreach ($ext in $extensions) {
267
+ $extensionMap[$ext.type] = $ext.name
268
+ }
269
+ if ($extensionMap.ContainsKey("MicrosoftMonitoringAgent")) {
270
+ $extensionName = $extensionMap["MicrosoftMonitoringAgent"]
271
+ }
272
+ elseif ($extensionMap.ContainsKey("OmsAgentForLinux")) {
273
+ $extensionName = $extensionMap["OmsAgentForLinux"]
274
+ }
275
+ if ($extensionName) {
276
+ $amaExtensionInstalled = "False"
277
+ if ($extensionMap.ContainsKey("AzureMonitorWindowsAgent") -or $extensionMap.ContainsKey("AzureMonitorLinuxAgent")) {
278
+ $amaExtensionInstalled = "True"
279
+ }
157
280
$csvObj = New-Object -TypeName PSObject -Property @{
158
- 'Name' = $vmssName
159
- 'Resource_Group' = $resourceGroup
160
- 'Resource_Type' = "VMSS"
161
- 'Install_Type' = "Extension"
162
- 'Extension_Name' = $extensionName
281
+ 'ResourceId' = $resourceId
282
+ 'Name' = $vmssName
283
+ 'Resource_Group' = $resourceGroup
284
+ 'Resource_Type' = "VMSS"
285
+ 'Install_Type' = "Extension"
286
+ 'Extension_Name' = $extensionName
287
+ 'AMA_Extension_Installed' = $amaExtensionInstalled
163
288
}
164
289
$csvObj | Export-Csv $using:fileName -Append -Force | Out-Null
165
- }
290
+ }
291
+ # az cli sometime cannot handle many requests at same time, so delaying next request by 2 milliseconds
292
+ Start-Sleep -Milliseconds 2
166
293
}
167
294
}
168
295
169
296
function GetInventory
170
297
{
171
298
param(
172
- $fileName = "MMAInventory .csv"
299
+ $fileName = "LogAnalyticsAgentExtensionInventory .csv"
173
300
)
174
301
175
302
# create a new file
176
303
New-Item -Name $fileName -ItemType File -Force
177
304
178
305
Start-Transcript -Path $logFileName -Append
179
- GetVmsWithMMAExtensionInstalled $fileName
180
- GetVmssWithMMAExtensionInstalled $fileName
306
+ GetVmsWithLogAnalyticsAgentExtensionInstalled $fileName
307
+ GetVmssWithLogAnalyticsAgentExtensionInstalled $fileName
308
+ GetArcServersWithLogAnalyticsAgentExtensionInstalled $fileName
181
309
Stop-Transcript
182
310
}
183
311
184
- function UninstallMMAExtension
312
+ function UninstallExtension
185
313
{
186
314
param(
187
- $fileName = "MMAInventory .csv"
315
+ $fileName = "LogAnalyticsAgentExtensionInventory .csv"
188
316
)
189
317
Start-Transcript -Path $logFileName -Append
190
318
Import-Csv $fileName | ForEach-Object -ThrottleLimit $parallelThrottleLimit -Parallel {
191
319
if ($_.Install_Type -eq "Extension")
192
320
{
321
+ $extensionName = $_.Extension_Name
322
+ $resourceName = $_.Name
323
+ Write-Debug "Uninstalling extension: $extensionName from $resourceName"
193
324
if ($_.Resource_Type -eq "VMSS")
194
325
{
195
326
# if the extension is installed with a custom name, provide the name using the flag: --extension-instance-name <extension name>
196
- az vmss extension delete --name $_.Extension_Name --vmss-name $_.Name --resource-group $_.Resource_Group --output none --no-wait
327
+ az vmss extension delete --name $extensionName --vmss-name $resourceName --resource-group $_.Resource_Group --output none --no-wait
197
328
}
198
- else
329
+ elseif($_.Resource_Type -eq "VM")
199
330
{
200
331
# if the extension is installed with a custom name, provide the name using the flag: --extension-instance-name <extension name>
201
- az vm extension delete --name $_.Extension_Name --vm-name $_.Name --resource-group $_.Resource_Group --output none --no-wait
332
+ az vm extension delete --name $extensionName --vm-name $resourceName --resource-group $_.Resource_Group --output none --no-wait
333
+ }
334
+ elseif($_.Resource_Type -eq "ArcServer")
335
+ {
336
+ az connectedmachine extension delete --name $extensionName --machine-name $resourceName --resource-group $_.Resource_Group --no-wait --output none --yes -y
202
337
}
338
+ # az cli sometime cannot handle many requests at same time, so delaying next delete request by 2 milliseconds
339
+ Start-Sleep -Milliseconds 2
203
340
}
204
341
}
205
342
Stop-Transcript
206
343
}
207
344
208
- $logFileName = "MMAUninstallUtilityScriptLog .log"
345
+ $logFileName = "LogAnalyticsAgentUninstallUtilityScriptLog .log"
209
346
210
347
switch ($args.Count)
211
348
{
212
349
0 {
213
350
Write-Host "The arguments provided are incorrect."
214
- Write-Host "To get the Inventory: Run the script as: PS> .\MMAUnistallUtilityScript .ps1 GetInventory"
215
- Write-Host "To uninstall MMA from Inventory: Run the script as: PS> .\MMAUnistallUtilityScript .ps1 UninstallMMAExtension "
351
+ Write-Host "To get the Inventory: Run the script as: PS> .\LogAnalyticsAgentUninstallUtilityScript .ps1 GetInventory"
352
+ Write-Host "To uninstall MMA/OMS from Inventory: Run the script as: PS> .\LogAnalyticsAgentUninstallUtilityScript .ps1 UninstallExtension "
216
353
}
217
354
1 {
218
355
if (-Not (Test-Path $logFileName)) {
@@ -240,10 +377,10 @@ You'll collect a list of all legacy agents, both MMA and OMS, on all VM, VMSSs
240
377
```
241
378
The script reports the total VM, VMSSs, or Arc enables servers seen in the subscription. It takes several minutes to run. You see a progress bar in the console window. Once complete, you are able to see a CSV file called MMAInventory.csv in the local directory with the following format.
242
379
243
- | Resource_Group | Resource_Type | Name | Install_Type | Extension_Name |
244
- | ---| ---| ---| ---| ---|
245
- | Linux-AMA-E2E | VM | Linux-ama-e2e-debian9 | Extension | OmsAgentForLinux |
246
- | AMA-ADMIN | VM | test2012-r2-da | Extension | MicrosoftMonitorAgent |
380
+ | Resource_ID | Name | Resource_Group | Resource_Type | Install_Type | Extension_Name | AMA_Extension_Installed |
381
+ | ---| ---| ---| ---| ---| --- | --- |
382
+ | 012cb5cf-e1a8-49ee-a484-d40673167c9c | Linux-ama-e2e-debian9 | Linux-AMA-E2E | VM | Extension | OmsAgentForLinux | True |
383
+ | 8acae35a-454f-4869-bf4f-658189d98516 | test2012-r2-da | test2012-r2-daAMA-ADMIN | VM | Extension | MicrosoftMonitorAgent | False |
247
384
248
385
## Step 4 Uninstall inventory
249
386
This script iterates through the list of VM, Virtual Machine Scale Sets, and Arc enabled servers and uninstalls the legacy agent. If the VM, Virtual Machine Scale Sets, or Arc enabled server is not running you won't be able to remove the agent.
0 commit comments