DBA Tooling · FI-TS München · 2026

SQL Server AlwaysOn
Setup Tool

Vollautomatische Konfiguration von Availability Groups
auf Windows Server Failover Clustern

SQL Server 2022 / 2025 Windows Server 2022 PowerShell 5.1 WinForms GUI v1.0.0

Uwe Janke  ·  Senior SQL Server DBA  ·  dtcSoftware

Motivation

The Problem

AlwaysOn-Konfiguration manuell — ein fehleranfälliger Marathon.

⏱️

2–4 Stunden

Zeitaufwand für eine manuelle AG-Einrichtung — je nach Erfahrung des Bearbeiters

📋

Checklisten-Pflege

Jeder DBA hat seine eigene Word-Checklist. Kein einheitlicher Stand, keine Versionierung

🔄

Nicht reproduzierbar

Schritt vergessen? Falsche Portangabe? Endpoint schon vorhanden? — Fehler fallen spät auf

🔐

Kerberos / SPN-Falle

SPNs fehlen → Cannot generate SSPI context → AD-Team kontaktieren → warten → weitermachen

🧹

Cleanup nach Fehlversuch

WSFC-Gruppe hängt noch, Registry-Key blockiert Neuversuch — schwer zu finden ohne Erfahrung

📄

Keine Dokumentation

Was wurde konfiguriert? Welcher Failover-Modus? Welches Service-Konto? — Nachträglich kaum rekonstruierbar

Überblick

The Solution

Ein einziges Script — AlwaysOnSetup.ps1 — erledigt alle 9 Konfigurationsschritte vollautomatisch nach einmaliger Parameterprüfung.


🖥️

WinForms GUI

Cluster-Daten werden automatisch eingelesen. Kein Tippen nötig — nur prüfen und starten.

📝

Automatische Dokumentation

Cluster-Backup, vollständiges Log und SPN-Anforderungsdatei werden automatisch gespeichert.

🔁

Idempotent & robust

Kann bei Fehler neu gestartet werden. Bereinigt WSFC-Überreste automatisch.

VorherNachher
2–4 Stunden~20 Minuten
Checkliste Word/ExcelGUI mit Vorbelgung
Kein Log3 Dateien automatisch
SPN: AD-Team anrufensetspn-Datei generiert
Fehlversuch → manuell putzenAutomatischer WSFC-Cleanup
✓ Getestet auf Windows Server 2022 · SQL Server 2022 Enterprise & Standard · 2- und 3-Node-Cluster
Vorbereitung

Prerequisites

Das Tool konfiguriert — es baut nicht. Was vorher stehen muss:

Infrastruktur

WSFC bereits eingerichtet

Windows Server Failover Cluster mit 2 oder 3 Nodes

SQL Server installiert

Enterprise oder Standard auf allen Nodes, gleiche Version

Port 5022 offen

Zwischen allen Nodes für den HADR Mirroring Endpoint

Backup-Share erreichbar

UNC-Pfad beschreibbar von allen Nodes

Berechtigungen & Module

AnforderungHinweis
Lokaler AdministratorAuf dem ausführenden Node
SQL sysadminAuf allen Nodes
Domänen-LeserechtFür SPN-Prüfung (Schritt 9)
FailoverClustersWird automatisch installiert
dbaTools ≥ 2.0Wird automatisch installiert
⚡ Empfehlung SPNs vor dem Setup setzen — spart einen manuellen Zwischen­schritt. Details auf Slide 9.
Bedienung

The Interface

Cluster-Daten werden automatisch eingelesen. PropertyGrid links — Live-Log rechts.

