Konfiguration einer Always On Availability Group mit PowerShell

Um Kosten zu senken, arbeiten viele Datenbankadministratoren mit Azure VM’s. Diese virtuelle Maschinen sparen hohe Hardware- und Administrationskosten von hochverfügbaren SQL Server Umgebungen ein und ermöglichen damit eine höhere Skalierbarkeit.

In diesem Artikel implementieren wir eine Hochverfügbarkeitsgruppe (mit End-to-End Verschlüsselung) mit PowerShell in einer Azure Umgebung. Ihre Always On Availability Gruppe wird mit folgenden Bestandteilen konfiguriert, die wir Ihnen im folgenden Artikel näher beschreiben werden:

  1. Virtuelles Netzwerk inkl. verschiedener Subnetze, sowie Front- & Backend Netze
  2. Domaincontroller mit Active Directory
  3. Zwei SQL Server VMs, die mittels Active Directory autorisiert werden
  4. Windows Failover-Cluster mit drei Knoten
  5. Verfügbarkeitsgruppen mit zwei Commit-Replikaten

Diese Konfiguration kommt nicht nur dem Punkt der Kosteneinsparung sehr entgegen, sie ermöglicht zudem die Einsparung von Rechenstunden, da Sie mit zwei synchronen Replikaten und Failover Clustern mit drei Knoten arbeiten.

Um Zeit zu sparen, richten wir die Hochverfügbarkeitsgruppe mit einem PowerShell Skript und nicht mit GUI ein. Hierfür müssen im Vorhinein folgende Vorkehrungen getroffen werden bevor wir starten:

  • Konfigurieren Sie sich (falls nicht bereits vorhanden) ein Azure Konto mit dem Abonnement “virtuelle Computer”
  • Installieren Sie Azure PowerShell Cmdlets
  • Eignen Sie sich im Vorhinein ein solides Grundwissen über Hochverfügbarkeitsgruppen an

Wir stellen nun eine Verbindung zu unserem Azure Abonnement her und konfigurieren das virtuelle Netzwerk.

1. Wir importieren zunächst über PowerShell das Azure Modul. Die PowerShell Sitzung verbinden wir im Nachgang mit unserem Azure Abonnement. Dafür verwenden wir folgendes Skript in PowerShell:

Import-Module "C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\Azure\Azure.psd1"
Get-AzurePublishSettingsFile
Import-AzurePublishSettingsFile <publishsettingsfilepath>

Der im Skript enthaltene Befehl Get-AzurePublishSettingsFile generiert automatisch ein Verwaltungszertifikat mit Azure und lädt es auf Ihren Computer herunter. Bei Durchführung öffnet sich ein Browserfenster, welches Sie nun auffordert sich in Ihrem Microsoft Konto einzuloggen und den Azure-Abonnement einzugeben.

  • Die vom PowerShell Skript heruntergeladene .publishsettings-Datei enthält alle notwendigen Informationen, die Sie zum Verwalten Ihres Azure-Abonnements benötigen.
  • Zu guter Letzt importieren Sie mit dem Befehl Import-AzurePublishSettingsFile das Azure Modul auf Ihren lokalen Computer.

2. Zum Erstellen Ihrer IT-Cloud-Infrastruktur müssen Sie nun einige Variablen definieren. Diese legen Sie bestenfalls im folgenden Skript fest:

$location = "West US"
$affinityGroupName = "test_group"
$affinityGroupDescription = "Test SQL HADR Affinity Group"
$affinityGroupLabel = "IaaS BI Affinity Group"
$networkConfigPath = "C:\scripts\Network.netcfg"
$virtualNetworkName = "test_network"
$storageAccountName = "<uniquestorageaccountname>"
$storageAccountLabel = "Test SQL HADR Storage Account"
$storageAccountContainer = "https://" + $storageAccountName + ".blob.core.windows.net/vhds/"
$winImageName = (Get-AzureVMImage | where {$_.Label -like "Windows Server 2008 R2 SP1*"} | sort PublishedDate -Descending)[0].ImageName
$sqlImageName = (Get-AzureVMImage | where {$_.Label -like "SQL Server 2012 SP1 Enterprise*"} | sort PublishedDate -Descending)[0].ImageName
$dcServerName = "test_server"
$dcServiceName = "<uniqueservicename>"
$availabilitySetName = "SQLHADR"
$vmAdminUser = "AzureAdmin"
$vmAdminPassword = "password"
$workingDir = "c:\scripts\"

