SQL 2012 HA Groups fully unattended
Hi all. As part of a XenDesktop 7.5 automated deployment, I have to deploy SQL 2012 silently. For redundancy needs, we use High Availability Groups. We also use the Managed Service Accounts brought by Windows 2008 R2. Here is the how-to.
Prerequisites
Set up a file share for quorum needs (here: \\SRVShare\QuorumShare).
Active Directory domain have to be set. In our case, we use Windows 2012 domain, but you may use Windows 2008 R2 domain level as Managed Service Accounts are supported since this release.
Reserve IPs for :
- WSFC cluster (here: 192.168.1.111).
- Availability Group Listener (here: 192.168.1.225).
Create an OU in your domain (here: SQLHA) where the cluster will create objects.
On all the future SQL servers (here: SQL1 and SQL2), install windows 2012R2 and add the features:
- Failover clustering
- RSAT/Feature Administration Tools/Failover Cluster management Tool
- Failover Cluster Module for Windows PowerShell
- ActiveDirectory-Powershell (only if you want to create MSA from SQL servers)
- .Net 3.5
For .Net 3.5, you have to specify the source in installation command line (there’s also a check box in the wizard):
Install-WindowsFeature -Name NET-Framework-Features -source D:\sources\sxs
With D:\ is windows media
Create and bind Managed Service Accounts
From each SQL Server, execute these PowerShell commands:
Import-Module ActiveDirectory New-ADServiceAccount -Name SQL2-SVC01 -RestrictToSingleComputer -Enabled $true Add-ADComputerServiceAccount -Identity SQL2 -ServiceAccount SQL2-SVC01$ Install-ADServiceAccount -Identity SQL2-SVC01$
Of course, SQL2 will be replace by SQL1 on the other server. You can also run these two commands from a domain controller.
Please note that despite Microsoft has released Group Managed Service Accounts, it is still not working with SQL 2012 (source: http://blogs.msdn.com/b/sqlosteam/archive/2014/02/19/msa-accounts-used-with-sql.aspx). So, we have to set up one MSA account for each server.
Create all instances
On each SQL servers, run an unattended installation with a configuration file :
D:\setup.exe /CONFIGURATIONFILE="configurationfileSQL1.ini"
Where D:\ is the SQL Server Enterprise Media. ConfigurationfileSQL.ini is joined to the end of this post. Feel free to edit it for your needs. You can also create your own by following an interactive setup of SQL. There’s an option at the end allowing you to save your INI file.
Reboot SQL servers!!!
Create a database
On the first SQL server, launch your SQL script to create a database.
sqlcmd -S SQL1\INSTANCE1 -i C:\Create_Database.sql
Create Windows Server Failover Cluster
Run the next PowerShell commands on one SQL server:
Import-Module failoverClusters #Optionally you can test your servers #Test-Cluster -Node @("SQL1") -Ignore network,inventory,storage #Test-Cluster -Node @("SQL2") -Ignore network,inventory,storage #Create cluster New-Cluster -Name SQLHA01 -Node @("SQL1","SQL2") -NoStorage -StaticAddress 192.168.1.111 #Set Quorum configuration Set-ClusterQuorum -NodeAndFileShareMajority \\SRVShare\QuorumShare
Allow Cluster to create object in destination OU
On one SQL server, run the following script. It will allow the cluster (SQLHA01$) to create objects in a specific OU (OU=SQLHA).
$ID = "Domain\SQLHA01$" #where SQLHA01 is the cluster name. $Path = "OU=SQLHA,DC=domain,DC=local" $ADSI = [ADSI]"LDAP://$Path" $NTAccount = New-Object System.Security.Principal.NTAccount($ID) $IdentityReference = $NTAccount.Translate([System.Security.Principal.SecurityIdentifier]) $ActiveDirectoryRights = "GenericAll" $AccessControlType = "Allow" $Inherit = "SelfAndChildren" $nullGUID = [guid]'00000000-0000-0000-0000-000000000000' $ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($IdentityReference,$ActiveDirectoryRights,$AccessControlType,$Inherit,$nullGUID) $ADSI.psbase.ObjectSecurity.SetAccessRule($ACE) $ADSI.psbase.commitchanges()
Sources :
http://www.theitjesus.com/use-powershell-to-add-permissions-to-ad-container-objects-for-machine-accounts-without-using-the-ad-module/
http://social.technet.microsoft.com/Forums/windowsserver/en-US/2fb86543-a6bc-4814-abb0-403816529c26/active-diretory-permissions-fail-with-setacl
ActiveDirectoryAccessRule : http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectoryaccessrule%28v=vs.110%29.aspx
activeDirectoryRights : http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectoryrights%28v=vs.110%29.aspx
AccessControlType : http://msdn.microsoft.com/en-us/library/w4ds5h86%28v=vs.110%29.aspx
Create SQL Availability Group
This script has to be run on the first SQL server:
import-Module sqlps # Backup my database and its log on the primary Backup-SqlDatabase ` -Database "MYDB" ` -BackupFile “\\Srv\BKPShare\MYDB.bak" ` -ServerInstance "SQL1\INSTANCE1" Backup-SqlDatabase ` -Database "MYDB" ` -BackupFile “\\Srv\BKPShare\MYDB.log" ` -ServerInstance "SQL1\INSTANCE1" ` -BackupAction Log # Restore the database and log on the secondary (using NO RECOVERY) Restore-SqlDatabase ` -Database "MYDB" ` -BackupFile “\\Srv\BKPShare\MYDB.bak" ` -ServerInstance "SQL2\INSTANCE1" ` -NoRecovery Restore-SqlDatabase ` -Database "MYDB" ` -BackupFile “\\Srv\BKPShare\MYDB.log" ` -ServerInstance "SQL2\INSTANCE1" ` -RestoreAction Log ` -NoRecovery # Create EndPoint (http://jamessql.blogspot.fr/2013/06/sql-server-2012-alwayson-availability_4738.html) $endpoint=New-SqlHADREndpoint -Port 5022 -Owner sa -Encryption Supported -EncryptionAlgorithm Aes -Name AlwaysonEndpoint -Path "SQLSERVER:\SQL\SQL1\INSTANCE1" Set-SqlHADREndpoint -InputObject $endpoint -State Started $endpoint=New-SqlHADREndpoint -Port 5022 -Owner sa -Encryption Supported -EncryptionAlgorithm Aes -Name AlwaysonEndpoint -Path "SQLSERVER:\SQL\SQL2\INSTANCE1" Set-SqlHADREndpoint -InputObject $endpoint -State Started #Grant SQL access to MSA sqlcmd -S SQL1\INSTANCE1 -i c:\GRANTConnectSQL1.sql sqlcmd -S SQL2\INSTANCE1 -i c:\GRANTConnectSQL2.sql # Create an in-memory representation of the primary replica. $primaryReplica = New-SqlAvailabilityReplica ` -Name "SQL1\INSTANCE1" ` -EndpointURL "TCP://SQL1.domain.local:5022" ` -AvailabilityMode "SynchronousCommit" ` -FailoverMode "Automatic" ` -Version 11 ` -AsTemplate # Create an in-memory representation of the secondary replica. $secondaryReplica = New-SqlAvailabilityReplica ` -Name "SQL2\INSTANCE1" ` -EndpointURL "TCP://SQL2.domain.local:5022" ` -AvailabilityMode "SynchronousCommit" ` -FailoverMode "Automatic" ` -Version 11 ` -AsTemplate #Enable Sql AlwaysOn Enable-SqlAlwaysOn -Path "SQLSERVER:\SQL\SQL1\INSTANCE1" -Force Enable-SqlAlwaysOn -Path "SQLSERVER:\SQL\SQL2\INSTANCE1" -Force # Create the availability group New-SqlAvailabilityGroup ` -Name "MyAG" ` -Path "SQLSERVER:\SQL\SQL1\INSTANCE1" ` -AvailabilityReplica @($primaryReplica,$secondaryReplica) ` -Database "MYDB" # Join the secondary replica to the availability group. Join-SqlAvailabilityGroup -Path "SQLSERVER:\SQL\SQL2\INSTANCE1\AvailabilityGroups" -Name "MyAG" # Join the secondary database to the availability group. Add-SqlAvailabilityDatabase -Path "SQLSERVER:\SQL\SQL2\INSTANCE1\AvailabilityGroups\MyAG" -Database "MYDB" #Create listener New-SqlAvailabilityGroupListener -Name SQLHAList -StaticIp '192.168.1.225/255.255.255.0' -Path "SQLSERVER:\SQL\SQL1\INSTANCE1\AvailabilityGroups\MyAG"
Since we use 2 different MSA, we need to allow each account to interact with the other server. In this script, you have to execute 2 SQL scripts:
GrantConnectSQL1.sql:
create login [Domain\SQL2-SVC01$] from windows; GRANT CONNECT ON ENDPOINT::AlwaysonEndpoint TO [Domain\SQL2-SVC01$];
GrantConnectSQL2.sql:
create login [Domain\SQL1-SVC01$] from windows;
GRANT CONNECT ON ENDPOINT::AlwaysonEndpoint TO [Domain\SQL1-SVC01$];
That’s it. Feel free to comment or correct, I’ll be glad to improve the how-to for the next readers.
Jerome
PS : It’s quite long but here is the ConfigurationFile.ini used to install SQL on both servers:
;SQL Server 2012 Configuration File [OPTIONS] ;EULA Acceptation IACCEPTSQLSERVERLICENSETERMS="True" ; Specifies a Setup work flow, like INSTALL, UNINSTALL, or UPGRADE. This is a required parameter. ACTION="Install" ; Detailed help for command line argument ENU has not been defined yet. ENU="True" ; Parameter that controls the user interface behavior. Valid values are Normal for the full UI,AutoAdvance for a simplied UI, and EnableUIOnServerCore for bypassing Server Core setup GUI block. ;UIMODE="Normal" ; Setup will not display any user interface. QUIET="True" ; Setup will display progress only, without any user interaction. QUIETSIMPLE="False" ; Specify whether SQL Server Setup should discover and include product updates. The valid values are True and False or 1 and 0. By default SQL Server Setup will include updates that are found. UpdateEnabled="False" ; Specifies features to install, uninstall, or upgrade. The list of top-level features include SQL, AS, RS, IS, MDS, and Tools. The SQL feature will install the Database Engine, Replication, Full-Text, and Data Quality Services (DQS) server. The Tools feature will install Management Tools, Books online components, SQL Server Data Tools, and other shared components. FEATURES=SQLENGINE,REPLICATION,FULLTEXT,DQ,SSMS,ADV_SSMS ; Specify the location where SQL Server Setup will obtain product updates. The valid values are "MU" to search Microsoft Update, a valid folder path, a relative path such as .\MyUpdates or a UNC share. By default SQL Server Setup will search Microsoft Update or a Windows Update service through the Window Server Update Services. UpdateSource="MU" ; Displays the command line parameters usage HELP="False" ; Specifies that the detailed Setup log should be piped to the console. INDICATEPROGRESS="False" ; Specifies that Setup should install into WOW64. This command line argument is not supported on an IA64 or a 32-bit system. X86="False" ; Specify the root installation directory for shared components. This directory remains unchanged after shared components are already installed. INSTALLSHAREDDIR="C:\Program Files\Microsoft SQL Server" ; Specify the root installation directory for the WOW64 shared components. This directory remains unchanged after WOW64 shared components are already installed. INSTALLSHAREDWOWDIR="C:\Program Files (x86)\Microsoft SQL Server" ; Specify a default or named instance. MSSQLSERVER is the default instance for non-Express editions and SQLExpress for Express editions. This parameter is required when installing the SQL Server Database Engine (SQL), Analysis Services (AS), or Reporting Services (RS). INSTANCENAME="INSTANCE1" ; Specify that SQL Server feature usage data can be collected and sent to Microsoft. Specify 1 or True to enable and 0 or False to disable this feature. SQMREPORTING="False" ; Specify the Instance ID for the SQL Server features you have specified. SQL Server directory structure, registry structure, and service names will incorporate the instance ID of the SQL Server instance. INSTANCEID="INSTANCE1" ; Specify if errors can be reported to Microsoft to improve future SQL Server releases. Specify 1 or True to enable and 0 or False to disable this feature. ERRORREPORTING="False" ; Specify the installation directory. INSTANCEDIR="C:\Program Files\Microsoft SQL Server" ; Agent account name AGTSVCACCOUNT="NT Service\SQLAgent$DOMAIN" ; Auto-start service after installation. AGTSVCSTARTUPTYPE="Manual" ; CM brick TCP communication port COMMFABRICPORT="0" ; How matrix will use private networks COMMFABRICNETWORKLEVEL="0" ; How inter brick communication will be protected COMMFABRICENCRYPTION="0" ; TCP port used by the CM brick MATRIXCMBRICKCOMMPORT="0" ; Startup type for the SQL Server service. SQLSVCSTARTUPTYPE="Automatic" ; Level to enable FILESTREAM feature at (0, 1, 2 or 3). FILESTREAMLEVEL="0" ; Set to "1" to enable RANU for SQL Server Express. ENABLERANU="False" ; Specifies a Windows collation or an SQL collation to use for the Database Engine. SQLCOLLATION="Latin1_General_CI_AS_KS" ; Account for SQL Server service: Domain\User or system account. SQLSVCACCOUNT="DOMAIN\SQL2-SVC01$" ; Windows account(s) to provision as SQL Server system administrators. SQLSYSADMINACCOUNTS="DOMAIN\administrator" ; Provision current user as a Database Engine system administrator for SQL Server 2012 Express. ADDCURRENTUSERASSQLADMIN="False" ; Specify 0 to disable or 1 to enable the TCP/IP protocol. TCPENABLED="1" ; Specify 0 to disable or 1 to enable the Named Pipes protocol. NPENABLED="0" ; Startup type for Browser Service. BROWSERSVCSTARTUPTYPE="Automatic" ; Add description of input argument FTSVCACCOUNT FTSVCACCOUNT="NT Service\MSSQLFDLauncher$INSTANCE1"