DBA Tooling · FI-TS Munich · 2026

SQL Server
Setup Tool

Standardized, reproducible SQL Server installations
following a company standard - fully automatic, domain-aware

SQL Server 2019 / 2022 / 2025 Windows Server 2022 PowerShell 5.1 dbatools 2.x WinForms GUI

Uwe Janke  ·  Senior SQL Server DBA  ·  dtcSoftware

Motivation

The Problem

Manual SQL Server installation - different every time, error-prone every time.

⏱️

1-3 hours

Manual effort per installation - without any post-configuration. With hardening, quickly 4+ hours

🗂️

No consistent standard

Drive layout, collation, TempDB size vary by operator. No versioned baseline

🔐

Hardening forgotten

SA account active, max memory not set, Ola jobs missing - deviations only surface in production

🏢

Domain differences

HLB vs. CONTOSO: different collation, different drives, different sysadmin groups - maintained manually

📋

57 company scripts

Previously 57 individual SQL scripts installed manually afterward. No log. No error handling

🔄

Not reproducible

A new environment? The previous DBA has left? - No evidence of what was installed and in what state

Overview

The Solution

One tool, one configuration, one standard. Set the domain once in the INI - everything else runs automatically afterward.


🖥️

WinForms GUI

No PowerShell knowledge needed. Domain-specific pre-filled values, all parameters visible at a glance

🔒

17-step PostInstall hardening

NTFS, MaxMemory, MAXDOP, TempDB, SA obfuscation, Ola jobs, company scripts - fully automatic

🏢

Zero-touch for new domains

Add an INI block, no code changes. Every parameter can be overridden per domain

BeforeAfter
1-4 hours manual~25-70 min. fully automatic
Different every timeReproducible, versioned
Hardening forgotten17 steps guaranteed
57 SQL scripts manuallyAutomatic, alphabetical
No domain logicINI-based, zero-touch
✓ Tested on Windows Server 2022 · SQL Server 2019, 2022, 2025 · HLB and CONTOSO domains
Preparation

Prerequisites & Source Structure

Prerequisites

RequirementNote
Local administratorOn the target server
5 drivesC/F/G/H/I - configurable via INI
Network share reachable\\srv\SQLSources
dbatools ≥ 2.0Installed automatically
sqmSQLToolInstalled automatically
SQL Server ISO extractedPrepared in the SQLSources share
ℹ New-SqlSourceStructure.ps1 Creates the complete SQLSources folder tree automatically - with a README.txt in every folder.

SQLSources Structure

\\srv\SQLSources\ ├── SQL2022\ │ ├── SQL_Install\ ← extracted ISO │ │ └── Updates\ ← current CU (.exe) │ ├── Reporting\ ← SSRS installer │ └── Management\ ← SSMS installer ├── SQL2019\ ← same structure ├── SQL2025\ ← same structure ├── Scripts\ ← company SQL scripts └── TDP\ ← IBM Spectrum Protect
Operation

The Interface

Pre-filled per domain - version, collation, drives, monitoring. Everything on a single form.

⚙️ SQL Server Setup - Standardized Installation
① SQL Server Version & Edition
Version:
2022
   Edition:
Developer
    🏢 Domain: HLB
② Instance Name
Instance name:
MSSQLServer
 
Default
 (empty / MSSQLServer = default instance)
③ Collation
Collation:
SQL_Latin1_General_CP1_CI_AS
  ✓ Domain collation active (HLB standard)
④ Service Account  (empty = NT SERVICE\MSSQLSERVER)
Account (DOMAIN\User):
HLB\svc-sql-prod
 
Check AD
Password:
••••••••
 ⚠️ AD check counts toward the lockout policy!
⑤ Disk Layout  Domain HLB · from INI
Install:
C:
Data:
G:
Log:
H:
TempDB:
I:
Backup:
F:
⑥ Monitoring
Monitoring type:
Full
⑦ Optional Components
SSRS
SSAS
SSMS
SSIS
TDP
⑧ Actions
Copy sources
Start installation
Close
⑨ Log
[09:42:11]Configuration loaded. Domain: HLB · Collation: SQL_Latin1_General_CP1_CI_AS [09:43:05]Phase 1: Robocopy started - \\srv\SQLSources\SQL2022 → C:\SQLSources\SQL2022 [09:48:32]Phase 1 complete. 4.2 GB copied in 327 sec. [09:48:35]Phase 2: Install-DbaInstance SQL Server 2022 Developer ...
Phase 2 - SQL Server installation running ... please wait
Workflow

4-Phase Workflow

All phases run sequentially in a background thread - the GUI stays usable at all times.

1
Source preparation
Robocopy
5-15 min.
2
SQL Server install
Install-DbaInstance
10-25 min.
3
Opt. components
SSAS/SSRS/SSMS/TDP
0-20 min.
4
PostInstall
17 steps
3-8 min.

Phase 1 - Robocopy

Local copy from the share