🔷 SQL Server AlwaysOn Setup Tool v1.0.0
Konfiguration
① KONFIGURATION (PropertyGrid)
1 - Cluster
Cluster-Name
SQLCLUSTER01
Listener-Name
AG-LISTENER01
Listener-IP
10.0.1.50
Listener-Port
1433
2 - Nodes
Node 1
▶ SQLNODE01\MSSQLSERVER
SQL-Instanz
SQLNODE01\MSSQLSERVER
Hostname
SQLNODE01
AlwaysOn-Status
Disabled
Node 2
▶ SQLNODE02\MSSQLSERVER
Node 3
(leer)
3 - Availability Group
AG-Name
AG_PROD_01
Endpoint-Port
5022
Failover-Modus
Automatic ▾
Backup-Präferenz
Primary ▾
Test-Datenbank
AG_TestDB
4 - SQL Service-Konto
Dienst-Konto
HLB\svc-sql-prod
Kennwort
••••••••••••
④ PROTOKOLL (Live-Log)
[10:14:22] === Cluster- und SQL-Informationen einlesen ===
[10:14:22] Cluster gefunden: SQLCLUSTER01
[10:14:23] Nodes: SQLNODE01, SQLNODE02
[10:14:23] Listener: AG-LISTENER01 IP: 10.0.1.50 Port: 1433
[10:14:24] Eingelesen: SQLCLUSTER01 - OK
 
[10:15:01] === Schritt 2: HADR aktivieren ===
[10:15:03] SQLNODE01: HADR aktiviert - Dienst wird neu gestartet
[10:15:14] SQLNODE01: SQL Server wieder erreichbar
[10:15:14] SQLNODE02: HADR aktiviert - Dienst wird neu gestartet
[10:15:22] === Schritt 3: Endpoint erstellen ===
[10:15:23] SQLNODE01: Endpoint 'Hadr_endpoint' (5022) angelegt
[10:15:23] SQLNODE02: Endpoint 'Hadr_endpoint' (5022) angelegt
[10:15:24] === Schritt 6: Availability Group anlegen ===
[10:15:31] AG_PROD_01 erfolgreich angelegt ✓
[10:15:32] SPN MSSQLSvc/SQLNODE02:1433 fehlt - Bitte AD-Team informieren
⑥ AG_PROD_01 erfolgreich konfiguriert SPN-Datei: C:\System\WinSrvLog\MSSQL\AlwaysOn_SPN_ADTeam_20260513.txt
Ablauf

9-Step Workflow

Alle Schritte laufen sequenziell und protokolliert. Übersprungene Schritte werden im Log ausgewiesen.

1
Service-Konto
Optional · WMI
2
HADR aktivieren
sp_configure
3
Endpoint
Port 5022
4
CONNECT
GRANT
5
Test-DB
FULL + Backup
6
AG anlegen
T-SQL / sqlcmd
7
Listener
ALTER AG
8
Status
DMV-Check
9
SPN-Prüfung
AD-Team Datei
ℹ Schritt 1 optional Wenn kein Service-Konto-Wechsel nötig ist, wird Schritt 1 übersprungen. Das Tool erkennt den aktuellen Kontostand automatisch.
⚠ Pause möglich bei Schritt 4 Wenn Kerberos-Auth fehlschlägt (fehlende SPNs), pausiert das Tool und fordert zur manuellen SQL-Login-Anlage auf.
Deep Dive · Schritt 2

HADR Activation

AlwaysOn ist in SQL Server standardmäßig deaktiviert und muss auf jedem Node einzeln eingeschaltet werden.

1
sp_configure setzen

Auf allen Nodes: hadr enabled = 1 via Invoke-DbaQuery

2
Dienst-Neustart via WMI

Win32_Service.StopService() / StartService() — kein Restart-Computer nötig

3
Bereitschaftstest

SELECT 1 alle 2 Sek., max. 120 Sek. — erst dann weiter zu Schritt 3

