Check possibility of Azure resource migration

Hey Folks! Today I want to show you script for Azure resource migration validation to new subscription.

Some time ago I have a request from customer to migrate some project specific Azure resources to new subscription. I wanted to be sure that I will do not have any problem once I click “Move” button directly from portal. I googled for solution and couldn’t find any script which will tell me if I can move resources or not. The only thing I found was Azure API which can tell you if migration is possible or not, so I decided to write some to make my life easier 🙂

Script require as input parameters for things:

  • sourceSubscriptionId
  • targetSubscriptionId
  • sourceResourceGroup,
  • targeResourceGroup

It’s checking for all resources in source resource group and check if they can be moved to source resource group in new subscription. In case that some resource is not possible to move script will let you know about that but without details why. Unfortunately API don’t provide such information. And that’s it – Azure resource migration validation is easy 🙂

Script:

param(
    $sourceSubscriptionID,
    $targetSubscriptionID,
    $sourceresourceGroup,
    $targetresourceGroup
)

function Get-AzCachedAccessToken()
{
    $azureContext = Get-AzContext
    $currentAzureProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile;
    $currentAzureProfileClient = New-Object Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient($currentAzureProfile);
    $azureAccessToken = $currentAzureProfileClient.AcquireAccessToken($azureContext.Tenant.Id).AccessToken;
    $azureAccessToken

}

function Get-AzBearerToken()
{
    $ErrorActionPreference = 'Stop'
    ('Bearer {0}' -f (Get-AzCachedAccessToken))
}

$currentContext = (Get-AzContext | select Subscription).Subscription.Id

if(!$currentContext){
    Login-AzAccount -SubscriptionId $sourceSubscriptionID
}
if($currentContext -ne $sourceSubscriptionID){
    Select-AzSubscription -SubscriptionId $sourceSubscriptionID
}

$resources = (Get-AzResource -ResourceGroupName $sourceresourceGroup)
foreach($resource in $resources){

    Write-Host "Checking resource type: $($resource.ResourceType) with resource name: $($resource.Name)"

    $resourceID = @()
    $resourceID += $resource.resourceId
    $body = @{
     resources=$resourceID ;
     targetResourceGroup= "/subscriptions/$targetSubscriptionID/resourceGroups/$targetresourceGroup"
    }

    #add try catch
    Try{
    $return = Invoke-WebRequest -Uri "https://management.azure.com/subscriptions/$sourceSubscriptionID/resourceGroups/$sourceresourceGroup/validateMoveResources?api-version=2018-02-01" -method Post -Body (ConvertTo-Json $body) -ContentType "application/json" -Headers @{Authorization = (Get-AzBearerToken)}
    }
    Catch{
        $statusCode = $null
        $statusCode = $_.Exception.Message
    }

    if($statusCode){
        [int]$retryTime = ($return.RawContent -split "Retry-After: ")[1].Substring(0,2)
        $retryTime = $retryTime+5

        do{
            Write-Host Waiting for status...
            Start-Sleep -Seconds $retryTime

            $validationUrl = ($return.RawContent -split "Location: ")[-1]
            $validationUrl = $validationUrl.Replace('`r`n','')
            Try{
            $status = Invoke-WebRequest -Uri $validationUrl -method Get -ContentType "application/json" -Headers @{Authorization = (Get-AzBearerToken)}
            $statusCode = $status.StatusCode
            }
            Catch{
                $statusCode = 205
                $Exc = $_.Exception
            }
        }
        while($statusCode -eq 202)

        if($statusCode -eq 205){
            Write-host "Resource type $($resource.ResourceType) with resource name $($resource.Name)can not be moved. Error: $Exc" -ForegroundColor Red
        }
        elseif($statusCode -eq 204){
            Write-Host "Resource type $($resource.ResourceType) with resource name $($resource.Name) can be moved to new subscrtipion" -ForegroundColor Green
        }
        else{
            Write-Host "Another problem occured for resource type $($resource.ResourceType) with resource name $($resource.Name). Error: $Exc"
        }
    }
    else{
        Write-Host "Another error occured. Error: $statusCode"
    }
}

I hope it will be usefull for some of you 😉

Enjoy!

2 thoughts on “Check possibility of Azure resource migration

  1. Hi
    Could you please share script
    log analytics integration with azure secrets and keys expiry date
    We have script only for secrets and keys expiry date , so could you please share log analytics integration also

    thank you

    1. Sorry, but generally we shared scripts which we created because they were usefull for us in some projects.
      We are not preparing scripts base on your orders 😉

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.