Skip to content

Commit 6eded6b

Browse files
authored
Merge pull request #12 from PureStorage-OpenConnect/ayun
T-SQL Snapshot w VMFS - V1
2 parents f8a8af9 + 8b0381b commit 6eded6b

File tree

6 files changed

+825
-111
lines changed

6 files changed

+825
-111
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
**VMFS/VMDK + SQL Server Snapshot Scripts**
2+
<p align="center"></p>
3+
This folder contains VMFS/VMDK + SQL Server example snapshot scripts.
4+
5+
**Files:**
6+
- VMFS-VMDK Snapshot.ps1
7+
8+
<!-- wp:separator -->
9+
<hr class="wp-block-separator"/>
10+
<!-- /wp:separator -->
11+
12+
**Scenario:**
13+
<BR>This example script shows steps to snapshot a VMFS datastore that contains data & log VMDKs for a SQL Server. The overall scenario is taking a snapshot of a production SQL Server's underlying datastore, and cloning the datastore to then overlay a pre-existing non-production datastore for a non-production SQL Server.
14+
15+
All references to a "target" refer to the non-production side (VM, datastore, etc).
16+
17+
**Prerequisites:**
18+
1. The production datastore must already be cloned and presented once, to the non-production side.
19+
2. This script assumes the database(s) are already attached on the target, non-production SQL Server.
20+
21+
**Important Usage Notes:**
22+
<BR>You must pre-setup the target VM with a cloned datastore from the source already. You will ONLY be utilizing the specific VMDK(s) that contain the data/log files of interest, from the cloned datastore. Also note that the VMFS datastore does not need to only exclusively contain VMDKs for the SQL Server in question. If other VMDKs are present in the datastore, used by the either the source SQL Server VM or other VMs, they do not need to be deleted or otherwise manipulated during this cloning process. Remember FlashArray deduplicates data, thus a clone's set of additional, unused VMDKs will not have a negative impact.
23+
24+
For the cloned datastore pre-setup, you can use subsets of the code below to clone the source datastore, present it to the target server, then attach the VMDK(s) containing the production databases that will be re-cloned with this script. Once "staged," you can then use this script fully to refresh the data files in the cloned datastore that is attached to the target server.
25+
26+
When cloning, note that the target datastore is dropped and replaced entirely. This is because when cloning a datastore, it must be resignatured and the datastore will be renamed with a non-deterministic naming scheme (snap-[[GUID chars]]-[[original DS name]]). Thus it is not possible to know what the new datastore name will be until the resignature step is executed.
27+
28+
This script also assumes that all database files (data and log) are on the same volume/single VMDK. If multiple volumes/VMDKs are being used, you will have to adjust the code (ex: add additional foreach loops for manipulating multiple VMDKs).
29+
30+
<!-- wp:separator -->
31+
<hr class="wp-block-separator"/>
32+
<!-- /wp:separator -->
33+
34+
**Disclaimer:**
35+
<BR>
36+
This example script is provided AS-IS and meant to be a building block to be adapted to fit an individual organization's infrastructure.
37+
<BR>
38+
<BR>
39+
40+
We encourage the modification and expansion of these scripts by the community. Although not necessary, please issue a Pull Request (PR) if you wish to request merging your modified code in to this repository.
41+
42+
<!-- wp:separator -->
43+
<hr class="wp-block-separator"/>
44+
<!-- /wp:separator -->
45+
46+
_The contents of the repository are intended as examples only and should be modified to work in your individual environments. No script examples should be used in a production environment without fully testing them in a development or lab environment. There are no expressed or implied warranties or liability for the use of these example scripts and templates presented by Pure Storage and/or their creators._
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
##############################################################################################################################
2+
# Refresh VMFS VMDK with Snapshot Demo
3+
#
4+
#
5+
# Scenario:
6+
# Snapshot and clone a "production" VMDK in a VMFS datastore, then present it to a "non-production" server.
7+
#
8+
# This example has two databases: ExampleDb1, ExampleDb2, whose data and log files both reside on a single disk/VMDK.
9+
#
10+
#
11+
# Usage Notes:
12+
#
13+
# You must pre-setup the target VM with a cloned datastore from the source already. You will ONLY be utilizing
14+
# the SPECIFIC VMDK(s) that contain the data/log files of interest, from the cloned datastore. Other VMDKs can safely be
15+
# ignored since they are deduped on FlashArray.
16+
#
17+
# For the cloned datastore pre-setup, you can use subsets of the code below to clone the source datastore, present it to
18+
# the target server, then attach the VMDK(s) containing the production databases that will be re-cloned with this script.
19+
# Once "staged," you can then use this script fully to refresh the data files in the cloned datastore that is attached
20+
# to the target server.
21+
#
22+
# This script also assumes that all database files (data and log) are on the same volume/single VMDK. If multiple
23+
# volumes/VMDKs are being used, adjust the code to add additional foreach loops when manipulating the VMDKs.
24+
#
25+
# 2025/12/22: AYun - Renamed to "VMFS-VMDK Snapshot - V1.ps1" and migrated to archive in
26+
# PureStorage-OpenConnect\sqlserver-scripts\demos-archive\VMFS-VMDK Snapshot
27+
#
28+
# Disclaimer:
29+
# This example script is provided AS-IS and meant to be a building block to be adapted to fit an individual
30+
# organization's infrastructure.
31+
##############################################################################################################################
32+
33+
34+
35+
# Import powershell modules
36+
Import-Module PureStoragePowerShellSDK2
37+
Import-Module VMware.VimAutomation.Core
38+
Import-Module SqlServer
39+
40+
41+
42+
# Declare variables
43+
$TargetVM = 'SqlServer1' # Name of target VM
44+
$Databases = @('ExampleDb1','ExampleDb2') # Array of database names
45+
$TargetDiskSerialNumber = '6000c02022cb876dcd321example01b' # Target Disk Serial Number
46+
$VIServerName = 'vcenter.example.com' # vCenter FQDN
47+
$ClusterName = 'WorkloadCluster1' # VMware Cluster
48+
$SourceDatastoreName = 'vmware_sql_datastore' # VMware datastore name
49+
$SourceVMDKPath = 'SqlServer1_1/SqlServer1.vmdk' # VMDK path inside the VMFS datastore
50+
$ArrayName = 'flasharray1.example.com' # FlashArray FQDN
51+
$SourceVolumeName = 'sql_volume_1' # Source volume name on FlashArray (may be same as your datastore name)
52+
$TargetVolumeName = 'sql_volume_2' # Target volume name on FlashArray (may be same as your datastore name)
53+
54+
55+
56+
# Set Credential - this assumes the same credential for the target VM and vCenter
57+
$Credential = Get-Credential
58+
59+
60+
61+
# Create a Powershell session against the target VM
62+
$TargetVMSession = New-PSSession -ComputerName $TargetVM -Credential $Credential
63+
64+
65+
66+
# Connect to vCenter
67+
$VIServer = Connect-VIServer -Server $VIServerName -Protocol https -Credential $Credential
68+
69+
70+
71+
# Offline the target database(s) by looping through $Databases array
72+
foreach ($Database in $Databases) {
73+
$Query = "ALTER DATABASE [$Database] SET OFFLINE WITH ROLLBACK IMMEDIATE"
74+
Invoke-Sqlcmd -ServerInstance $TargetVM -Database master -Query $Query
75+
}
76+
77+
78+
79+
# Offline the volumes that have SQL data
80+
Invoke-Command -Session $TargetVMSession -ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using:TargetDiskSerialNumber } | Set-Disk -IsOffline $True }
81+
82+
83+
84+
# Prepare to remove the VMDK from the VM
85+
$VM = Get-VM -Server $VIServer -Name $TargetVM
86+
$HardDisk = Get-HardDisk -VM $VM | Where-Object { $_.FileName -match $SourceVMDKPath }
87+
88+
89+
90+
# Remove the VMDK from the VM
91+
Remove-HardDisk -HardDisk $HardDisk -Confirm:$false
92+
93+
94+
95+
# Prepare to remove the stale datastore
96+
$DataStore = $HardDisk.Filename.Substring(1, ($HardDisk.Filename.LastIndexOf(']') - 1))
97+
$Hosts = Get-Cluster $ClusterName | Get-VMHost | Where-Object { ($_.ConnectionState -eq 'Connected') }
98+
99+
100+
101+
# Guest hard disk removed, now remove the stale datastore - this can take a min or two
102+
Get-Datastore $DataStore | Remove-Datastore -VMHost $Hosts[0] -Confirm:$False
103+
104+
105+
106+
# Connect to the array, authenticate. Remember disclaimer at the top!
107+
$FlashArray = Connect-Pfa2Array -Endpoint $ArrayName -Credential ($Credential) -IgnoreCertificateError
108+
109+
110+
111+
# Perform the volume overwrite (no intermediate snapshot needed!)
112+
New-Pfa2Volume -Array $FlashArray -Name $TargetVolumeName -SourceName $SourceVolumeName -Overwrite $True
113+
114+
115+
116+
# Rescan storage on each ESX host in the $Hosts array
117+
foreach ($VmHost in $Hosts) {
118+
Get-VMHostStorage -RescanAllHba -RescanVmfs -VMHost $VmHost | Out-Null
119+
}
120+
121+
122+
123+
# Connect to EsxCli
124+
$esxcli = Get-EsxCli -VMHost $Hosts[0]
125+
126+
127+
128+
# Resignature the cloned datastore
129+
$EsxCli.Storage.Vmfs.Snapshot.Resignature($SourceDatastoreName)
130+
131+
132+
133+
# Find the assigned datastore name, this may take a few seconds
134+
# NOTE: when a datastore comes back, it's name will be "snap-[GUID chars]-[original DS name]"
135+
# This is why the wildcard match below is needed.
136+
$DataStore = (Get-Datastore | Where-Object { $_.Name -match 'snap' -and $_.Name -match $SourceDatastoreName })
137+
138+
139+
140+
# Rescan storage again to make sure all hosts can see the new datastore
141+
foreach ($VmHost in $Hosts) {
142+
Get-VMHostStorage -RescanAllHba -RescanVmfs -VMHost $VmHost | Out-Null
143+
}
144+
145+
146+
147+
# Attach the VMDK from the newly cloned datastore back to the target VM
148+
New-HardDisk -VM $VM -DiskPath "[$DataStore] $SourceVMDKPath"
149+
150+
151+
152+
# Online the volume on the target VM
153+
Invoke-Command -Session $TargetVMSession -ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using:TargetDiskSerialNumber } | Set-Disk -IsOffline $False }
154+
155+
156+
157+
# Volume might be read-only, ensure it's read/write
158+
Invoke-Command -Session $TargetVMSession -ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using:TargetDiskSerialNumber } | Set-Disk -IsReadOnly $False }
159+
160+
161+
162+
# Online the target database(s) by looping through $Databases array
163+
foreach ($Database in $Databases) {
164+
$Query = "ALTER DATABASE [$Database] SET ONLINE WITH ROLLBACK IMMEDIATE"
165+
Invoke-Sqlcmd -ServerInstance $TargetVM -Database master -Query $Query
166+
}
167+
168+
169+
170+
# Remove powershell session
171+
Remove-PSSession $TargetVMSession

0 commit comments

Comments
 (0)