Beachten Sie bei der Variablen-Definition folgende Gesichtspunkte:

  • Die Variablen $storageAccountName und $dcServiceName müssen eindeutig definiert sein, da sie verwendet werden, um Ihr Cloudspeicherkonto bzw. Ihren Cloudserver zu identifizieren.
  • Die Namen, die Sie für die Variablen $affinityGroupName und $virtualNetworkName angeben, werden im Konfigurationsdokument für virtuelle Netzwerke festgelegt, welches wir später verwenden.
  • $sqlImageName gibt den aktualisierten Namen des VM-Images an, welches das SQL Server 2012 Service Pack 1 Enterprise Edition enthält.
  • Wir verwenden password als durchgängiges Kennwort im gesamten Tutorial.

3. Nachfolgend erstellen wir eine Affinitätsgruppe mit folgendem Befehl:

New-AzureAffinityGroup `
    -Name $affinityGroupName `
    -Location $location `
    -Description $affinityGroupDescription `
    -Label $affinityGroupLabel

4. und erstellen ein virtuelles Netzwerk durch Importieren der Konfigurationsdatei:

Set-AzureVNetConfig `
    -ConfigurationPath $networkConfigPath

Die Konfigurationsdatei ist ein XML. Dokument mit dem virtuellen Netzwerk test_network und der Affinitätsgruppe test_group. Das virtuelle Netzwerk hat nun die IP Adresse 10.10.0.0/16 mit den Subnetzen 0.10.1.0/24 und 10.10.2.0/24. Unterschieden werden die Subnetze durch ein Frontend- und ein Backendsubnetz. Im Frontend Subnetz können Sie Clientanwendungen platzieren. Das hintere Subnetz eignet sich für die Einrichtung von SQL Server VMs.

<NetworkConfiguration xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
  <VirtualNetworkConfiguration>
    <Dns />
    <VirtualNetworkSites>
      <VirtualNetworkSite name="test_network" AffinityGroup="test_group">
        <AddressSpace>
          <AddressPrefix>10.10.0.0/16</AddressPrefix>
        </AddressSpace>
        <Subnets>
          <Subnet name="Front">
            <AddressPrefix>10.10.1.0/24</AddressPrefix>
          </Subnet>
          <Subnet name="Back">
            <AddressPrefix>10.10.2.0/24</AddressPrefix>
          </Subnet>
        </Subnets>
      </VirtualNetworkSite>
    </VirtualNetworkSites>
  </VirtualNetworkConfiguration>
</NetworkConfiguration>
```xml

5. Als nächstes erstellen wir ein Speicherkonto, welches der eben erstellen Affinitätsgruppe zugeordnet ist.

New-AzureStorageAccount `
    -StorageAccountName $storageAccountName `
    -Label $storageAccountLabel `
    -AffinityGroup $affinityGroupName
Set-AzureSubscription `
    -SubscriptionName (Get-AzureSubscription).SubscriptionName `
    -CurrentStorageAccount $storageAccountName

6. Nach dem Erstellen des Speicherkontos, erstellen wir nun einen Domänencontrollerserver in der Azure VM.

New-AzureVMConfig `
    -Name $dcServerName `
    -InstanceSize Medium `
    -ImageName $winImageName `
    -MediaLocation "$storageAccountContainer$dcServerName.vhd" `
    -DiskLabel "OS" |
    Add-AzureProvisioningConfig `
        -Windows `
        -DisableAutomaticUpdates `
        -AdminUserName $vmAdminUser `
        -Password $vmAdminPassword |
        New-AzureVM `
            -ServiceName $dcServiceName `
            –AffinityGroup $affinityGroupName `
            -VNetName $virtualNetworkName
  • New-AzureVMConfig erstellt eine VM-Konfiguration.
  • Add-AzureProvisioningConfig gibt die Konfigurationsparameter eines eigenständigen Windows-Servers an.
  • Add-AzureDataDisk fügt den Datenträger hinzu, den Sie zum Speichern von Active Directory-Daten verwenden. In diesem Fall ist keine Zwischenspeicherungsoption konfiguriert.
  • New-AzureVM erstellt die neue Azure-VM im Clouddienst.

7. Wir warten nun bis die neue VM vollständig bereitgestellt ist und laden zwischenzeitlich die Remotedesktopdatei in unser Arbeitsverzeichnis herunter. Mit dem Befehl while können wir den aktuellen Bereitstellungsstatus der Azure VM herausfinden. In der Regel dauert der Prozess eine Weile.

$VMStatus = Get-AzureVM -ServiceName $dcServiceName -Name $dcServerName

While ($VMStatus.InstanceStatus -ne "ReadyRole")
{
    write-host "Waiting for " $VMStatus.Name "... Current Status = " $VMStatus.InstanceStatus
    Start-Sleep -Seconds 15
    $VMStatus = Get-AzureVM -ServiceName $dcServiceName -Name $dcServerName
}

Get-AzureRemoteDesktopFile `
    -ServiceName $dcServiceName `
    -Name $dcServerName `
    -LocalPath "$workingDir$dcServerName.rdp"