robocopy \\srv\SQLSources\SQL2022 C:\SQLSources\SQL2022 /E /R:2 /W:5

Why local?

Setup.exe and the CU patch run more stably from a local drive. Avoids network interruptions during setup

Slipstream CU

The CU file in \Updates\ is automatically used by Install-DbaInstance as the UpdateSourcePath

Phase 3 - Optional Components

ComponentInstaller
SSRSSQLServerReportingServices.exe - standalone since 2017
SSASEnabled in the SQL setup via the AS feature
SSMSSSMS-Setup-ENU.exe - version-independent
SSISFeature IS in the SQL engine setup (no extra file)
TDPsetup.exe from \TDP\ - version-independent
Deep Dive · Phase 2

Install-DbaInstance - Parameters & Slipstream

The tool passes all parameters fully from the INI + GUI to Install-DbaInstance. No INI file is created manually.

ParameterSource
VersionGUI combo box
EditionGUI combo box
InstanceNameGUI text box
CollationINI / domain override
DataPath / LogPathINI DiskLayout
TempPathINI DiskLayout
BackupPathINI DiskLayout
UpdateSourcePath\SQL_Install\Updates\ auto
ProductIDINI SerialNumbers
SqlSvcAccountGUI input
FeaturesINI + GUI checkboxes
# Detect the slipstream CU automatically
$cuPath = Join-Path $localSrc 'SQL_Install\Updates'
$cuFile = Get-ChildItem $cuPath '*.exe' `
           -ErrorAction SilentlyContinue |
           Select-Object -First 1

# Install-DbaInstance call (excerpt)
$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
✓ Instant File Initialization PerformVolumeMaintenanceTasks = $true - lets SQL Server allocate volume space without zero-filling. Noticeably faster for file operations.
Deep Dive · Configuration

Domain Detection & INI Logic

The tool detects the domain automatically at startup and loads domain-specific defaults from the INI - with no code changes.

1
Detect the domain

[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name - the NetBIOS name is extracted

2
Look up the INI section

First [DiskLayout_HLB], then [DiskLayout_Standard] as a fallback

3
Collation, monitoring, groups

Domain_HLB = SQL_Latin1... - per-key domain-specific or a standard fallback

4
New domain = INI only

No PowerShell changes. Just add a new [DiskLayout_XYZ] block to settings.ini

# settings.ini (excerpt)
[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       =   # empty = no sysadmin

[Monitoring]
Domain_HLB     = 2  # Full
Domain_CONTOSO = 1  # Standard
DefaultType    = 1
Deep Dive · Phase 4

PostInstall - 17 Steps

Fully automatic after the installation. Every step logged, every error caught.

1
NTFS permissions
2
Max server memory (90%)
3
Optimize for ad hoc
4
Cost threshold = 50
5
MAXDOP (CPU-based)
6
SQL Agent autostart
7
Optimize TempDB
8
Recovery model FULL
9
Disable SQL Browser
10
AD sysadmin groups
11
SA obfuscation
12
Monitoring key
13
Instance validation
14
Custom PostInstall.ps1
15
Ola Hallengren install
16
Configure Splunk
17
Company SQL scripts *.sql
ℹ Step 7 - TempDB File count is CPU-based (max. 8), size from the INI. No later manual adjustment needed.
✓ Step 17 - new Replaces the old 57 manual SQL scripts. Alphabetical, GO separators, ContinueOnError.
Deep Dive · Step 17

Company SQL Scripts - From 57 to Few

Previously 57 individual SQL scripts installed manually afterward. Today largely covered by sqmSQLTool - the rest runs automatically.

Before (script)Today (sqmSQLTool)
010_maxmemory.sqlPostInstall step 2
020_maxdop.sqlPostInstall step 5
030_ntfs.sqlInvoke-sqmNtfsSetup
040_sa_rename.sqlInvoke-sqmSaObfuscation
050_ola_jobs.sqlNew-sqmOlaMaintenanceJobs
Company logins, linked serverStep 17 (remaining)
ℹ Default path \\srv\SQLSources\Scripts\ - used automatically when SqlScriptsPath is empty in settings.ini.
# Invoke-SqlScriptFolder - flow
$scripts = Get-ChildItem '\\srv\SQLSources\Scripts' `
            -Filter '*.sql' | Sort-Object Name

# Alphabetical: 001_ through 057_
foreach ($script in $scripts) {
  $sql = Get-Content $script.FullName -Raw

  # GO separator: split into batches
  $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 - move to the next script
    }
  }
}
⚡ Recommended naming 001_logins.sql, 002_linkedserver.sql - the order is controlled via the filename.
Deep Dive · Steps 10-11

SA Obfuscation & Sysadmin Groups

The SA account is the best-known attack target on SQL Server. The tool obfuscates it automatically - safely, with no manual intervention.

10
AD group into the sysadmin role

Domain-specific group from the INI. At least one group must be assigned - otherwise no sysadmin access remains after renaming SA

11
Rename SA + password

