0

I'm using the below script from http://vcloud-lab.com/entries/microsoft-azure/get-azure-virtual-machine-backup-reports-using-powershell to pull Azure VM backup details. Currently I have to run the script against each subscription, I would love to have it loop though all subscriptions.

I've been trying to get it working using this example https://www.jpaul.me/2019/05/azure-automation-how-to-quickly-work-with-many-subscriptions/ but I'm new to powershell and am struggling. Any suggestions would be really appreciated.

[CmdletBinding(SupportsShouldProcess=$True,
    ConfirmImpact='Medium',
    HelpURI='http://vcloud-lab.com',
    DefaultParameterSetName = 'AllVirtualMachines'
)]

<#
    .SYNOPSIS
    Collect Azure VM Backup Information

    .DESCRIPTION
    This Script collects Azure Virtual Machine Backup Recovery service vault information, This report includes the complete backup status Information of VM.

    .PARAMETER AllVirtualMachines
    Collect Backup information of the all Azure Virtual Machines, This is default parameter.

    .PARAMETER VirtualMachineList
    You can specify for which virtual machine you want backup information.

    .INPUTS
    None. Provides virtual machine information.

    .OUTPUTS
    Generate Backup information. You can pipe information to Export-CSV.

    .EXAMPLE
    PS> .\Get-AzVMBackupInformation.ps1
    
    VM_Name                         : vcloud-lab-vm01
    VM_Location                     : uksouth
    VM_ResourceGroupName            : VCLOUD-LAB.COM
    VM_BackedUp                     : True
    VM_RecoveryVaultName            : vault828
    VM_RecoveryVaultPolicy          : DailyPolicy-kosrnox0
    VM_BackupHealthStatus           : Passed
    VM_BackupProtectionStatus       : Healthy
    VM_LastBackupStatus             : Completed
    VM_LastBackupTime               : 27-05-2021 19:32:34
    VM_BackupDeleteState            : NotDeleted
    VM_BackupLatestRecoveryPoint    : 27-05-2021 19:32:37
    VM_Id                           : /subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/VCLOUD-LAB.COM/providers/Microsoft.Compute/virtualMachines/vcloud-lab-vm01
    RecoveryVault_ResourceGroupName : vCloud-lab.com
    RecoveryVault_Location          : uksouth
    RecoveryVault_SubscriptionId    : /subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vCloud-lab.com/providers/Microsoft.RecoveryServices/vaults/vault828

    .EXAMPLE
    PS> .\Get-AzVMBackupInformation.ps1 -AllVirtualMachines
    This produces same result as .\Get-AzVMBackupInformation.ps1 from all VMs

    .EXAMPLE
    PS> .\Get-AzVMBackupInformation.ps1 -VirtualMachineList
    Provide either single virtual machine name or in list
    
    .LINK
    Online version: http://vcloud-lab.com

    .LINK
    Get-AzVMBackupInformation.ps1
#>
Param
( 
    [parameter(Position=0, ParameterSetName = 'AllVMs' )]
    [Switch]$AllVirtualMachines,
    [parameter(Position=0, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True, ParameterSetName = 'VM' )]
    [alias('Name')]
    [String[]]$VirtualMachineList
) #Param
Begin 
{
    #Collecing Azure virtual machines Information
    Write-Host "Collecing Azure virtual machine Information" -BackgroundColor DarkGreen
    if (($PSBoundParameters.ContainsKey('AllVirtualMachines')) -or ($PSBoundParameters.Count -eq 0))
    {
        $vms = Get-AzVM
    } #if ($PSBoundParameters.ContainsKey('AllVirtualMachines'))
    elseif ($PSBoundParameters.ContainsKey('VirtualMachineList'))
    {
        $vms = @()
        foreach ($vmname in $VirtualMachineList)
        {
            $vms += Get-AzVM -Name $vmname
            
        } #foreach ($vmname in $VirtualMachineList)
    } #elseif ($PSBoundParameters.ContainsKey('VirtualMachineList'))

    #Collecing All Azure backup recovery vaults Information
    Write-Host "Collecting all Backup Recovery Vault information" -BackgroundColor DarkGreen
    $backupVaults = Get-AzRecoveryServicesVault
} #Begin 
Process
{
    $vmBackupReport = [System.Collections.ArrayList]::new()
    foreach ($vm in $vms) 
    {
        $recoveryVaultInfo = Get-AzRecoveryServicesBackupStatus -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Type 'AzureVM'
        if ($recoveryVaultInfo.BackedUp -eq $true)
        {
            Write-Host "$($vm.Name) - BackedUp : Yes"
            #Backup Recovery Vault Information
            $vmBackupVault = $backupVaults | Where-Object {$_.ID -eq $recoveryVaultInfo.VaultId}

            #Backup recovery Vault policy Information
            $container = Get-AzRecoveryServicesBackupContainer -ContainerType AzureVM -VaultId $vmBackupVault.ID -FriendlyName $vm.Name #-Status "Registered" 
            $backupItem = Get-AzRecoveryServicesBackupItem -Container $container -WorkloadType AzureVM -VaultId $vmBackupVault.ID
        } #if ($recoveryVaultInfo.BackedUp -eq $true)
        else 
        {
            Write-Host "$($vm.Name) - BackedUp : No" -BackgroundColor DarkRed
            $vmBackupVault = $null
            $container =  $null
            $backupItem =  $null
        } #else if ($recoveryVaultInfo.BackedUp -eq $true)
        
        [void]$vmBackupReport.Add([PSCustomObject]@{
            VM_Name = $vm.Name
            VM_Location = $vm.Location
            VM_ResourceGroupName = $vm.ResourceGroupName
            VM_BackedUp = $recoveryVaultInfo.BackedUp
            VM_RecoveryVaultName =  $vmBackupVault.Name
            VM_RecoveryVaultPolicy = $backupItem.ProtectionPolicyName
            VM_BackupHealthStatus = $backupItem.HealthStatus
            VM_BackupProtectionStatus = $backupItem.ProtectionStatus
            VM_LastBackupStatus = $backupItem.LastBackupStatus
            VM_LastBackupTime = $backupItem.LastBackupTime
            VM_BackupDeleteState = $backupItem.DeleteState
            VM_BackupLatestRecoveryPoint = $backupItem.LatestRecoveryPoint
            VM_Id = $vm.Id
            RecoveryVault_ResourceGroupName = $vmBackupVault.ResourceGroupName
            RecoveryVault_Location = $vmBackupVault.Location
            RecoveryVault_SubscriptionId = $vmBackupVault.ID
        }) #[void]$vmBackupReport.Add([PSCustomObject]@{
    } #foreach ($vm in $vms) 
} #Process
end
{
    $vmBackupReport
} #end
Yahtzee
  • 1
  • 2