Ist der Domänencontroller erfolgreich bereitgestellt, konfigurieren wir als nächstes die Active Directory Domäne auf ebendiesem Controller.

Konfiguration des Domänencontrollers

  1. Stellen Sie eine Verbindung zum Domänencontrollerserver her, indem Sie die Remotedesktopdatei starten. Verwenden Sie den Login des Computeradministrators, den Sie beim Erstellen der neuen VM angegeben haben.
  2. Öffnen Sie PowerShell im Administratormodus
  3. Führen Sie den folgenden DCPROMO.EXE- Befehl aus, um die Domäne corp.test.com mit den Datenverzeichnissen auf Laufwerk M einzurichten. Nach Abschluss des Befehls, wird die VM einem Neustart unterzogen.

    dcpromo.exe ` /unattend ` /ReplicaOrNewDomain:Domain ` /NewDomain:Forest ` /NewDomainDNSName:corp.test.com ` /ForestLevel:4 ` /DomainNetbiosName:CORP ` /DomainLevel:4 ` /InstallDNS:Yes ` /ConfirmGc:Yes ` /CreateDNSDelegation:No ` /DatabasePath:"C:\Windows\NTDS" ` /LogPath:"C:\Windows\NTDS" ` /SYSVOLPath:"C:\Windows\SYSVOL" ` /SafeModeAdminPassword:"password"

4. Stellen Sie die Verbindung zum Domänencontrollerserver wieder her, indem Sie die Remotedesktopdatei starten. Melden Sie sich dieses Mal als CORP\Administrator an .

5. Importieren Sie mittels PowerShell das Active Directory PowerShell-Modul mit dem folgenden Befehl:

Import-Module ActiveDirectory

6. Mit dem nachfolgenden Befehl New-ADUser fügen sie 3 Benutzer zur Domäne hinzu:

$pwd = ConvertTo-SecureString "password" -AsPlainText -Force
New-ADUser `
    -Name 'Install' `
    -AccountPassword  $pwd `
    -PasswordNeverExpires $true `
    -ChangePasswordAtLogon $false `
    -Enabled $true
New-ADUser `
    -Name 'SQLSvc1' `
    -AccountPassword  $pwd `
    -PasswordNeverExpires $true `
    -ChangePasswordAtLogon $false `
    -Enabled $true
