Standardisierte, reproduzierbare SQL Server Installationen
nach Unternehmensstandard — vollautomatisch, domänenspezifisch
Uwe Janke · Senior SQL Server DBA · dtcSoftware
Manuelle SQL Server Installation — jedes Mal anders, jedes Mal fehleranfällig.
Manueller Aufwand je Installation — ohne Nachkonfiguration. Mit Härtung schnell 4+ Stunden
Laufwerksbelegung, Collation, TempDB-Größe variieren je Bearbeiter. Kein versionierter Stand
SA-Account aktiv, Max Memory nicht gesetzt, Ola-Jobs fehlen — Abweichungen fallen erst im Betrieb auf
HLB vs. CONTOSO: andere Collation, andere Laufwerke, andere Sysadmin-Gruppen — manuell gepflegt
Früher 57 einzelne SQL-Skripte manuell nachinstalliert. Kein Protokoll. Kein Fehler-Handling
Neue Umgebung? Alter DBA ist weg? — Kein Nachweis was installiert wurde und in welchem Zustand
Ein Tool, eine Konfiguration, ein Standard. Domäne einmal in der INI hinterlegen — danach läuft alles automatisch.
Kein PowerShell-Wissen nötig. Domänspezifische Vorbelegung, alle Parameter auf einem Blick
NTFS, MaxMemory, MAXDOP, TempDB, SA-Obfuscation, Ola-Jobs, Firmen-Scripts — vollautomatisch
INI-Block hinzufügen, kein Code anfassen. Alle Parameter domänenspezifisch überschreibbar
| Vorher | Nachher |
|---|---|
| 1–4 Stunden manuell | ~25–70 Min. vollautomatisch |
| Jedes Mal anders | Reproduzierbar, versioniert |
| Härtung vergessen | 17 Schritte garantiert |
| 57 SQL-Scripts manuell | Automatisch alphabetisch |
| Keine Domänen-Logik | INI-basiert, zero-touch |
| Anforderung | Hinweis |
|---|---|
| Lokaler Administrator | Auf dem Zielserver |
| 5 Laufwerke | C/F/G/H/I — per INI konfigurierbar |
| Netzwerk-Share erreichbar | \\srv\SQLSources |
dbaTools ≥ 2.0 | Wird automatisch installiert |
sqmSQLTool | Wird automatisch installiert |
| SQL Server ISO entpackt | Im SQLSources-Share vorbereitet |
Domänenspezifisch vorbelegt — Version, Collation, Laufwerke, Monitoring. Alles auf einem Formular.
Alle Phasen laufen sequenziell in einem Background-Thread — GUI bleibt jederzeit bedienbar.
robocopy \\srv\SQLSources\SQL2022 C:\SQLSources\SQL2022 /E /R:2 /W:5
Setup.exe und CU-Patch laufen stabiler von lokalem Laufwerk. Netzwerkunterbrechungen während des Setups vermieden
CU-Datei in \Updates\ wird von Install-DbaInstance automatisch als UpdateSourcePath verwendet
| Komponente | Installer |
|---|---|
| SSRS | SQLServerReportingServices.exe — eigenständig ab 2017 |
| SSAS | Im SQL-Setup via Feature AS aktiviert |
| SSMS | SSMS-Setup-ENU.exe — versionsneutral |
| SSIS | Feature IS im SQL-Engine-Setup (keine Extra-Datei) |
| TDP | setup.exe aus \TDP\ — versionsneutral |
Das Tool übergibt alle Parameter vollständig aus INI + GUI an Install-DbaInstance. Keine INI-Datei wird manuell erstellt.
| Parameter | Quelle |
|---|---|
Version | GUI ComboBox |
Edition | GUI ComboBox |
InstanceName | GUI TextBox |
Collation | INI / Domain-Override |
DataPath / LogPath | INI DiskLayout |
TempPath | INI DiskLayout |
BackupPath | INI DiskLayout |
UpdateSourcePath | \SQL_Install\Updates\ auto |
ProductID | INI SerialNumbers |
SqlSvcAccount | GUI Eingabe |
Features | INI + GUI Checkboxen |
# Slipstream CU automatisch erkennen $cuPath = Join-Path $localSrc 'SQL_Install\Updates' $cuFile = Get-ChildItem $cuPath '*.exe' ` -ErrorAction SilentlyContinue | Select-Object -First 1 # Install-DbaInstance Aufruf (Auszug) $params = @{ SqlInstance = 'localhost' Version = $ver Edition = $edition Path = $localSrc UpdateSourcePath = if ($cuFile) { $cuPath } else { $null } Collation = $collation DataPath = $paths.Data LogPath = $paths.Log TempPath = $paths.TempDB BackupPath = $paths.Backup Features = $features SqlSvcAccount = $svcAccount SqlSvcPassword = $svcPassword ProductID = $productKey PerformVolumeMaintenanceTasks = $true } Install-DbaInstance @params -Confirm:$false
PerformVolumeMaintenanceTasks = $true — SQL Server darf Volume ohne Zero-Fill allokieren. Deutlich schneller bei Dateioperationen.
Das Tool erkennt die Domäne automatisch beim Start und lädt domänenspezifische Vorgaben aus der INI — ohne Code-Änderung.
[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name — NetBIOS-Name extrahiert
Erst [DiskLayout_HLB], dann [DiskLayout_Standard] als Fallback
Domain_HLB = SQL_Latin1... — pro Key domänenspezifisch oder Standard-Fallback
Keine PowerShell-Änderung. Nur neuen [DiskLayout_XYZ] Block in settings.ini eintragen
# settings.ini (Auszug) [DiskLayout_Standard] DataDrive = G LogDrive = H TempDrive = I BackupDrive = F InstallDrive= C [Collations] Standard = Latin1_General_CI_AS Domain_HLB = SQL_Latin1_General_CP1_CI_AS Domain_CONTOSO = Latin1_General_CI_AS [SysadminGroups] Domain_HLB = HLB\Fg_DC_SqlAdminAll_Mod Domain_CONTOSO = CONTOSO\Rg_SQL_Sysadmin Standard = # leer = kein Sysadmin [Monitoring] Domain_HLB = 2 # Vollständig Domain_CONTOSO = 1 # Standard DefaultType = 1
Vollautomatisch nach der Installation. Jeder Schritt protokolliert, jeder Fehler abgefangen.
Früher 57 einzelne SQL-Skripte manuell nachinstalliert. Heute durch sqmSQLTool weitgehend abgedeckt — der Rest läuft automatisch.
| Früher (Skript) | Heute (sqmSQLTool) |
|---|---|
010_maxmemory.sql | Schritt 2 PostInstall |
020_maxdop.sql | Schritt 5 PostInstall |
030_ntfs.sql | Invoke-sqmNtfsSetup |
040_sa_rename.sql | Invoke-sqmSaObfuscation |
050_ola_jobs.sql | New-sqmOlaMaintenanceJobs |
| Firmen-Logins, LinkedServer | Schritt 17 (verbleibend) |
\\srv\SQLSources\Scripts\ — wird automatisch verwendet wenn SqlScriptsPath in settings.ini leer ist.
# Invoke-SqlScriptFolder — Ablauf $scripts = Get-ChildItem '\\srv\SQLSources\Scripts' ` -Filter '*.sql' | Sort-Object Name # Alphabetisch: 001_ bis 057_ foreach ($script in $scripts) { $sql = Get-Content $script.FullName -Raw # GO-Trenner: Batches aufteilen $batches = $sql -split '\r?\nGO\r?\n|\r?\nGO$' | Where-Object { $_.Trim() -ne '' } foreach ($batch in $batches) { try { Invoke-DbaQuery -SqlInstance $inst ` -Query $batch -ErrorAction Stop log " OK: $($script.Name)" } catch { log " WARN: $($script.Name) - $_" # ContinueOnError - naechstes Skript } } }
001_logins.sql, 002_linkedserver.sql — Reihenfolge über Dateiname steuerbar.
SA-Account ist das bekannteste Angriffsziel auf SQL Server. Das Tool verschleiert ihn automatisch — sicher, ohne manuellen Eingriff.
Domain-spezifische Gruppe aus INI. Mindestens eine Gruppe muss zugewiesen sein — sonst kein sysadmin mehr nach SA-Umbenennung
Invoke-sqmSaObfuscation: zufälliger Name, zufälliges 32-Zeichen Passwort. Name + Passwort nur im Rückgabeobjekt — sicher verwahren
| Angriff | Schutz |
|---|---|
Brute Force auf sa | Login heißt nicht mehr sa |
| Standard-Passwort | 32-Zeichen Zufalls-Passwort |
| SA bleibt aktiv | Gesperrter Login (disabled) |
| Kein Admin-Zugang | AD-Gruppe vor Umbenennung gesetzt |
[SysadminGroups] leer lassen = SA-Obfuscation wird übersprungen. Empfohlen: AD-Gruppe immer konfigurieren.
Get-sqmSQLInstanceCheck prüft nach allen PostInstall-Schritten ob die Instanz healthy ist.
Das Setup Tool richtet die Basis ein. sqmSQLTool übernimmt danach den laufenden Betrieb — AlwaysOnSetup die HA-Konfiguration.
New-sqmOlaUsrDbBackupJob — FULL/DIFF/LOG-Jobs. Bereits in PostInstall Schritt 15 angelegt
Invoke-sqmSplunkConfiguration — Monitoring-Key + Splunk-Forwarder. PostInstall Schritt 16
Deadlock-Analyse, Health-Checks, Zertifikat-Management — alles nach dem initialen Setup
AlwaysOnSetup setzt voraus dass SQL Server auf allen Nodes identisch installiert ist — genau das liefert das Setup Tool
1. SQLSetupTool auf Node 1 + Node 2 → 2. AlwaysOnSetup für AG-Konfiguration → 3. sqmSQLTool für laufenden Betrieb
Was das Tool bewusst nicht macht — und warum.
| Aufgabe | Zuständigkeit |
|---|---|
| Laufwerke formatieren / zuweisen | Server-Team |
| Windows Server installieren | Server-Team |
| DNS-Einträge | Netzwerk-Team |
| Produktivdatenbanken migrieren | SQLMigration Tool |
| AlwaysOn konfigurieren | AlwaysOnSetup Tool |
| Firewall-Regeln | Netzwerk-Team |
InplaceUpDate.
| Problem | Ursache | Lösung |
|---|---|---|
Install-DbaInstance Timeout |
Setup dauert länger als erwartet (CU-Patch) | dbaTools wartet aktiv — kein manueller Eingriff. Bei echtem Timeout: Log unter %TEMP%\dbatools |
| Robocopy fehlgeschlagen | Share nicht erreichbar oder keine Schreibrechte auf lokalem Laufwerk | UNC-Pfad in settings.ini prüfen. Laufwerk C: muss ausreichend Platz haben (~10 GB) |
| SA-Obfuscation übersprungen | Keine Sysadmin-Gruppe in [SysadminGroups] konfiguriert |
Domain-Eintrag in settings.ini ergänzen. SA bleibt dann aktiv — manuell sichern |
| SQL-Skript schlägt fehl (Schritt 17) | Syntax-Fehler, fehlendes Objekt, Berechtigungsproblem im Firmen-Script | ContinueOnError: restliche Skripte laufen weiter. Fehlschlager im Log als WARN sichtbar |
| Falsche Collation gesetzt | Domäne nicht erkannt — Standard-Fallback verwendet | Domain-Erkennung im Log prüfen. Ggf. Domain_XYZ Eintrag in settings.ini ergänzen |
| dbaTools Import fehlgeschlagen | PSGallery nicht erreichbar, ShareBasePath fehlt | Offline-Kopie unter [dbaTools] ShareBasePath in settings.ini konfigurieren |
4 Phasen vollautomatisch — Robocopy, Install-DbaInstance, Komponenten, Härtung
INI-Block hinzufügen — kein PowerShell-Code anfassen. Sofort einsatzbereit
NTFS, MaxMemory, MAXDOP, TempDB, SA-Obfuscation, Ola-Jobs, Firmen-Scripts
sqmSQLTool deckt den Großteil ab. Rest läuft als Step 17 automatisch
Einheitliche Basis für AlwaysOnSetup, sqmSQLTool, SQLMigration
| GitHub | github.com/JankeUwe/SQLSetupTool |
| Quellstruktur | New-SqlSourceStructure.ps1 |
| Website | www.powershelldba.de |