Skip to content
Menu
Tech Automation Blog
  • About Author
  • Contact
Tech Automation Blog

Create Azure disk snapshot using Powershell

Posted on August 17, 2019February 27, 2022

Update : updated script to support Azure Az powershell module.

Today , I am going to share a script to take Snapshot of Azure Managed disks. Taking a snapshot of business critical systems before working on any system change which can potentially cause business impact is crucial. If something goes wrong, you can quickly restore it from the snapshot.

Following script is written in a format to run as an Automation Account Runbook in Azure. However, you can easily change it to run as a normal Powershell script. You can take snapshots of both OS Disk and Data Disks based on passed parameters.

Before start using this script, make sure, you have Azure Az Module installed and imported on the system. For more information on how to install and configure Az module refer following article : https://docs.microsoft.com/en-us/powershell/azure/new-azureps-module-az?view=azps-5.5.0 .

Param(
    [String]$vmName,
    [Parameter(Mandatory=$true)]
    [String]$resourceGroupName,
    [Parameter(Mandatory=$false)]
    [bool]$includeOSDisk = $true,
    [Parameter(Mandatory=$true)]
    [bool]$includeDataDisk = $false,
    [Parameter(Mandatory=$true)]
    [bool]$allowShutdown
)
#region - login to Azure from the Automation Account.Setup Automation account as prerequisite.
$connectionName = "AzureRunAsConnection"
try{
    #Get the connection 'AzureRunAsConnection'
    $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName
    "Logging in to Azure..."
    Add-AzAccount `
        -ServicePrincipal `
        -TenantId $servicePrincipalConnection.TenantId `
        -ApplicationId $servicePrincipalConnection.ApplicationId `
        -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch{
    if(!$ServicePrincipalConnection){
        $ErrorMessage = "Connection $connectionName not found."
        throw $ErrorMessage
    }else{
        Write-Error -Message $_.Exception
        throw $_.Exception
    }
}
#endregion
#get vm details check if vm exists, if no, exit out
try{
    $vmDetails = Get-AzVM -Name $vmName -ResourceGroupName $resourceGroupName
    if([string]::IsNullOrEmpty($vmDetails)){
        Write-Error -Message "ERROR: No such VM $vmName exists in the resource group or subscription.Try again with correct VM name."
        Exit
    }
}
catch{
    Write-Error -Message $_.Exception
    throw $_.Exception
    Exit
}
#
#function to take snapshot
function take-snapshot($dUri,$dName,$vm,$rgName,$loc){
    try{
        $snapshot = New-AzSnapshotConfig -SourceUri $dUri -Location $loc -CreateOption Copy
        $snapshotName = "$($dName)-$((Get-Date).ToString("MM-dd-yyyy-HHmmss"))"
        $snapshotStatus = New-AzSnapshot -SnapshotName $snapshotName -ResourceGroupName $rgName -Snapshot $snapshot
        if($snapshotStatus.ProvisioningState -ne "Succeeded"){
            Write-Error -Message "ERROR: Failed to take snapshot disk $dName of $vm."     
        }
        else{
            Write-Output "SUCCESS: Snapshot for disk $dName has been completed successfully.Snapshot Name : $snapshotName. "
        }
    }
    catch{
        Write-Error -Message "ERROR: Failed to take snapshot of disk $dName of $vm."
        Exit        
    }
}
#
#shutdown if the parameter set to allow shutdown
if($allowShutdown){
    try{
        $vmPowerStatus = (Get-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -Status).Statuses.code
        if($vmPowerStatus -contains "PowerState/running"){
            $vmRunning = $true
            Stop-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -StayProvisioned -Force -Confirm:$false
            do
            {
                Start-Sleep -Seconds 5
                $vmPowerStatus = (Get-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -Status).Statuses.code
            }while($vmPowerStatus -contains "PowerState/running")        
        }
    }
    catch{
        Write-Error -Message "ERROR: Failed to shutdown $vm.Script will exit"
        Exit         
    }
}
#
#based on disk selection take snapshot of disks
if($includeOSDisk){
    $diskUri = $vmDetails.StorageProfile.OsDisk.ManagedDisk.Id
    $diskName = $vmDetails.StorageProfile.OsDisk.Name
    take-snapshot $diskUri $diskName $vmName $resourceGroupName $vmDetails.Location
}
if($includeDataDisk){ 
    $dataDisks = $vmDetails.StorageProfile.DataDisks  
    if(!([string]::IsNullOrEmpty($dataDisks))){
        foreach($disk in $dataDisks){
            $diskUri = $disk.ManagedDisk.Id
            $diskName = $disk.Name
            take-snapshot $diskUri $diskName $vmName $resourceGroupName $vmDetails.Location
        }        
    }
    else{
        Write-Output "INFORMATION: No Data disk attached to this VM.Skipping Snapshot process for Data disks."
    }    
}
#
Write-Output "INFORMATION: Snapshot operation has been completed for $vmName."

#bring server back online if it was shutdown earlier
if($allowShutdown -and $vmRunning){
    try{
        Start-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -Confirm:$false
        do
        {
            Start-Sleep -Seconds 5
            $vmPowerStatus = (Get-AzVM -Name $vmName -ResourceGroupName $resourceGroupName -Status).Statuses.code
        }while(!($vmPowerStatus -contains "PowerState/running"))
        Write-Output "INFORMATION: Virtual Machine $vmName is back online now."
    }
    catch{
        Write-Error "ERROR: Failed to bring $vmName online.Please check the $vmName through portal"
    }
}
#

Login to Azure Portal using https://portal.azure.com and open Azure Automation Accounts from left pane.

Login to Azure Portal

Open configured Azure Automation account and select Runbooks from Process Automation option in the left pane.

Note: To run this script you will need to Import Powershell Az Modules, otherwise, it will throw error. Refer following article on how to import different modules :

https://docs.microsoft.com/en-us/azure/automation/shared-resources/modules

Create new Runbook

Create a new Runbook using the script above and save it. Once, it is saved run the Runbook from the list.

Execute Runbook

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on LinkedIn (Opens in new window) LinkedIn
July 2025
M T W T F S S
 123456
78910111213
14151617181920
21222324252627
28293031  
« May    

Recent Posts

  • Monitor and alert Azure Service Health issues May 5, 2020
  • AWS IAM User access review May 3, 2020
  • Integrate Azure Security Center with Event Hub April 28, 2020
  • Add Tags to Azure Subscription April 24, 2020
  • Automate Azure billing report in Excel March 6, 2020

Categories

©2025 Tech Automation Blog | Powered by SuperbThemes