New-ADUser `
    -Name 'SQLSvc2' `
    -AccountPassword  $pwd `
    -PasswordNeverExpires $true `
    -ChangePasswordAtLogon $false `
    -Enabled $true

CORP\Install wird verwendet, um alles zu konfigurieren, was mit den SQL Server-Dienstinstanzen, dem Failovercluster und der Verfügbarkeitsgruppe zu tun hat. CORP\SQLSvc1 und CORP\SQLSvc2 werden als SQL Server-Dienstkonten für die beiden SQL Server-VMs verwendet.

7. Als nächstes führen wir den eben beschriebenen Befehl CORP\Install aus, um Berechtigungen zum Erstellen von Computerobjekten in der Domäne zu erteilen .

Cd ad:
$sid = new-object System.Security.Principal.SecurityIdentifier (Get-ADUser "Install").SID
$guid = new-object Guid bf967a86-0de6-11d0-a285-00aa003049e2
$ace1 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"CreateChild","Allow",$guid,"All"
$corp = Get-ADObject -Identity "DC=corp,DC=test,DC=com"
$acl = Get-Acl $corp
$acl.AddAccessRule($ace1)
Set-Acl -Path "DC=corp,DC=test,DC=com" -AclObject $acl

Die oben angegebene GUID ist die GUID für den Computerobjekttyp. Um Active Directory Objekte für das Failovercluster zu erstellen, benötigt das Konto CORP\Install benötigt die Berechtigungen, “Alle Eigenschaften lesen” und “Computerobjekte erstellen” zu dürfen. Hier handelt es sich um die Standardkonfiguration, sodass Sie hier nichts aktiv einrichten müssen.

Nachdem wir die Konfiguration des Domänencontrollers und der Active Directory vorgenommen haben, erstellen wir im nächsten Schritt SQL Server VMs.

Erstellen einer SQL Server VM

1. Wie gewohnt, starten wir mit einem PowerShell Befehl in die Konfiguration einer SQL Server VM.

$domainName= "corp"
$FQDN = "corp.test.com"
$subnetName = "Back"
$sqlServiceName = "<uniqueservicename>"
$quorumServerName = "test_quorum"
$sql1ServerName = "test_SQL1"
$sql2ServerName = "test_SQL2"
$availabilitySetName = "SQLHADR"
$dataDiskSize = 100
$dnsSettings = New-AzureDns -Name "testBackDNS" -IPAddress "10.10.0.4"

Die IP Adresse 10.10.0.4 wird der ersten VM zugewiesen, die im Subnetz der Azure VM erstellt wurde. zum Gegenprüfen, ob diese mit der IP Adresse des Domänencontrollers übereinstimmt, verwenden Sie den Befehl IPCONFIG.

2. Als nächstes erstellen wir die erste VM im Failovercluster mit dem Namen: test_quorum 

New-AzureVMConfig `
    -Name $quorumServerName `
    -InstanceSize Medium `
    -ImageName $winImageName `
    -MediaLocation "$storageAccountContainer$quorumServerName.vhd" `
    -AvailabilitySetName $availabilitySetName `
    -DiskLabel "OS" |
    Add-AzureProvisioningConfig `
        -WindowsDomain `
        -AdminUserName $vmAdminUser `
        -Password $vmAdminPassword `
        -DisableAutomaticUpdates `
        -Domain $domainName `
        -JoinDomain $FQDN `
        -DomainUserName $vmAdminUser `
        -DomainPassword $vmAdminPassword |
        Set-AzureSubnet `
            -SubnetNames $subnetName |
            New-AzureVM `
                -ServiceName $sqlServiceName `
                –AffinityGroup $affinityGroupName `
                -VNetName $virtualNetworkName `
                -DnsSettings $dnsSettings

Auch hier gehen wir erneut auf die Einzelheiten des Befehls ein:

  • New-AzureVMConfig erstellt eine VM-Konfiguration mit dem gewünschten Namen. Die nachfolgenden VMs werden mit demselben Verfügbarkeitsgruppennamen erstellt und derselben Verfügbarkeitsgruppe hinzugefügt.
  • Add-AzureProvisioningConfig verbindet die VM mit der erstellten Active Directory-Domäne.
  • Set-AzureSubnet platziert die VM im hinteren Subnetz.
  • New-AzureVM erstellt eine neue Azure VM im neuen Clouddienst. Der Parameter DnsSettings gibt an, dass der DNS-Server für die Server die IP-Adresse des Domänencontrollers 10.10.0.4 hat. Dieser Parameter ist erforderlich, damit die neuen VMs erfolgreich der Active Directory-Domäne beitreten können. Ohne diesen Parameter müssen Sie die IPv4-Einstellungen in Ihrer VM manuell festlegen, um den Domänencontrollerserver nach der Bereitstellung der VM als primären DNS-Server zu verwenden und dann die VM mit der Active Directory-Domäne verbinden.

 3. Nachfolgend erstellen wir nun die SQL Server-VMs mit den Namen test_SQL1 und test_SQL2.

