1- # ############################################################################
1+ # #############################################################################################################################
22# ActiveDR - Non-Disruptive DR Test for SQL Server
33#
4- # Author: Andy Yun
5- # Written: 2023-05-10
6- # Updated: 2023-11-28
7- #
84# Scenario:
9- # Test failover only in DR. Do not impact Production
5+ # Test failover only in DR. Does not impact Production.
106#
11- # Single test database "ActiveDR_Example_DB" on two RDM volumes:
12- # data & log, on each SQL Server.
7+ # Single test database "ExampleDb" on two RDM volumes: data & log, on each SQL Server.
138#
149# Prerequisites:
15- # 1. DR Pod needs to be pre-created
16- # 2. Databases in DR Pod need to be "initialized" by being presented
17- # and attached to the DR SQL Server, then set offline
18- # 3. After Step 2 initialization, be sure to retrieve applicable
19- # DR disk serial numbers & substitute in code
20- # 4. On DR server, SQL Server service off. Service auto-start should
21- # be set to Manual as well.
10+ # 1. DR Pod needs to be pre-created
11+ # 2. Databases in DR Pod need to be "initialized" by being presented and attached to the DR SQL Server, then set offline
12+ # 3. After Step 2 initialization, be sure to retrieve applicable DR disk serial numbers & substitute in code
13+ # 4. On DR server, SQL Server service off. Service auto-start should be set to Manual as well.
2214#
2315# Usage Notes:
24- # This script is meant to be run in chunks. Break/exit commands have
25- # been added where appropriate.
26- #
27- # This example script is provided AS-IS and meant to be a building
28- # block to be adapted to fit an individual organization's
29- # infrastructure.
16+ # This script is meant to be run in chunks. Note the Part X headers. DO NOT run everything at once!
3017#
31- # ############################################################################
18+ # Disclaimer:
19+ # This example script is provided AS-IS and meant to be a building block to be adapted to fit an individual
20+ # organization's infrastructure.
21+ # #############################################################################################################################
3222
3323
3424
@@ -47,13 +37,13 @@ Import-Module SqlServer
4737# Set Variables
4838$ArrayName = " flasharray1.example.com" # DR FlashArray
4939$PodName = " ActiveDrPod" # Pod name on the DR FlashArray
50- $TargetSQLServer = " SqlServer1" # DR SQL Server
51- $DbName = " ExampleDb" # Name of database
40+ $DRSQLServer = " SqlServer1" # DR SQL Server
41+ $DatabaseName = " ExampleDb" # Name of database
5242
5343
5444
5545# Connect to DR SQL Server
56- $TargetSQLServerSession = New-PSSession - ComputerName $TargetSQLServer
46+ $DRSQLServerSession = New-PSSession - ComputerName $DRSQLServer
5747
5848
5949
@@ -77,7 +67,7 @@ Get-Pfa2Pod -Array $FlashArray -Name $PodName
7767# Because disk serial number can change between reboots, need to programmatically reference
7868# serial number to properly identify which disks to manipulate.
7969# Use Get-Disk to determine disk serial numbers
80- Invoke-Command - Session $TargetSQLServerSession - ScriptBlock { Get-Disk | Format-Table }
70+ Invoke-Command - Session $DRSQLServerSession - ScriptBlock { Get-Disk | Format-Table }
8171
8272
8373
@@ -88,31 +78,31 @@ $Disk2 = "6000c02022cb876dcd321example02b" # Serial Number of log disk
8878
8979
9080# Online the windows disks
91- Invoke-Command - Session $TargetSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk1 } | Set-Disk - IsOffline $False }
92- Invoke-Command - Session $TargetSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk2 } | Set-Disk - IsOffline $False }
81+ Invoke-Command - Session $DRSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk1 } | Set-Disk - IsOffline $False }
82+ Invoke-Command - Session $DRSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk2 } | Set-Disk - IsOffline $False }
9383
9484
9585
9686# Setting volumes to Read/Write
97- Invoke-Command - Session $TargetSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk1 } | Set-Disk - IsReadOnly $False }
98- Invoke-Command - Session $TargetSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk2 } | Set-Disk - IsReadOnly $False }
87+ Invoke-Command - Session $DRSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk1 } | Set-Disk - IsReadOnly $False }
88+ Invoke-Command - Session $DRSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk2 } | Set-Disk - IsReadOnly $False }
9989
10090
10191
10292# Confirm disks are online
103- Invoke-Command - Session $TargetSQLServerSession - ScriptBlock { Get-Disk | Format-Table }
93+ Invoke-Command - Session $DRSQLServerSession - ScriptBlock { Get-Disk | Format-Table }
10494
10595
10696
10797# Online the database
108- $Query = " ALTER DATABASE [$DbName ] SET ONLINE WITH ROLLBACK IMMEDIATE"
109- Invoke-Sqlcmd - ServerInstance $TargetSQLServer - Database master - Query $Query
98+ $Query = " ALTER DATABASE [$DatabaseName ] SET ONLINE WITH ROLLBACK IMMEDIATE"
99+ Invoke-Sqlcmd - ServerInstance $DRSQLServer - Database master - Query $Query
110100
111101
112102
113103# Confirm database online
114- $Query = " SELECT [name], [state_desc] FROM sys.databases WHERE [name] = '$DbName '"
115- Invoke-Sqlcmd - ServerInstance $TargetSQLServer - Database master - Query $Query
104+ $Query = " SELECT [name], [state_desc] FROM sys.databases WHERE [name] = '$DatabaseName '"
105+ Invoke-Sqlcmd - ServerInstance $DRSQLServer - Database master - Query $Query
116106
117107
118108
@@ -123,25 +113,25 @@ Invoke-Sqlcmd -ServerInstance $TargetSQLServer -Database master -Query $Query
123113
124114
125115# Offline the database
126- $Query = " ALTER DATABASE [$DbName ] SET OFFLINE WITH ROLLBACK IMMEDIATE"
127- Invoke-Sqlcmd - ServerInstance $TargetSQLServer - Database master - Query $Query
116+ $Query = " ALTER DATABASE [$DatabaseName ] SET OFFLINE WITH ROLLBACK IMMEDIATE"
117+ Invoke-Sqlcmd - ServerInstance $DRSQLServer - Database master - Query $Query
128118
129119
130120
131121# Confirm database offline
132- $Query = " SELECT [name], [state_desc] FROM sys.databases WHERE [name] = '$DbName '"
133- Invoke-Sqlcmd - ServerInstance $TargetSQLServer - Database master - Query $Query
122+ $Query = " SELECT [name], [state_desc] FROM sys.databases WHERE [name] = '$DatabaseName '"
123+ Invoke-Sqlcmd - ServerInstance $DRSQLServer - Database master - Query $Query
134124
135125
136126
137127# Offline the volume
138- Invoke-Command - Session $TargetSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk1 } | Set-Disk - IsOffline $True }
139- Invoke-Command - Session $TargetSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk2 } | Set-Disk - IsOffline $True }
128+ Invoke-Command - Session $DRSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk1 } | Set-Disk - IsOffline $True }
129+ Invoke-Command - Session $DRSQLServerSession - ScriptBlock { Get-Disk | Where-Object { $_.SerialNumber -eq $using :Disk2 } | Set-Disk - IsOffline $True }
140130
141131
142132
143133# Confirm disks are offline
144- Invoke-Command - Session $TargetSQLServerSession - ScriptBlock { Get-Disk | Format-Table }
134+ Invoke-Command - Session $DRSQLServerSession - ScriptBlock { Get-Disk | Format-Table }
145135
146136
147137
0 commit comments