Search code examples
azurepowershellazure-powershellazure-cloud-services

Why does Move-AzResource fail to move resources with dependencies within the same resource group?


I am trying to write a powershell script that automates aggregating all resources to the same resource group, but I'm hitting errors which stops the execution of Move-AzResource.

$resources = Get-AzResource
#Skip already migrated resources:
$resources = $resources | Where-Object {$_.ResourceGroupName -ne "spMigrateResourceGroup"}

$groups = $resources | Group-Object ResourceGroupName
$groups = $groups.Name

$groups | ForEach-Object {
    $group = $_

    $groupResources = $resources | Where-Object ResourceGroupName -eq $group
    $groupResourceIds = $groupResources.ResourceId

    $response = Move-AzResource -DestinationResourceGroupName $resourceGroupTarget `
    -ResourceId $groupResourceIds -Force -Verbose -Debug

    Write-Host $response
}

Since Move-AzResource is constrained to move resources within the same resource group at a time, I grab resourceId's within the same resource group and initiate Move-AzResource, but I hit errors like:

DEBUG: ============================ HTTP RESPONSE ============================

Status Code:
BadRequest

Headers:
Cache-Control                 : no-cache
Pragma                        : no-cache
x-ms-failure-cause            : gateway
x-ms-ratelimit-remaining-subscription-writes: 1199
x-ms-request-id               : e0f0f5e3-faaf-44ad-b3e4-61e51ad89a84
x-ms-correlation-request-id   : e0f0f5e3-faaf-44ad-b3e4-61e51ad89a84
x-ms-routing-request-id       : SOUTHCENTRALUS:20200331T165747Z:e0f0f5e3-faaf-44ad-b3e4-61e51ad89a84
Strict-Transport-Security     : max-age=31536000; includeSubDomains
X-Content-Type-Options        : nosniff
Date                          : Tue, 31 Mar 2020 16:57:46 GMT

Body:
{
  "error": {
    "code": "MultipleErrorsOccurred",
    "message": "Multiple error occurred: BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest. Please see details.",
    "details": [
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2S17W19/extensions/SqlIaasExtension' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2S17W19/extensions/joindomain' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS02/extensions/SiteRecovery-Windows' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS02/extensions/BGInfo' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS01/extensions/SiteRecovery-Windows' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS01/extensions/BGInfo' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG02/extensions/SiteRecovery-Windows' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG02/extensions/BGInfo' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG01/extensions/SiteRecovery-Windows' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG01/extensions/BGInfo' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2DFS01/extensions/SiteRecovery-Windows' is not a top level resource."
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2DFS01/extensions/BGInfo' is not a top level resource."
      },
        "message": "Identifier '//resourceGroups/rg-spoc-ae2/providers/      },
      {                                                                                                                  Microsoft.Compute/virtualMachines/SPOCAE2BIS01/extensions/SiteRecovery-Windows' is not a top level resource."
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/      },
      {                                                                                                                  Microsoft.Compute/virtualMachines/SPOCAE2BIS01/extensions/BGInfo' is not a top level resource."
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/rg-spoc-ae2/providers/      },
      {                                                                                                                  Microsoft.Compute/virtualMachines/SPOCAE2ADS01/extensions/Microsoft.Powershell.DSC' is not a top level resource."
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/rg-spoc-ae2/providers/
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/
      },
      {
        "code": "ResourceNotTopLevel",
        "message": "Identifier '//resourceGroups/RG-SPOC-AE2/providers/
      }
    ]
  }
}

I believe when it says "ResourceNotTopLevel" it's saying it's a dependency and is supposed to be moved together with the top level resource that controls it, like a database server with databases. But I'm fairly sure the dependencies and dependents are packaged within the same resource group, and is therefore provided within the Move-AzResource command. In fact, I can initiate the same command on the Azure Portal by using the "Move" feature of resource groups, and it successfully moves every resource in the group to a target resource group - which suggests to me everything necessary for the move is in the resource group.

So I guess my question is two fold: why is this happening (especially since it seems to work on the portal), and why doesn't Move-AzResource at least move forward with moving the resources it can? The docs suggest that the command does its best to move what it can, but Move-AzResource seems to stop upon trying to validate some of the bad requests. Here are the resources sent with one iteration of the loop:

Body:
{
  "targetResourceGroup": "//resourceGroups/spMigrateResourceGroup",
  "resources": [
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Storage/storageAccounts/stoae2arscache",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Storage/storageAccounts/frankcloudshellstorage",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.SqlVirtualMachine/SqlVirtualMachines/SPOCAE2S17W19",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/virtualNetworks/VNET-SPOC-AE2",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/publicIPAddresses/SQL-EXTERNAL",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/publicIPAddresses/SQL2014SP3-EXTERNAL",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/publicIPAddresses/PIP-VNG-VNET-SPOC-AE2",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/publicIPAddresses/PIP-SPOCAE2NST01-1",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/publicIPAddresses/PIP-RDG-SPOC-AE2",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/publicIPAddresses/PIP-EXTERNAL",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/publicIPAddresses/PIP-DFS",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/publicIPAddresses/PIP-ADS",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkSecurityGroups/NSG-SPOC-AE2",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkInterfaces/spocae2nst01155",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkInterfaces/NIC-SPOCAE2S17W19-01",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkInterfaces/NIC-SPOCAE2RDS02-1",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkInterfaces/NIC-SPOCAE2RDS01-1",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkInterfaces/NIC-SPOCAE2RDG02-1",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkInterfaces/NIC-SPOCAE2RDG01-1",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkInterfaces/NIC-SPOCAE2DFS01-1",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkInterfaces/NIC-SPOCAE2BIS02-1",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkInterfaces/NIC-SPOCAE2BIS01-1",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/networkInterfaces/NIC-SPOCAE2ADS01-1",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/localNetworkGateways/LNG-VNET-SPOC-AWU",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/loadBalancers/ILB-SPOCAFCAE2-SSRS",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Network/loadBalancers/ILB-SPOCAFCAE2-SQL",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.DevTestLab/schedules/shutdown-computevm-SPOCAE2DFS01",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.DevTestLab/schedules/shutdown-computevm-SPOCAE2ADS01",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2S17W19/extensions/SqlIaasExtension",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2S17W19/extensions/joindomain",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2S17W19",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS02/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS02/extensions/BGInfo",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS02",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS01/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS01/extensions/BGInfo",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS01",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG02/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG02/extensions/BGInfo",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG02",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG01/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG01/extensions/BGInfo",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG01",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2DFS01/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2DFS01/extensions/BGInfo",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2DFS01",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2BIS01/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2BIS01/extensions/BGInfo",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2BIS01",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2ADS01/extensions/Microsoft.Powershell.DSC",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2ADS01",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SQL_TEMPDB_H",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SQL_OSDISK",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SQL_LOG_G",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SQL_DATA_F",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SQL2014SP3_TEMPDB_H",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SQL2014SP3_OSDISK",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SQL2014SP3_LOG_G",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SQL2014SP3_DATA_F",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2S17W19_TEMPDB_H",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2S17W19_OSDISK",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2S17W19_LOG_G",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2S17W19_DATA_F",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2RDS02_OSDISK.vhd",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2RDS01_OSDISK.vhd",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2RDG02_OSDISK.vhd",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2RDG01_OSDISK.vhd",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2NST01_OsDisk_1_1e0ef5ca87c34a0d9283d37b3c531910",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2DFS01_OSDISK.vhd",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2DFS01_DFS_DISK_1",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2BIS02_OSDISK.vhd",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2BIS01_OSDISK.vhd",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/disks/SPOCAE2ADS01_OSDISK.vhd",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/availabilitySets/AS-SPOC-SQL-AE2",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/availabilitySets/AS-SPOC-RDS-AE2",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/availabilitySets/AS-SPOC-RDG-AE2",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/availabilitySets/AS-SPOC-DFS-AE2",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/availabilitySets/AS-SPOC-BIS-AE2",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/availabilitySets/AS-SPOC-ADS-AE2"
  ]
}

Note: I cut out the subscriptions from the errors provided.

Update: Here is the error message preceding the expanded debug log:

Message        : MultipleErrorsOccurred : Multiple error occurred: BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest,BadRequest. Please see details.
StackTrace     :    at Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.ResourceManagerCmdletBase.HandleException(ExceptionDispatchInfo capturedException)
                    at Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.ResourceManagerCmdletBase.EndProcessing()
                    at System.Management.Automation.CommandProcessorBase.Complete()
Exception      : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Entities.ErrorResponses.ErrorResponseMessageException
InvocationInfo : {Move-AzResource}
Line           :     $response = Move-AzResource -DestinationResourceGroupName $resourceGroupTarget `

Position       : At ...\aggregator.ps1:82 char:17
                 + … $response = Move-AzResource -DestinationResourceGroupName $resourceGr …
                 +  

Solution

  • From resources, remove all .../extensions/xxx resources. i.e.:

    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2S17W19/extensions/SqlIaasExtension",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2S17W19/extensions/joindomain",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS02/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS02/extensions/BGInfo",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS01/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDS01/extensions/BGInfo",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG02/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG02/extensions/BGInfo",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG01/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2RDG01/extensions/BGInfo",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2DFS01/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2DFS01/extensions/BGInfo",
    "//resourceGroups/rg-spoc-ae2/providers/Microsoft.Compute/virtualMachines/SPOCAE2BIS01/extensions/SiteRecovery-Windows",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2BIS01/extensions/BGInfo",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2ADS01/extensions/Microsoft.Powershell.DSC",
    

    If we take this machine (SPOCAE2S17W19) and associated resources as an example:

    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2S17W19/extensions/SqlIaasExtension",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2S17W19/extensions/joindomain",
    "//resourceGroups/RG-SPOC-AE2/providers/Microsoft.Compute/virtualMachines/SPOCAE2S17W19",
    

    The "top level" group in this case is:

    .../virtualMachines/SPOCAE2S17W19
    

    The other resources under it:

    .../virtualMachines/SPOCAE2S17W19/extensions/SqlIaasExtension
    .../virtualMachines/SPOCAE2S17W19/extensions/joindomain
    

    Are not "top level groups".

    These extensions will be automatically moved with the main "top level" group, e.g. .../virtualMachines/SPOCAE2S17W19.