# Create test_SQL1...
New-AzureVMConfig `
    -Name $sql1ServerName `
    -InstanceSize Large `
    -ImageName $sqlImageName `
    -MediaLocation "$storageAccountContainer$sql1ServerName.vhd" `
    -AvailabilitySetName $availabilitySetName `
    -HostCaching "ReadOnly" `
    -DiskLabel "OS" |
    Add-AzureProvisioningConfig `
        -WindowsDomain `
        -AdminUserName $vmAdminUser `
        -Password $vmAdminPassword `
        -DisableAutomaticUpdates `
        -Domain $domainName `
        -JoinDomain $FQDN `
        -DomainUserName $vmAdminUser `
        -DomainPassword $vmAdminPassword |
        Set-AzureSubnet `
            -SubnetNames $subnetName |
            Add-AzureEndpoint `
                -Name "SQL" `
                -Protocol "tcp" `
                -PublicPort 1 `
                -LocalPort 1433 |
                New-AzureVM `
                    -ServiceName $sqlServiceName

# Create test_SQL2...
New-AzureVMConfig `
    -Name $sql2ServerName `
    -InstanceSize Large `
    -ImageName $sqlImageName `
    -MediaLocation "$storageAccountContainer$sql2ServerName.vhd" `
    -AvailabilitySetName $availabilitySetName `
    -HostCaching "ReadOnly" `
    -DiskLabel "OS" |
    Add-AzureProvisioningConfig `
        -WindowsDomain `
        -AdminUserName $vmAdminUser `
        -Password $vmAdminPassword `
        -DisableAutomaticUpdates `
        -Domain $domainName `
        -JoinDomain $FQDN `
        -DomainUserName $vmAdminUser `
        -DomainPassword $vmAdminPassword |
        Set-AzureSubnet `
            -SubnetNames $subnetName |
            Add-AzureEndpoint `
                -Name "SQL" `
                -Protocol "tcp" `
                -PublicPort 2 `
                -LocalPort 1433 |
                New-AzureVM `
                    -ServiceName $sqlServiceName
  • New-AzureVMConfig erstellt eine VM-Konfiguration mit dem gewünschten Namen. Die nachfolgenden VMs werden mit demselben Verfügbarkeitsgruppennamen erstellt und derselben Verfügbarkeitsgruppe hinzugefügt.Es nutzt das SQL Server 2012 Service Pack 1 Enterprise Edition-Image in den virtuellen Maschinen. Außerdem wird die Betriebssystemfestplatte auf read-only-Caching (kein Schreib-Caching) eingestellt. 
    -> Es wird empfohlen, die Datenbankdateien auf einen separaten Datenträger zu migrieren, den Sie an die VM anfügen ohne eine Lese- oder Schreibcache-Konfiguration. 
  • Add-AzureProvisioningConfig verbindet die VM mit der Active Directory-Domäne.
  • Set-AzureSubnet platziert die VM im hinteren Subnetz.
  • Add-AzureEndpoint fügt Zugriffsendpunkte hinzu, damit Clientanwendungen auf die SQL Server -Dienstinstanzen im Internet zugreifen können. test_SQL1 und test_SQL2 werden unterschiedlichen Ports zugewiesen.
  • New-AzureVM erstellt die neue SQL Server-VM im gleichen Clouddienst wie test_quorum. Sie müssen die VMs im selben Clouddienst platzieren, wenn sie sich in derselben Verfügbarkeitsgruppe befinden sollen.

4. Wir warten nun, bis jede VM vollständig bereitgestellt ist die ihre jeweilige Remote-Desktop-Datei in Ihr Arbeitsverzeichnis heruntergeladen hat. Der Befehl for durchläuft die drei neuen VMs und führt die Befehle innerhalb der oberen Klammern für jede von ihnen aus.

Foreach ($VM in $VMs = Get-AzureVM -ServiceName $sqlServiceName)
{
    write-host "Waiting for " $VM.Name "..."

    # Loop until the VM status is "ReadyRole"
    While ($VM.InstanceStatus -ne "ReadyRole")
    {
        write-host "  Current Status = " $VM.InstanceStatus
        Start-Sleep -Seconds 15
        $VM = Get-AzureVM -ServiceName $VM.ServiceName -Name $VM.InstanceName
    }

    write-host "  Current Status = " $VM.InstanceStatus

    # Download remote desktop file
    Get-AzureRemoteDesktopFile -ServiceName $VM.ServiceName -Name $VM.InstanceName -LocalPath "$workingDir$($VM.InstanceName).rdp"
}