ℹ Warum WMI statt Restart-Service? Restart-Service MSSQLSERVER prüft nicht ob der Dienst wirklich wieder bereit ist. WMI + aktiver Verbindungstest stellt sicher, dass SQL Server vollständig initialisiert ist, bevor Schritt 3 beginnt.
# Auf jedem Node:
Invoke-DbaQuery -SqlInstance $node `
  -Query "EXEC sp_configure 'hadr enabled',1;
           RECONFIGURE"

# WMI Dienst-Neustart
$svc = Get-WmiObject Win32_Service `
  -ComputerName $node `
  -Filter "Name='MSSQLSERVER'"
$svc.StopService()  # warten bis Stopped
$svc.StartService() # warten bis Running

# Bereitschaftstest (max. 120s)
$ok = $false
for ($i=0; $i -lt 60; $i++) {
  try {
    Invoke-DbaQuery -Query "SELECT 1"
    $ok = $true; break
  } catch { Start-Sleep 2 }
}
if (-not $ok) { throw "Timeout" }
Deep Dive · Schritt 6

AG Creation — Why sqlcmd?

Für CREATE AVAILABILITY GROUP wird bewusst sqlcmd direkt verwendet — nicht Invoke-DbaQuery.

⚠ Das dbaTools-Verbindungs-Cache-Problem Nach dem Dienst-Neustart in Schritt 2 hält dbaTools intern gecachte Verbindungsobjekte. Über diese erscheint sys.availability_groups noch leer — obwohl die AG bereits existiert. sqlcmd öffnet bei jedem Aufruf eine frische TCP-Verbindung und sieht den aktuellen Zustand.
ℹ dbaTools — bewusst minimaler Einsatz Nur Invoke-DbaQuery und Connect-DbaInstance werden genutzt. Alle anderen Operationen: direktes T-SQL, WMI oder FailoverClusters-Cmdlets.
# CREATE AVAILABILITY GROUP via sqlcmd
# -- frische Verbindung, kein dbaTools-Cache
$sql = @"
CREATE AVAILABILITY GROUP [$AgName]
WITH (AUTOMATED_BACKUP_PREFERENCE = PRIMARY)
FOR DATABASE [$TestDb]
REPLICA ON
  N'$node1' WITH (
    ENDPOINT_URL = 'TCP://$node1:5022',
    FAILOVER_MODE = AUTOMATIC,
    AVAILABILITY_MODE = SYNCHRONOUS_COMMIT),
  N'$node2' WITH (
    ENDPOINT_URL = 'TCP://$node2:5022',
    FAILOVER_MODE = AUTOMATIC,
    AVAILABILITY_MODE = SYNCHRONOUS_COMMIT);
"@

# sqlcmd direkt aufrufen
sqlcmd -S $node1 -E -Q $sql
Deep Dive · Schritt 4 + 9

Kerberos & SPN Handling

SPNs ermöglichen Kerberos-Auth. Fehlen sie, schlägt Windows-Auth mit Cannot generate SSPI context fehl.

SituationAblauf
SPNs gesetzt ✓Vollautomatisch — kein Eingriff
SPNs fehlen ✗Pause → T-SQL anzeigen → manuell → Weiter

Fallback-Mechanismus:

1
Tool erkennt SSPI-Fehler

Kerberos-Test schlägt fehl auf betroffenem Node

2
T-SQL-Block im Log

Temporäres Login — fertig zum Kopieren in SSMS

3
Manuell ausführen + Weiter

Tool prüft SQL-Auth, setzt mit allen Schritten fort

4
Automatisches Cleanup

Temporäres Login am Ende garantiert gelöscht

Benötigte SPNs

# Je Node – Kurzname und FQDN
setspn -S MSSQLSvc/SQLNODE01:1433 DOM\svc-sql
setspn -S MSSQLSvc/SQLNODE01.dom.com:1433 DOM\svc-sql

setspn -S MSSQLSvc/SQLNODE02:1433 DOM\svc-sql
setspn -S MSSQLSvc/SQLNODE02.dom.com:1433 DOM\svc-sql

# AG-Listener
setspn -S MSSQLSvc/AG-LISTENER:1433 DOM\svc-sql
setspn -S MSSQLSvc/AG-LISTENER.dom.com:1433 DOM\svc-sql

# Prüfung:
setspn -L DOM\svc-sql
✓ Schritt 9 generiert diese Befehle automatisch Datei: AlwaysOn_SPN_ADTeam_<Datum>.txt
Einfach an das AD-Team weitergeben.
Ausgaben

Output & Logging

Alle Dateien landen automatisch unter C:\System\WinSrvLog\MSSQL\ — keine manuelle Aktion nötig.

DateiInhaltZeitpunkt
AlwaysOn_ClusterSettings_<Datum>.txtCluster-Backup vor ÄnderungenSchritt 1
AlwaysOn_Setup_<Datum>.logVollständiges Text-LogAbschluss
AlwaysOn_Setup_<Datum>.rtfFarbiges Log (manuell)Manuell
AlwaysOn_SPN_ADTeam_<Datum>.txtsetspn-Befehle für AD-TeamSchritt 9

Log-Farbcodierung

=== Schritt 6: Availability Group anlegen ===
[10:15:25] CREATE AVAILABILITY GROUP [AG_PROD_01] ...
[10:15:31] AG_PROD_01 erfolgreich angelegt ✓
[10:15:32] ⚠ SPN MSSQLSvc/SQLNODE02:1433 fehlt
[10:15:45] ✗ Endpoint-Port 5022 bereits belegt
BlauAbschnittsüberschrift
GrünErfolg
GelbWarnung / Hinweis
RotFehler
Robustheit

WSFC Cleanup & Retry

Fehlgeschlagene Setup-Versuche hinterlassen WSFC-Überreste, die einen Neuversuch blockieren.


1
Prüfung vor AG-Anlage

Tool prüft ob WSFC-Gruppe für den AG-Namen bereits existiert

2
Stop + Remove-ClusterGroup

-RemoveResources -Force — vollständige Bereinigung

3
Registry-Bereinigung

HadrAgNameToldMap auf allen Nodes via Invoke-Command

4
Neuversuch sauber möglich

Kein manueller Eingriff nötig

# WSFC-Überreste prüfen und bereinigen
$existingGroup = Get-ClusterGroup `
  -Name $AgName -ErrorAction SilentlyContinue