1 Answers1

1

You can try this sample script from the MS doc for looping through multiple subscriptions.

Connect-AzAccount

$SubscriptionList = Get-AzSubscription

foreach ($Id in $SubscriptionList)
{
    #Provide the subscription Id where the VMs reside
    $subscriptionId = $Id

    #Provide the name of the csv file to be exported
    $reportName = "myReport.csv"
    Select-AzSubscription $subscriptionId
    $report = @()
    $vms = Get-AzVM
    $publicIps = Get-AzPublicIpAddress
    $nics = Get-AzNetworkInterface | ?{ $_.VirtualMachine -NE $null}

    foreach ($nic in $nics) 
        {
        $info = "" | Select VmName, ResourceGroupName, Region, VmSize, VirtualNetwork, Subnet, PrivateIpAddress, OsType, PublicIPAddress, NicName, ApplicationSecurityGroup, subscriptionId
        $vm = $vms | ? -Property Id -eq $nic.VirtualMachine.id

        foreach($publicIp in $publicIps) 
        {
            if($nic.IpConfigurations.id -eq $publicIp.ipconfiguration.Id) 
                {
                    $info.PublicIPAddress = $publicIp.ipaddress
                }
        }
        $info.subscriptionId = $subscriptionId
        $info.OsType = $vm.StorageProfile.OsDisk.OsType
        $info.VMName = $vm.Name
        $info.ResourceGroupName = $vm.ResourceGroupName
        $info.Region = $vm.Location
        $info.VmSize = $vm.HardwareProfile.VmSize
        $info.VirtualNetwork = $nic.IpConfigurations.subnet.Id.Split("/")[-3]
        $info.Subnet = $nic.IpConfigurations.subnet.Id.Split("/")[-1]
        $info.PrivateIpAddress = $nic.IpConfigurations.PrivateIpAddress
        $info.NicName = $nic.Name
        $info.ApplicationSecurityGroup = $nic.IpConfigurations.ApplicationSecurityGroups.Id
        $report+=$info
        }
    $report | ft subscriptionId, VmName, ResourceGroupName, Region, VmSize, VirtualNetwork, Subnet, PrivateIpAddress, OsType, PublicIPAddress, NicName, ApplicationSecurityGroup
    $report | Export-CSV "$home/$reportName"
}
 

References: Collect details about all VMs in a subscription with PowerShell - Azure Virtual Machines | Microsoft Docs , Iterate through subscriptions using an Array to avoid manual work · Issue #50670 · MicrosoftDocs/azure-docs · GitHub and powershell - How to loop through multiple Azure subscriptions on Azure Pipelines Yaml? - Stack Overflow

Madhuraj Vadde
  • 1,099
  • 1
  • 5
  • 13
  • It looks like that script example requires you to manually set the subscription context via the $subscriptionId variable, what I am looking for is for the script to automatically loop through all subscriptions. This example below does exactly that, getting AzVM info for all subscriptions. My problem is incorporating this into the script above. ` $VMs = @() $Subscriptions = Get-AzSubscription foreach ($sub in $Subscriptions) { Get-AzSubscription -SubscriptionName $sub.Name | Set-AzContext $VMs += Get-AzVM } $VMs | Ft ` – Yahtzee Mar 08 '22 at 12:58
  • you can use Get-AzSubscription to get all the subscriptions. Put the above script into loop that would go through all the subscriptions. https://learn.microsoft.com/en-us/powershell/module/az.accounts/get-azsubscription?view=azps-7.3.0#example-1--get-all-subscriptions-in-all-tenants – Madhuraj Vadde Mar 08 '22 at 13:03
  • I have updated the script that uses foreach loop to get all the VM details for all the Subscriptions (that logged in user is part of). You can change the core script (collecting VM details) based on your requirement. – Madhuraj Vadde Mar 08 '22 at 13:52