Letztlich sind die SQL Server VMs nun bereitgestellt. Weiter geht es mit der Initialisierung der Failovercluster-VMs.

Initialisierung von Failovercluster VMs

In diesem Abschnitt müssen wir nun die drei Server ändern, die wir im Failovercluster und der SQL Server-Installation verwendet haben. 

  • Alle Server müssen die Failover-Clustering-Funktion installieren .
  • Alle Server müssen CORP\Install als Maschinenadministrator hinzufügen
  • test_SQL1 und test_SQL2 müssen CORP\Install als Systemadministratorrolle in der Standarddatenbank hinzufügen .
  • test_SQL1 und test_SQL2 müssen NT AUTHORITY\System als Anmeldung mit den folgenden Berechtigungen hinzufügen :
    • Ändern einer beliebigen Verfügbarkeitsgruppe
    • Verbinden mit SQL
    • Serverstatus anzeigen
  • test_SQL1 und test_SQL2 müssen das TCP-Protokoll auf der SQL Server-VM aktivieren. Sie müssen zusätzlich die Firewall für den Remotezugriff von SQL Server öffnen.

Wir starten mit test_quorum und führen die folgenden Schritte aus:

  1. Starten Sie eine Verbindung mit test_quorum durch die Remotedesktopdatei. Verwenden Sie den Login des Computeradministrators, den Sie beim Erstellen der VMs eingerichtet haben.
  2. Stellen Sie sicher, dass die Computer erfolgreich mit corp.test.comverbunden ist.
  3. Warten Sie, bis die SQL Server-Installation die Ausführung der automatisierten Initialisierungsaufgaben abgeschlossen hat.
  4. Öffnen Sie ein PowerShell-Fenster im Administratormodus.
  5. Installieren Sie die Windows-Failover-Clustering-Funktion.
Import-Module ServerManager
Add-WindowsFeature Failover-Clustering

6. Fügen Sie CORP\Install als lokalen Administrator hinzu.

net localgroup administrators "CORP\Install" /Add

7. Melden Sie sich von test_quorum mit folgendem Befehl ab. Die Arbeit auf diesem Server ist nun beendet.

logoff.exe

Initialisieren nun als Nächstes test_SQL1 und test_SQL2 und führen Sie folgende Schritte aus, die für beide SQL Server-VMs identisch sind.

  1. Stellen Sie eine Verbindung zu den beiden SQL Server-VMs durch die Remotedesktopdatei her. Verwenden Sie den Login des Computeradministrators, den Sie beim Erstellen der VMs eingerichtet haben.
  2. Stellen Sie sicher, dass die Computer erfolgreich mit corp.test.com verbunden ist.
  3. Warten Sie, bis die SQL Server-Installation die Ausführung der automatisierten Initialisierungsaufgaben abgeschlossen hat.
  4. Öffnen Sie ein PowerShell-Fenster im Administratormodus.
  5. Installieren Sie die Windows-Failover-Clustering-Funktion.
Import-Module ServerManager
Add-WindowsFeature Failover-Clustering

6. Fügen Sie CORP\Install als lokalen Administrator hinzu.

net localgroup administrators "CORP\Install" /Add

7. Importieren Sie den SQL Server PowerShell-Anbieter.

Set-ExecutionPolicy -Execution RemoteSigned -Force
Import-Module -Name "sqlps" -DisableNameChecking

8. Fügen Sie CORP\Install als Systemadministrator für die Standardinstanz von SQL Server hinzu.

net localgroup administrators "CORP\Install" /Add
Invoke-SqlCmd -Query "EXEC sp_addsrvrolemember 'CORP\Install', 'sysadmin'" -ServerInstance "."

9. Fügen Sie NT AUTHORITY\System als Anmeldung drei oben beschriebenen Berechtigungen hinzu.