if ($existingGroup) {
  Write-Log "Verwaiste WSFC-Gruppe gefunden – bereinige..."
  Stop-ClusterGroup -Name $AgName -Force
  Remove-ClusterGroup -Name $AgName `
    -RemoveResources -Force
}

# Registry auf allen Nodes bereinigen
$regKey = "HKLM:\Cluster\HadrAgNameToldMap"
Invoke-Command -ComputerName $allNodes {
  if (Test-Path $using:regKey) {
    Remove-ItemProperty -Path $using:regKey `
      -Name $using:AgName -ErrorAction SilentlyContinue
  }
}
Toolchain

Connection to sqmSQLTool

Das AlwaysOn Setup Tool richtet die AG ein. sqmSQLTool übernimmt danach den laufenden Betrieb.

Nach dem Setup — sqmSQLTool-Aufgaben

🏥

Monitoring einrichten

Invoke-sqmSplunkConfiguration — AG-Replikationsstatus, Sync-Health, Failover-Events an Splunk

🔐

SA-Obfuscation

Invoke-sqmSaObfuscation — SA-Account auf allen Nodes umbenennen, Standardangriffsfläche reduzieren

📜

Zertifikat anlegen

New-sqmSqlCertificate — Endpoint-Verschlüsselung mit eigenem SQL-Zertifikat absichern

Laufender Betrieb

🔎

AlwaysOn-Health-Check

Get-sqmServerSetting — regelmäßige Prüfung aller AG-Replicas auf Synchronisierungsstatus

💾

Backup-Management

Invoke-sqmUserDatabaseBackup — erkennt Read-Only Secondaries automatisch und überspringt sie

🐛

Deadlock-Analyse

Get-sqmDeadlockReport — AG-aware, liest nur vom Primary, stündliche Erfassung

sqmSQLTool — nächste Session SQLSetupTool — AG nach Neuinstallation DeadlockCollector — laufender Betrieb
Abgrenzung

Scope & Boundaries

Was das Tool bewusst nicht macht — und warum.

Außerhalb des Scope

