Query ASR Replicated Item Status using Powershell

In this short blog post, I am going to show how to query the status of replicated items in an Azure Site Recovery (ASR) vault.  My objective for this post is to share some of the details of ASR Powershell API/object model that may not be obvious immediately.  There are two reasons for this in my opinion.  The first is the fact that the object model does not necessarily map to the UI elements/object that are exposed in the portal which makes it a bit challenging to know where to start.  I am referring to objects such as ASRFabric and ASRProtectionContainer, which you will see in the script below, that do not have corresponding UI elements in the portal.  The second reason is that there are no end-to-end script examples (that I could find) which walk through the process of setting up the flow to be able to successfully query for the status of the replicated items.  Now that i have provided a bit of context for the post, here is the script flow.

  1. Create a service principal and gather the CLIENT_ID, CLIENT_SECRET, and your AAD TENANT_ID.  You can find more details here on how to create a Service Principal in Azure
  2. Assign Site Recovery Contributor RBAC role to the Service Principal to relevant subscriptions.  You can find more details here on how to assign a RBAC role to a Service Principal in subscription
  3. Login using service principal credentials
  4. For each Subscription that you are interested in
    1. Get all the Vault objects in the Subscription
    2. For each Vault
      1. Import the Vault settings file
      2. Get a list of Fabric objects in the Vault
      3. For each Fabric object
        1. Get a list of ASR Protection Container objects
        2. For each container object
          1. Get a list of replicated items
          2. Query the status and format for display as desired
 



# Variable Declaration
$CLIENT_SECRET = "Service Principal client secret"
$CLIENT_ID = "Service Principal client ID also known as Application ID"
$TENANT_ID = "AAD Tenant ID"

Write-Host "Logging you in..."
$secpasswd = ConvertTo-SecureString $CLIENT_SECRET -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($CLIENT_ID, $secpasswd)
Add-AzureRmAccount -ServicePrincipal -Tenant $TENANT_ID -Credential $mycreds

# Clear the contents of log file
Clear-Content -Path FILE_PATH_OF_VMSTATUS_LOG_FILE

# Enter the subscriptions where ASR is enabled
$Subscriptions = "An Array of subscription names that the Service Pricipal has access to (recommend Site Recovery Contributor RBAC role)"
foreach ($Subscription in $Subscriptions)
{
    # Select the subscription
    Select-AzureRmSubscription -SubscriptionName $Subscription

    # get the list of recovery services vaults in the subscription
    $VaultObjs = Get-AzureRmRecoveryServicesVault
    foreach ($VaultObj in $VaultObjs) 
    {
        # get and import vault settings file
        $VaultFileLocation = Get-AzureRmRecoveryServicesVaultSettingsFile -SiteRecovery -Vault $VaultObj
        Import-AzureRmRecoveryServicesAsrVaultSettingsFile -Path $VaultFileLocation.FilePath

        # get the list of fabrics in a vault
        $Fabrics = Get-AzureRmRecoveryServicesAsrFabric
        foreach ($Fabric in $Fabrics)
        {
            # get containers and protected items in a container
            $Containers = Get-AzureRmRecoveryServicesAsrProtectionContainer -Fabric $Fabric
            foreach ($Container in $Containers)
            {
                $items = Get-AzureRmRecoveryServicesAsrReplicationProtectedItem -ProtectionContainer $Container
                foreach ($item in $items)
                {
                    # Initialize an empty error array for capturing error(s) of each protected item
                    $ItemError = ""
                    foreach ($ASRerror in $item.ReplicationHealthErrors)
                    {
                        $ItemError=$ItemError,$ASRerror.ErrorMessage
                    }
                    
                    # Capture the status of machines which are in critical state to a file
                    If(-Not($item.ReplicationHealth -eq "Normal"))
                    {
                        $ASRVMHealthStatus=$Subscription+"`t"+$VaultObj.Name+"`t"+$Item.FriendlyName+"`t"+$Item.ReplicationHealth+"`t"+$ItemError
                        $ASRVMHealthStatus | Out-File -Append -FilePath FILE_PATH_OF_VMSTATUS_LOG_FILE
                    }
                }
            }
        }

        # remove vault settings file
        rm -Path $VaultFileLocation.FilePath
    }
}