@@ -4,7 +4,7 @@ description: This article explains the steps to cleanly remove your VMware vCent
4
4
author : snehithm
5
5
ms.author : snmuvva
6
6
ms.topic : how-to
7
- ms.date : 11/06 /2023
7
+ ms.date : 11/30 /2023
8
8
ms.service : azure-arc
9
9
ms.subservice : azure-arc-vmware-vsphere
10
10
ms.custom : devx-track-azurecli
@@ -95,246 +95,8 @@ You can remove your VMware vSphere resources from Azure Arc using either the deb
95
95
96
96
# ## Remove VMware vSphere resources from Azure Arc using deboarding script
97
97
98
- Use the deboarding script to do a full cleanup of all the Arc-enabled VMware resources. The script removes all the Azure resources, including vCenter, custom location, virtual machines, virtual templates, hosts, clusters, resource pools, datastores, virtual networks, Azure Resource Manager (ARM) resource of Appliance, and the appliance VM running on vCenter.
98
+ Download the [ deboarding script](https://aka.ms/arcvmwaredeboard) to do a full cleanup of all the Arc-enabled VMware resources. The script removes all the Azure resources, including vCenter, custom location, virtual machines, virtual templates, hosts, clusters, resource pools, datastores, virtual networks, Azure Resource Manager (ARM) resource of Appliance, and the appliance VM running on vCenter.
99
99
100
- ` ` ` powershell
101
- [CmdletBinding()]
102
- Param(
103
- [string] $vCenterId ,
104
- [string] $AVSId ,
105
- [string] $ApplianceConfigFilePath ,
106
- [switch] $Force
107
- )
108
-
109
- $DeleteFailedThreshold = 20
110
- $AVS_API_Version = " 2022-05-01"
111
-
112
- $logFile = Join-Path $PSScriptRoot " arcvmware-deboard.log"
113
-
114
- function logText($msg) {
115
- $msgFull = " $( Get-Date -UFormat ' %T' ) $msg "
116
- Write-Host $msgFull
117
- Write-Output $msgFull >> $logFile
118
- }
119
-
120
- function fail($msg) {
121
- $msgFull = @"
122
- $( Get-Date -UFormat ' %T' ) Script execution failed with error: $msg
123
- $( Get-Date -UFormat ' %T' ) Debug logs have been dumped to $logFile
124
- $( Get-Date -UFormat ' %T' ) The script will terminate shortly
125
- " @
126
- Write-Host -ForegroundColor Red $msgFull >> $logFile
127
- Write-Output $msgFull >> $logFile
128
- Start-Sleep -Seconds 5
129
- exit 1
130
- }
131
-
132
- if (! ($PSBoundParameters .ContainsKey(' vCenterId' ) -xor $PSBoundParameters .ContainsKey(' AVSId' ))) {
133
- fail " Please specify either vCenterId or AVSId, not both."
134
- }
135
-
136
-
137
- logText " Writing debug logs to $logFile "
138
-
139
- logText " Installing az cli extensions for Arc"
140
- az extension add --upgrade --name arcappliance
141
- az extension add --upgrade --name k8s-extension
142
- az extension add --upgrade --name customlocation
143
- $vmware_ext_ver = az version --query ' extensions.connectedvmware' -o tsv 2>> $logFile
144
- if ($vmware_ext_ver -and [System.Version]$vmware_ext_ver -gt [System.Version]" 0.1.12" ) {
145
- logText " Removing the connectedvmware extension and pinning it to 0.1.12"
146
- az extension remove --name connectedvmware --debug 2>> $logFile
147
- }
148
- az extension add --upgrade --name connectedvmware --version 0.1.12
149
- az extension add --upgrade --name resource-graph
150
-
151
- logText " Fetching some information related to the vCenter..."
152
- if ($PSBoundParameters .ContainsKey(' AVSId' )) {
153
- $vCenterId = az rest --method get --url " $AVSId /addons/arc?api-version=$AVS_API_Version " --query " properties.vCenter" -o tsv --debug 2>> $logFile
154
- if ($null -eq $vCenterId ) {
155
- fail " Unable to find vCenter ID for AVS $AVSId "
156
- }
157
- logText " vCenterId is $vCenterId "
158
- }
159
- else {
160
- $exists = az connectedvmware vcenter show --ids $vCenterId --debug 2>> $logFile
161
- if ($null -eq $exists ) {
162
- fail " Unable to find vCenter ID $vCenterId "
163
- }
164
- }
165
-
166
- $customLocationID = az resource show --ids $vCenterId --query extendedLocation.name -o tsv --debug 2>> $logFile
167
- $customLocation = az resource show --ids $customLocationID --debug 2>> $logFile | ConvertFrom-Json
168
-
169
- if ($null -ne $customLocation ) {
170
- $clusterExtensionIds = $customLocation .properties.clusterExtensionIds
171
- $applianceId = $customLocation .properties.hostResourceId
172
- }
173
-
174
- $otherCustomLocationsInAppliance = $( az graph query -q @"
175
- Resources
176
- | where type =~ 'Microsoft.ExtendedLocation/customLocations'
177
- | where id !~ '$customLocationID '
178
- | where properties.hostResourceId =~ '$applianceId '
179
- | project id
180
- " @.Replace(" ` r` n" , " " ).Replace(" ` n" , " " ) --debug 2>> $logFile | ConvertFrom-Json).data.id
181
-
182
- $resourceTypes = [PSCustomObject]@(
183
- @{ Type = " Microsoft.ConnectedVMwareVsphere/VirtualMachines" ; InventoryType = " VirtualMachine" ; AzSubCommand = " vm" ; AzArgs = @(" --retain" ) },
184
- @{ Type = " Microsoft.ConnectedVMwareVsphere/VirtualMachineTemplates" ; InventoryType = " VirtualMachineTemplate" ; AzSubCommand = " vm-template" },
185
- @{ Type = " Microsoft.ConnectedVMwareVsphere/Hosts" ; InventoryType = " Host" ; AzSubCommand = " host" },
186
- @{ Type = " Microsoft.ConnectedVMwareVsphere/Clusters" ; InventoryType = " Cluster" ; AzSubCommand = " cluster" },
187
- @{ Type = " Microsoft.ConnectedVMwareVsphere/ResourcePools" ; InventoryType = " ResourcePool" ; AzSubCommand = " resource-pool" },
188
- @{ Type = " Microsoft.ConnectedVMwareVsphere/Datastores" ; InventoryType = " Datastore" ; AzSubCommand = " datastore" },
189
- @{ Type = " Microsoft.ConnectedVMwareVsphere/VirtualNetworks" ; InventoryType = " VirtualNetwork" ; AzSubCommand = " virtual-network" }
190
- )
191
-
192
- foreach ($resourceType in $resourceTypes ) {
193
- $resourceIds = @()
194
- $skipToken = $null
195
- $query = @"
196
- (
197
- Resources
198
- | where type =~ ' $($resourceType.Type)'
199
- | where properties.vCenterId =~ ' $vCenterId'
200
- | project id=tolower(id)
201
- | union (
202
- ConnectedVMwareVsphereResources
203
- | where type =~ ' Microsoft.ConnectedVMwareVsphere/VCenters/InventoryItems' and kind =~ ' $($resourceType.InventoryType)'
204
- | where id startswith ' $vCenterId/InventoryItems'
205
- | where properties.managedResourceId ! = ' '
206
- | extend id=tolower(tostring(properties.managedResourceId))
207
- | project id
208
- )
209
- ) | distinct id
210
- " @.Replace(" ` r` n" , " " ).Replace(" ` n" , " " )
211
- logText " Searching $( $resourceType .Type) ..."
212
- $deleteFailed = @ ()
213
- while ($true ) {
214
- if ($skipToken ) {
215
- $page = az graph query --skip-token $skipToken -q $query --debug 2>> $logFile | ConvertFrom-Json
216
- }
217
- else {
218
- $page = az graph query -q $query --debug 2>> $logFile | ConvertFrom-Json
219
- }
220
- $page .data | ForEach-Object {
221
- $resourceIds += $_ .id
222
- }
223
- if ($null -eq $page .skip_token) {
224
- break
225
- }
226
- $skipToken = $page .skip_token
227
- }
228
- logText " Found $( $resourceIds .Count) $( $resourceType .Type) "
229
-
230
- $azArgs = $resourceType .AzArgs
231
- if ($Force ) {
232
- $azArgs = @ (" --force" )
233
- }
234
- $width = $resourceIds.Count.ToString ().Length
235
- for ($i = 0; $i -lt $resourceIds .Count; $i ++) {
236
- $resourceId = $resourceIds [$i ]
237
- logText $( " ({0,$width }/$( $resourceIds .Count) ) Deleting $resourceId " -f $( $i + 1) )
238
- az connectedvmware $resourceType .AzSubCommand delete --debug --yes --ids $resourceId $azArgs 2>> $logFile
239
- if ($LASTEXITCODE -ne 0) {
240
- logText " Failed to delete $resourceId "
241
- $deleteFailed += $resourceId
242
- }
243
- if ($deleteFailed .Count -gt $DeleteFailedThreshold ) {
244
- fail @"
245
- Failed to delete $( $deleteFailed .Count) resources. Skipping the deletion of the rest of the resources in the vCenter.
246
- The resource ID of these resources are:
247
- ` t$( $deleteFailed -join " ` n` t" )
248
-
249
- Skipping vCenter deletion.
250
- " @
251
- }
252
- }
253
- }
254
-
255
- if ($deleteFailed .Count -gt 0) {
256
- fail @"
257
- Failed to delete $( $deleteFailed .Count) resources. The resource ID of these resources are:
258
- ` t$( $deleteFailed -join " ` n` t" )
259
-
260
- Skipping vCenter deletion.
261
- " @
262
- }
263
-
264
- Write-Host " "
265
- logText " Successfully deleted all the resources in the vCenter"
266
- logText " Deleting the vCenter: $vCenterId "
267
- $azArgs = @ ()
268
- if ($Force ) {
269
- $azArgs = @ (" --force" )
270
- }
271
- az connectedvmware vcenter delete --debug --yes --ids $vCenterId $azArgs 2>> $logFile
272
- if ($LASTEXITCODE -ne 0) {
273
- fail " Failed to delete $vCenterId "
274
- }
275
- if ($PSBoundParameters .ContainsKey(' AVSId' )) {
276
- logText " Deleting the arc addon for the AVS $AVSId "
277
- az rest --method delete --debug --url " $AVSId /addons/arc?api-version=$AVS_API_Version " 2>> $logFile
278
- if ($LASTEXITCODE -ne 0) {
279
- fail " Failed to delete $AVSId /addons/arc"
280
- }
281
- }
282
-
283
- function extractPartsFromID($id) {
284
- $id -match " /+subscriptions/+([^/]+)/+resourceGroups/+([^/]+)/+providers/+([^/]+)/+([^/]+)/+([^/]+)"
285
- return @{
286
- SubscriptionId = $Matches [1]
287
- ResourceGroup = $Matches [2]
288
- Provider = $Matches [3]
289
- Type = $Matches [4]
290
- Name = $Matches [5]
291
- }
292
- }
293
-
294
- if ($null -ne $clusterExtensionIds -and $clusterExtensionIds .Count -gt 1) {
295
- logText " Skipping the deletion of custom location and appliance because there are multiple cluster extensions enabled in the custom location"
296
- logText " The cluster extension IDs are:"
297
- logText " $( $clusterExtensionIds -join " ` n " )"
298
- exit 0
299
- }
300
- if ($null -eq $customLocation ) {
301
- logText " The custom location '$customLocationID ' is not found. Skipping the deletion of the custom location."
302
- }
303
- else {
304
- logText " Deleting the custom location: $customLocationID "
305
- $clInfo = extractPartsFromID $customLocationID
306
- az customlocation delete --debug --yes --subscription $clInfo .SubscriptionId --resource-group $clInfo .ResourceGroup --name $clInfo .Name 2>> $logFile
307
- # The command above is returning error when the cluster is not reachable, so $LASTEXITCODE is not reliable.
308
- # Instead, check if resource is not found after delete, else throw error.
309
- $cl = az resource show --ids $customLocationID --debug 2>> $logFile
310
- if ($cl ) {
311
- fail " Failed to delete $customLocationID "
312
- }
313
- }
314
- if ($otherCustomLocationsInAppliance .Count -gt 0) {
315
- logText " Skipping the deletion of the appliance because there are other custom locations in the appliance"
316
- logText " The custom location IDs of these custom locations are:"
317
- logText " $( $otherCustomLocationsInAppliance -join " ` n " )"
318
- exit 0
319
- }
320
-
321
- if ($PSBoundParameters .ContainsKey(' ApplianceConfigFilePath' )) {
322
- logText " Deleting the appliance: $applianceId "
323
- az arcappliance delete vmware --debug --yes --config-file $ApplianceConfigFilePath 2>> $logFile
324
- if ($LASTEXITCODE -ne 0) {
325
- fail " Failed to delete $applianceId "
326
- }
327
- }
328
- else {
329
- logText " Skipping the deletion of the appliance VM on the VCenter because the appliance config file path is not provided"
330
- logText " Just deleting the ARM resource of the appliance: $applianceId "
331
- az resource delete --debug --ids $applianceId 2>> $logFile
332
- if ($LASTEXITCODE -ne 0) {
333
- fail " Failed to delete $applianceId "
334
- }
335
- }
336
- logText " Cleanup Complete!"
337
- ` ` `
338
100
# ### Run the script
339
101
To run the deboarding script, follow these steps:
340
102
0 commit comments