AufgabeZuständigkeit
WSFC anlegenServer-Team / Failover-Cluster-Setup
DNS-Einträge für ListenerNetzwerk-Team
Firewall Port 5022Netzwerk-Team
SPNs setzenAD-Team (Tool liefert die Befehle)
SQL Server installierenSQLSetupTool
Produktivdatenbanken in AG aufnehmenManuell / Migration Tool

Designentscheidungen

ℹ Nur eine Test-Datenbank Das Tool nimmt eine Test-DB in die AG auf — um die Funktionsfähigkeit zu beweisen. Produktivdatenbanken werden danach manuell oder per SQLMigration-Tool hinzugefügt.
ℹ Kein GUI-Autostart Das Script wird per PowerShell gestartet (.\AlwaysOnSetup.ps1). Kein Installer, keine Registry-Einträge — bewusst einfach zu deployen.
✓ Alle Änderungen reversibel Cluster-Backup vor Schritt 1. HADR kann wieder deaktiviert werden. Temporäres Login wird immer entfernt.
Fehlerbehandlung

Troubleshooting

FehlermeldungUrsacheLösung
Cannot generate SSPI context SPNs fehlen im AD Manuellen SQL-Login-Schritt im Tool durchführen. Langfristig: AD-Team SPNs setzen lassen
WSFC group … already exists Überrest eines Fehlversuchs Tool bereinigt automatisch: Remove-ClusterGroup + Registry
Login failed for user AGSetup_… Mixed Mode deaktiviert oder Password-Policy Server Properties → Security → SQL Server and Windows Authentication mode
Backup-Verzeichnis nicht erreichbar UNC-Pfad ungültig / keine Schreibrechte Pfad im PropertyGrid korrigieren — muss von allen Nodes beschreibbar sein
Endpoint-Port 5022 belegt Bestehender Endpoint oder anderer Dienst SELECT * FROM sys.endpoints WHERE type=4 — Port im PropertyGrid anpassen
AG nach 60s nicht sichtbar SQL Server nicht vollständig bereit Tool wartet aktiv bis 120s. Danach Dienst manuell prüfen
Endpoint-Eigentümer ungültig Temporärer AGSetup_*-Login war Eigentümer und wurde gelöscht AUTHORIZATION auf Service-Konto gesetzt — tritt nicht mehr auf
✓ Endpoint-Eigentümer — wie es funktioniert Ohne AUTHORIZATION-Klausel setzt SQL Server den aktuell ausführenden Login als Endpoint-Eigentümer. Im SQL-Auth-Fallback (fehlende SPNs) wäre das der temporäre AGSetup_XXXXXXXX-Login — der am Ende von Schritt 9 gelöscht wird. Ergebnis: Endpoint existiert weiter, sein Eigentümer-Principal nicht mehr. Das Tool setzt daher explizit AUTHORIZATION [<ServiceKonto>] — oder sa als Fallback.
Zusammenfassung

Summary & Next Steps

Key Takeaways

2–4h → ~20 Minuten

Vollautomatischer Durchlauf nach einmaliger Parameterprüfung

Kerberos-Fallback eingebaut

Fehlende SPNs stoppen das Setup nicht — kontrollierter Workaround

Automatische Dokumentation

Cluster-Backup, Log, SPN-Datei — ohne Zusatzaufwand

Idempotent

WSFC-Cleanup erlaubt sauberen Neuversuch nach Fehler

Teil der Toolchain

Zusammen mit sqmSQLTool und SQLSetupTool vollständiger DBA-Workflow

Links & Ressourcen

GitHubgithub.com/JankeUwe/AlwaysOnSetup
DokuAlwaysOn_Doku.html
HandbuchAlwaysOn_Handbuch.docx
Websitewww.powershelldba.de

Nächste Präsentationen

SQLSetupTool — Standardisierte SQL-Installation sqmSQLTool — DBA-Toolbox (Monitoring, Backup, Analyse) DeadlockCollector — Automatische Deadlock-Erfassung ReportDeploymentTool — SSRS Massendeployment