Invoke-SqlCmd -Query "CREATE LOGIN [NT AUTHORITY\SYSTEM] FROM WINDOWS" -ServerInstance "."
Invoke-SqlCmd -Query "GRANT ALTER ANY AVAILABILITY GROUP TO [NT AUTHORITY\SYSTEM] AS SA" -ServerInstance "."
Invoke-SqlCmd -Query "GRANT CONNECT SQL TO [NT AUTHORITY\SYSTEM] AS SA" -ServerInstance "."
Invoke-SqlCmd -Query "GRANT VIEW SERVER STATE TO [NT AUTHORITY\SYSTEM] AS SA" -ServerInstance "."

10. Öffnen Sie die Firewall für den Remotezugriff

netsh advfirewall firewall add rule name='SQL Server (TCP-In)' program='C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Binn\sqlservr.exe' dir=in action=allow protocol=TCP

11. Melden Sie sich nun von allen VMs ab.

logoff.exe

In diesem Abschnitt haben wir nun das Failovercluster mit allen vorhandenen SQL Servern initialisiert und konfiguriert. Im nächsten Schritt erstellen wir eine Verfügbarkeitsgruppe.

Konfiguration einer Verfügbarkeitsgruppe

  1. Stellen Sie eine Verbindung mit test_SQL1 durch die Remotedesktopdatei her. Anstatt sich mit dem Computerkonto anzumelden, melden Sie sich mit CORP\Install an .
  2. Öffnen Sie ein PowerShell-Fenster im Administratormodus.
  3. Definieren Sie die folgenden Variablen:
$server1 = "test_SQL1"
$server2 = "test_SQL2"
$serverQuorum = "test_quorum"
$acct1 = "CORP\SQLSvc1"
$acct2 = "CORP\SQLSvc2"
$password = "password"
$clusterName = "test_cluster"
$timeout = New-Object System.TimeSpan -ArgumentList 0, 0, 30
$db = "test_db"
$backupShare = "\\$server1\backup"
$quorumShare = "\\$server1\quorum"
$ag = "AG1"

4. Importieren Sie nun den SQL PowerShell Anbieter:

Set-ExecutionPolicy RemoteSigned -Force
Import-Module "sqlps" -DisableNameChecking

5. Ändern Sie das SQL Server-Dienstkonto für test_SQL1 in CORP\SQLSvc1.

$wmi1 = new-object ("Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer") $server1
$wmi1.services | where {$_.Type -eq 'SqlServer'} | foreach{$_.SetServiceAccount($acct1,$password)}
$svc1 = Get-Service -ComputerName $server1 -Name 'MSSQLSERVER'
$svc1.Stop()
$svc1.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Stopped,$timeout)
$svc1.Start();
$svc1.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running,$timeout)

6. Selbiges machen Sie nun für test_SQL2. → CORP\SQLSvc2.

$wmi2 = new-object ("Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer") $server2
$wmi2.services | where {$_.Type -eq 'SqlServer'} | foreach{$_.SetServiceAccount($acct2,$password)}
$svc2 = Get-Service -ComputerName $server2 -Name 'MSSQLSERVER'
$svc2.Stop()
$svc2.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Stopped,$timeout)
$svc2.Start();
$svc2.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running,$timeout)

7. Laden Sie nun CreateAzureFailoverCluster.ps1 in das lokale Arbeitsverzeichnis herunter. Mithilfe dieses Skripts können Sie ein funktionsfähiges Failovercluster erstellen. 

8. Wechseln Sie in Ihr Arbeitsverzeichnis und erstellen Sie den Failovercluster mit dem heruntergeladenen Skript

Set-ExecutionPolicy Unrestricted -Force
.\CreateAzureFailoverCluster.ps1 -ClusterName "$clusterName" -ClusterNode "$server1","$server2","$serverQuorum"

9. Aktivieren Sie die AlwaysOn- Verfügbarkeitsgruppen für die SQL Server-Standardinstanzen auf test_SQL1 und test_SQL2.

Enable-SqlAlwaysOn `
    -Path SQLSERVER:\SQL\$server1\Default `
    -Force
Enable-SqlAlwaysOn `
    -Path SQLSERVER:\SQL\$server2\Default `
    -NoServiceRestart
$svc2.Stop()
$svc2.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Stopped,$timeout)
$svc2.Start();
$svc2.WaitForStatus([System.ServiceProcess.ServiceControllerStatus]::Running,$timeout)

