1+ $subscriptionId = ' ########-####-####-####-############'
2+ $subscriptionName = ' YOUR-AZURE-SUBSCRIPTION-NAME'
3+ $resourceGroupName = ' YOUR-AZURE-RESOURCE-GROUP-NAME'
4+ $location = ' YOUR-AZURE-RESOURCE-GROUP-LOCATION'
5+ $vmName = ' YOUR-VIRTUAL-MACHINE-NAME'
6+ $snapshotName = ' SNAPSHOT-NAME'
7+ $diskName = " YOUR-SNAPSHOT-BACKUP-NAME"
8+ $storageType = ' ' # E.g., 'Premium_LRS'
9+ $bkmFile = " FILEPATH-FOR-THE-.BKM-FILE" # E.g., "C:\BKP\db.bkm"
10+
11+ $SQLServer = " YOUR-SQL-SERVER-INSTANCE-NAME"
12+ $db = " YOUR-DATABASE-NAME"
13+
14+ $suspendDb = " ALTER DATABASE [" + $db + " ] SET SUSPEND_FOR_SNAPSHOT_BACKUP ON;"
15+ $backupMetadata = " BACKUP DATABASE [" + $db + " ] TO DISK='" + $bkmfile + " ' WITH SNAPSHOT, FORMAT;"
16+ $unsuspendDb = " ALTER DATABASE [" + $db + " ] SET SUSPEND_FOR_SNAPSHOT_BACKUP OFF;"
17+
18+ $createDB = " IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = '" + $db + " ') CREATE DATABASE " + $db
19+ $dropDB = " IF EXISTS(SELECT * FROM sys.databases WHERE name = '" + $db + " ') BEGIN ALTER DATABASE [" + $db + " ] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;DROP DATABASE " + $db + " END"
20+ $mdfFile = " F:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\" + $db + " .mdf"
21+ $ldfFile = " F:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\" + $db + " _log.ldf"
22+
23+ $restoreDB = " RESTORE DATABASE [" + $db + " ] FROM DISK='" + $bkmFile + " ' WITH SNAPSHOT, MOVE '" + $db + " ' TO '" + $mdfFile + " ', MOVE '" + $db + " _log' TO '" + $ldfFile + " ';"
24+
25+
26+ # Login and set the Azure subscription
27+ # ##########################################
28+ az login
29+ Connect-AzAccount
30+ Select-AzSubscription - SubscriptionId $subscriptionId
31+ az account set -- subscription $subscriptionName
32+
33+ # Import Modules
34+ # ##########################################
35+ Import-Module - Name SQLPS
36+ Install-Module - Name Az
37+
38+ # Create a sample database
39+ # ##########################################
40+ $sqlConn = New-Object System.Data.SQLClient.SQLConnection
41+ # Open SQL Server connection to master
42+ $sqlConn.ConnectionString = " server='" + $SQLServer + " ';database='master';Integrated Security=True;"
43+ $sqlConn.Open ()
44+
45+ $Command = New-Object System.Data.SQLClient.SQLCommand
46+ $Command.Connection = $sqlConn
47+
48+ # Create Database
49+ $Command.CommandText = $createDB
50+ $Result = $Command.ExecuteNonQuery ();
51+
52+ # Close SQL Server connection
53+ $sqlConn.Close ()
54+
55+ # Take a snapshot backup
56+ # ##########################################
57+
58+ $sqlConn.ConnectionString = " server='" + $SQLServer + " ';database='" + $db + " ';Integrated Security=True;"
59+
60+ # Open SQL Server connection
61+ $sqlConn.Open ()
62+
63+ $Command = New-Object System.Data.SQLClient.SQLCommand
64+ $Command.Connection = $sqlConn
65+
66+ # Suspend Database
67+ $Command.CommandText = $suspendDb
68+ $Result = $Command.ExecuteNonQuery ();
69+
70+ # Take a disk snapshot
71+ try
72+ {
73+ $osDiskId = az vm show - g $resourceGroupName - n $vmName -- query " storageProfile.osDisk.managedDisk.id" - o tsv
74+ az snapshot create - g $resourceGroupName -- source " $osDiskId " -- name $snapshotName
75+ }
76+ catch
77+ {
78+ # Unsuspend Database
79+ $Command.CommandText = $unsuspendDb
80+ $Result = $Command.ExecuteNonQuery ();
81+ }
82+
83+ # Backup database metadata
84+ $Command.CommandText = $backupMetadata
85+ $Result = $Command.ExecuteNonQuery ();
86+
87+ # Unsuspend Database
88+ $Command.CommandText = $unsuspendDb
89+ $Result = $Command.ExecuteNonQuery ();
90+
91+ # Close SQL Server connection
92+ $sqlConn.Close ()
93+
94+ # Mount Disk
95+ # ##########################################
96+
97+ $snapshot = Get-AzSnapshot - SnapshotName $snapshotName
98+
99+ # Create Disk from snapshot
100+ $diskConfig = New-AzDiskConfig - AccountType $storageType - Location $location - CreateOption Copy - SourceResourceId $snapshot.Id - Zone 1
101+ New-AzDisk - ResourceGroupName $resourceGroupName - DiskName $diskName - Disk $diskConfig
102+
103+ # Attach disk to VM
104+ $disk = Get-AzDisk - ResourceGroupName $resourceGroupName - DiskName $diskName
105+ $vm = Get-AzVM - Name $vmName - ResourceGroupName $resourceGroupName
106+
107+ $vm = Add-AzVMDataDisk - Name $diskName - CreateOption Attach - Lun 0 - VM $vm - ManagedDiskId $disk.Id
108+ Update-AzVM - VM $vm - ResourceGroupName $resourceGroupName
109+
110+ # Bring disk online
111+ # ##########################################
112+ # TODO: Get Disk Number programmatically - Currently hardcoded to 2
113+ Set-Disk - Number 2 - IsOffline $false
114+
115+
116+ # Drop database and restore from snapshot
117+ # ##########################################
118+ # Open SQL Server connection to master
119+ $sqlConn.ConnectionString = " server='" + $SQLServer + " ';database='master';Integrated Security=True;"
120+ $sqlConn.Open ()
121+
122+ $Command = New-Object System.Data.SQLClient.SQLCommand
123+ $Command.Connection = $sqlConn
124+
125+ # Drop Database
126+ $Command.CommandText = $dropDB
127+ $Result = $Command.ExecuteNonQuery ();
128+
129+ # Restore Database
130+ $Command.CommandText = $restoreDB
131+ $Result = $Command.ExecuteNonQuery ();
132+
133+ # Close SQL Server connection
134+ $sqlConn.Close ()
135+
136+
137+ # Clean up
138+ # ##########################################
139+
140+ # Open SQL Server connection to master
141+ $sqlConn.ConnectionString = " server='" + $SQLServer + " ';database='master';Integrated Security=True;"
142+ $sqlConn.Open ()
143+
144+ $Command = New-Object System.Data.SQLClient.SQLCommand
145+ $Command.Connection = $sqlConn
146+
147+ # Drop Database
148+ $Command.CommandText = $dropDB
149+ $Result = $Command.ExecuteNonQuery ();
150+
151+ # Close SQL Server connection
152+ $sqlConn.Close ()
153+
154+
155+ # Remove snapshot
156+ Remove-AzSnapshot - ResourceGroupName $resourceGroupName - SnapshotName $snapshotName - Force;
157+
158+ # Remove metadata file
159+ if (Test-Path $bkmFile ) {
160+ Remove-Item $bkmFile
161+ }
162+
163+ # Remove disk from VM
164+ $vm = Remove-AzVMDataDisk - VM $vm - Name $diskName
165+ Update-AzVM - VM $vm - ResourceGroupName $resourceGroupName
166+
167+ # Remove unmanaged disk
168+ Remove-AzDisk - ResourceGroupName $resourceGroupName - DiskName $diskName - Force;
0 commit comments