Invoke-sqmSaObfuscation: a random name, a random 32-character password. Name + password only appear in the return object - keep them safe

⚠ Built-in safety net If no AD group could be assigned, SA obfuscation is automatically skipped - no possible loss of access.
AttackProtection
Brute force on saLogin is no longer named sa
Default password32-character random password
SA stays activeLogin is locked (disabled)
No admin accessAD group set before renaming
ℹ Only if an AD group is assigned Leaving [SysadminGroups] empty = SA obfuscation is skipped. Recommendation: always configure an AD group.
✓ Step 13 - Validation Get-sqmSQLInstanceCheck checks after all PostInstall steps whether the instance is healthy.
Toolchain

Connection to sqmSQLTool & AlwaysOn

The Setup Tool sets up the foundation. sqmSQLTool then takes over day-to-day operations - AlwaysOnSetup handles the HA configuration.

After setup - sqmSQLTool tasks

💾

Backup jobs

New-sqmOlaUsrDbBackupJob - FULL/DIFF/LOG jobs. Already created in PostInstall step 15

🏥

Monitoring & Splunk

Invoke-sqmSplunkConfiguration - monitoring key + Splunk forwarder. PostInstall step 16

📜

Ongoing operations

Deadlock analysis, health checks, certificate management - all after the initial setup

AlwaysOn After Setup

🔷

Prerequisite: the same base

AlwaysOnSetup requires SQL Server to be installed identically on all nodes - exactly what the Setup Tool delivers

🔄

Typical workflow

1. SQLSetupTool on node 1 + node 2 → 2. AlwaysOnSetup for AG configuration → 3. sqmSQLTool for ongoing operations

ℹ Collation consistency For AlwaysOn, all nodes must have the same collation. INI-based pre-filling ensures that.
AlwaysOnSetup - HA configuration after SQL installation sqmSQLTool - DBA toolbox (monitoring, backup, analysis) SQLMigration - migrate production databases
Boundaries

Scope & Boundaries

What the tool deliberately does not do - and why.

Outside the Scope

TaskResponsibility
Drive assignment (assigning letters D:/E:/F:)Server team
Install Windows ServerServer team
DNS recordsNetwork team
Migrate production databasesSQLMigration Tool
Configure AlwaysOnAlwaysOnSetup Tool
Firewall rulesNetwork team

Design Decisions

ℹ No upgrade scenario The tool performs a fresh install. In-place upgrades (e.g. 2019 → 2022) are a separate tool: InplaceUpDate.
ℹ Always a local Robocopy copy Setup.exe always runs from a local drive - never directly from the share. More stable, no timeout risk.
✓ Automatic 64K NTFS formatting The tool checks all SQL drives for 64K block size. On a mismatch: a dialog offers to reformat - no manual intervention needed ([PreInstall] Format64kCheck).
✓ Idempotent PostInstall Most PostInstall steps can be run multiple times without causing harm. A restart is safe.
Error Handling

Troubleshooting

ProblemCauseSolution
Install-DbaInstance timeout Setup takes longer than expected (CU patch) dbatools waits actively - no manual intervention. For a real timeout: check the log under %TEMP%\dbatools
Robocopy failed Share unreachable or no write permission on the local drive Check the UNC path in settings.ini. Drive C: must have enough space (~10 GB)
SA obfuscation skipped No sysadmin group configured in [SysadminGroups] Add a domain entry to settings.ini. SA then stays active - secure it manually
SQL script fails (step 17) Syntax error, missing object, permission issue in a company script ContinueOnError: remaining scripts keep running. Failures show up as WARN in the log
Wrong collation set Domain not detected - the standard fallback was used Check domain detection in the log. Add a Domain_XYZ entry to settings.ini if needed
dbatools import failed PSGallery unreachable, ShareBasePath missing Configure an offline copy under [dbatools] ShareBasePath in settings.ini
Summary

Summary & Next Steps

Key Takeaways

1-4h → 25-70 minutes

4 phases fully automatic - Robocopy, Install-DbaInstance, components, hardening

Zero-touch for new domains

Add an INI block - no PowerShell code changes. Ready to use immediately

17-step hardening guaranteed

NTFS, MaxMemory, MAXDOP, TempDB, SA obfuscation, Ola jobs, company scripts

57 SQL scripts obsolete

sqmSQLTool covers the majority. The rest runs automatically as step 17

The foundation for the whole toolchain

A consistent base for AlwaysOnSetup, sqmSQLTool, SQLMigration

Links & Resources

GitHubgithub.com/JankeUwe/SQLSetupTool
Source structureNew-SqlSourceStructure.ps1
Websitewww.powershelldba.de

Next Presentations

sqmSQLTool - DBA toolbox (monitoring, backup, analysis) AlwaysOnSetup - configure Availability Groups automatically DeadlockCollector - automatic deadlock capture ReportDeploymentTool - SSRS mass deployment InplaceUpDate - in-place SQL Server upgrade