10. Erstellen Sie nun ein Sicherungsverzeichnis und erteilen Sie Berechtigungen für die SQL Server-Dienstkonten. Sie verwenden dieses Verzeichnis, um eine Verfügbarkeitsdatenbank auf dem sekundären Replikat vorzubereiten.

$backup = "C:\backup"
New-Item $backup -ItemType directory
net share backup=$backup "/grant:$acct1,FULL" "/grant:$acct2,FULL"
icacls.exe "$backup" /grant:r ("$acct1" + ":(OI)(CI)F") ("$acct2" + ":(OI)(CI)F")

11. Erstellen Sie auf test_SQL1 eine Datenbank namens test_db. Erstellen Sie sowohl eine vollständige Sicherung als auch eine Protokollsicherung. Stellen Sie sie auf test_SQL2 mit der Option WITH NORECOVERY wieder her.

Invoke-SqlCmd -Query "CREATE database $db"
Backup-SqlDatabase -Database $db -BackupFile "$backupShare\db.bak" -ServerInstance $server1
Backup-SqlDatabase -Database $db -BackupFile "$backupShare\db.log" -ServerInstance $server1 -BackupAction Log
Restore-SqlDatabase -Database $db -BackupFile "$backupShare\db.bak" -ServerInstance $server2 -NoRecovery
Restore-SqlDatabase -Database $db -BackupFile "$backupShare\db.log" -ServerInstance $server2 -RestoreAction Log -NoRecovery

12. Erstellen Sie jetzt die Verfügbarkeitsgruppen-Endpunkte auf den SQL Server-VMs und legen Sie die Berechtigungen für die jeweiligen Endpunkte fest.

$endpoint =
  New-SqlHadrEndpoint MyMirroringEndpoint `
    -Port 5022 `
    -Path "SQLSERVER:\SQL\$server1\Default"
  Set-SqlHadrEndpoint `
    -InputObject $endpoint `
    -State "Started"
$endpoint =
  New-SqlHadrEndpoint MyMirroringEndpoint `
    -Port 5022 `
    -Path "SQLSERVER:\SQL\$server2\Default"
Set-SqlHadrEndpoint `
     -InputObject $endpoint `
     -State "Started"

Invoke-SqlCmd -Query "CREATE LOGIN [$acct2] FROM WINDOWS" -ServerInstance $server1
Invoke-SqlCmd -Query "GRANT CONNECT ON ENDPOINT::[MyMirroringEndpoint] TO [$acct2]" -ServerInstance $server1
Invoke-SqlCmd -Query "CREATE LOGIN [$acct1] FROM WINDOWS" -ServerInstance $server2
Invoke-SqlCmd -Query "GRANT CONNECT ON ENDPOINT::[MyMirroringEndpoint] TO [$acct1]" -ServerInstance $server2

13. Erstellen Sie die Verfügbarkeitsreplikate.

$primaryReplica =
   New-SqlAvailabilityReplica `
     -Name $server1 `
     -EndpointURL "TCP://$server1.corp.test.com:5022" `
     -AvailabilityMode "SynchronousCommit" `
     -FailoverMode "Automatic" `
     -Version 11 `
     -AsTemplate
$secondaryReplica =
   New-SqlAvailabilityReplica `
     -Name $server2 `
     -EndpointURL "TCP://$server2.corp.test.com:5022" `
     -AvailabilityMode "SynchronousCommit" `
     -FailoverMode "Automatic" `
     -Version 11 `
     -AsTemplate

14. Erstellen Sie abschließend die Verfügbarkeitsgruppe und fügen Sie das sekundäre Replikat der Verfügbarkeitsgruppe hinzu.

New-SqlAvailabilityGroup `
    -Name $ag `
    -Path "SQLSERVER:\SQL\$server1\Default" `
    -AvailabilityReplica @($primaryReplica,$secondaryReplica) `
    -Database $db
Join-SqlAvailabilityGroup `
    -Path "SQLSERVER:\SQL\$server2\Default" `
    -Name $ag
Add-SqlAvailabilityDatabase `
    -Path "SQLSERVER:\SQL\$server2\Default\AvailabilityGroups\$ag" `
    -Database $db

Fazit

Mit den vorangegangenen Schritten haben wir nun eine SQL Server Always On Availability Gruppe mit PowerShell in Azure erfolgreich implementiert.