There have been changes in the way Azure is processing some of our old scripts, so we spent some time re-writing them. As such this article is intended to replace a July 2024 article with the same title.

This script will create and delete snapshots for all Azure subscriptions and Resource Groups within a single tenant.

Cloudshell / PowerShell Script to Snapshot All VM’s in All Subscriptions and Resource Groups

In the first and 10th lines you can see that it is set to skip any VM starting with XXXXXXX

  • You can obviously edit XXXXXXX as you see fit
    • In our case, our client had a dozens of VM’s that all started with the same prefix, they did not want us to snapshot


# Get all subscriptions and resource groups, then create snapshots of all VMs, excluding those starting with "XXXXXXX"
Get-AzSubscription | ForEach-Object {
    Set-AzContext -SubscriptionId $_.Id
    $resource_groups = Get-AzResourceGroup | Select-Object -ExpandProperty ResourceGroupName
    $resource_groups | ForEach-Object { $rg = $_
        Write-Host "Processing resource group: $rg"
        $vms = Get-AzVM -ResourceGroupName $rg
        $vms | ForEach-Object {
            $vm = $_
            if ($vm.Name -like "XXXXXXX*") {
                Write-Host "Skipping VM: $($vm.Name)"
                return
            }

            Write-Host "Creating snapshot of VM: $($vm.Name)"
            $osDisk = Get-AzDisk -ResourceGroupName $rg -DiskName $vm.StorageProfile.OsDisk.Name

            $snapshotConfig = New-AzSnapshotConfig -SourceUri $osDisk.Id -Location $vm.Location -CreateOption Copy
            $snapshotName = "URTech-$($vm.Name)-$(Get-Date -Format 'yyyyMMddHHmmss')"
            New-AzSnapshot -ResourceGroupName $rg -Snapshot $snapshotConfig -SnapshotName $snapshotName
            Write-Host "Successfully created snapshot: $snapshotName"
        }
    }
}

How To Delete ALL Snapshots From All Subscriptions and Resource Groups

Here we have two options.

1 – Delete ALL Snapshots


# Get all subscriptions and resource groups, then delete all snapshots
Get-AzSubscription | ForEach-Object {
    Set-AzContext -SubscriptionId $_.Id
    $resource_groups = Get-AzResourceGroup | Select-Object -ExpandProperty ResourceGroupName
    $resource_groups | ForEach-Object {
        Write-Host "Processing resource group: $_"
        $snapshots = Get-AzSnapshot -ResourceGroupName $_
        $snapshots | ForEach-Object {
            Write-Host "Deleting snapshot: $($_.Name)"
            try {
                Remove-AzSnapshot -ResourceGroupName $_.ResourceGroupName -SnapshotName $_.Name -Force
                Write-Host "Successfully deleted snapshot: $($_.Name)"
            } catch {
                Write-Host "Failed to delete snapshot: $($_.Name). Error: $_"
            }
        }
    }
}

2 – Delete All Snapshots Starting With the Prefix URTech-

In the script to create snapshots we prefixed all of the snaps with the text URTECH-, to keep your snapshots distinct from other people snapshots.

If you want to only delete the ones you just created use this slightly modified version of the script above:


# Get all subscriptions and resource groups, then delete snapshots prefixed with "URTech-"
Get-AzSubscription | ForEach-Object {
    Set-AzContext -SubscriptionId $_.Id
    $resource_groups = Get-AzResourceGroup | Select-Object -ExpandProperty ResourceGroupName
    $resource_groups | ForEach-Object {
        Write-Host "Processing resource group: $_"
        $snapshots = Get-AzSnapshot -ResourceGroupName $_
        $snapshots | ForEach-Object {
            if ($_.Name -like "URTech-*") {
                Write-Host "Deleting snapshot: $($_.Name)"
                try {
                    Remove-AzSnapshot -ResourceGroupName $_.ResourceGroupName -SnapshotName $_.Name -Force
                    Write-Host "Successfully deleted snapshot: $($_.Name)"
                } catch {
                    Write-Host "Failed to delete snapshot: $($_.Name). Error: $_"
                }
            } else {
                Write-Host "Skipping snapshot: $($_.Name)"
            }
        }
    }
}


0 Comments

Leave a Reply

Avatar placeholder

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