sqmSQLTool
PowerShell Modul für SQL Server Administration
PowerShell für SQL-Administratoren
praxisnahe Aufgaben & Workflows
Das Modul sqmSQLTool baut auf PowerShell und dbatools auf – aber ergänzt mehr als 70 spezialisierte Funktionen für Sicherheit, Verfügbarkeitsgruppen, Policy-Erzwingung und automatisierte Diagnosen. Hier die wichtigsten Beispiele für den täglichen Einsatz.
Komfortables vollständiges Backup aller User-Datenbanken mit Komprimierung und automatischem Zielpfad. Alternativ kann man auch natives Backup-DbaDatabase verwenden, aber Invoke-sqmUserDatabaseBackup legt zusätzlich Prüfungen auf freien Speicherplatz an.
# Backup aller User-Datenbanken auf Standardverzeichnis (C:\Backups oder konfigurierter Pfad)
Invoke-sqmUserDatabaseBackup -SqlInstance "SRV-SQL01"
# Backup mit individuellem Zielordner + Log-Shrink nach Sicherung (optional)
Invoke-sqmUserDatabaseBackup -SqlInstance "SRV-SQL01" -BackupRoot "E:\SQLBackups" -CompressBackup
# Backup einer einzelnen Datenbank
Invoke-sqmUserDatabaseBackup -SqlInstance "SRV-SQL01" -Database "SalesDB"
Invoke-sqmRestoreDatabase – sie erkennt automatisch den letzten vollen Backup-Pfad und kann optional eine Differenz-/Log-Restore-Kette abbilden.
Erzeugt einen SQL Login, wobei das Passwort vorher gegen die aktive Active Directory Standardrichtlinie geprüft wird (Länge, Komplexität). Zusätzlich wird CHECK_POLICY = ON und CHECK_EXPIRATION = ON gesetzt. Umgeht die Einschränkungen einer reinen SQL-Policy und schützt vor schwachen Passwörtern.
# Passwort sicher abfragen
$secPassword = Read-Host "Passwort für neuen Login" -AsSecureString
# Login mit AD-Policy-Prüfung anlegen
New-SqmSqlLoginWithADPolicy -SqlInstance "PROD-01" `
-LoginName "AppUser_Business" `
-SecurePassword $secPassword `
-EnforcePasswordExpiration $true
# Mit Must Change (zwingt Benutzer zum Ändern beim ersten Login)
New-SqmSqlLoginWithADPolicy -SqlInstance "PROD-01" -LoginName "NewAnalyst" -SecurePassword $secPassword -MustChange $true
Get-ADDefaultDomainPasswordPolicy. Das AD-Modul muss verfügbar sein (RSAT). Falls nicht, fällt die Prüfung zwar nicht komplett aus, aber die volle Richtlinientreue ist dann nicht garantiert.
Mit den AlwaysOn-Cmdlets lassen sich Datenbanken bequem zu einer Verfügbarkeitsgruppe hinzufügen – inkl. Aktivierung von Auto-Seeding und Bereinigung auf den Sekundärknoten. Reporting mit Get-sqmAgHealthReport zeigt Synchronisationsstatus, Redo-Queue und Verbindungsprobleme an.
# Datenbank der AG hinzufügen (AutoSeed)
Invoke-sqmAddDatabaseToAvailabilityGroup -AvailabilityGroup "AG_PROD" -Database "ERP"
# Alle User-DBs einer Instanz der AG zuweisen
Invoke-sqmAddDatabaseToAvailabilityGroup -SqlInstance "SQL01" -AvailabilityGroup "AG_PROD" -All
# Zustandsbericht aller AGs (CSV + TXT)
Get-sqmAgHealthReport -SqlInstance "SQL01" -OutputPath "D:\Reports\AlwaysOn"
# Alle Secondaries synchronisieren (Logins, Jobs, Operatoren)
Sync-sqmAgNode -SqlInstance "SQL01"
Repair-sqmAlwaysOnDatabases prüft inkonsistente DBs und Invoke-sqmFailover ermöglicht kontrolliertes Failover inkl. Health-Check.
Automatische Analyse der Index-Fragmentierung mit Handlungsempfehlung (REORGANIZE ab 5%, REBUILD ab 30%). Werte können direkt an Invoke-sqmUpdateStatistics oder Invoke-sqmQueryStore weitergereicht werden.
# Fragmentierungsanalyse für eine Datenbank
Get-sqmIndexFragmentation -SqlInstance "SQL01" -Database "Sales" -MinFragmentationPercent 10
# REBUILD-Kandidaten anzeigen
Get-sqmIndexFragmentation -SqlInstance "SQL01" -All | Where-Object Recommendation -eq 'REBUILD'
# Fehlende Indizes per DMV-Cache (Top 20)
Get-sqmMissingIndexes -SqlInstance "SQL01" -TopN 20
# Query Store auswerten: Top 10 Queries nach CPU, Diagnose-Modus
Invoke-sqmQueryStore -SqlInstance "SQL01" -Database "FinanceDB" -Query -TopN 10 -OrderBy CPU -LookbackHours 48
Get-sqmIndexFragmentation mit Invoke-sqmUpdateStatistics -All -OnlyModified, um Wartungsfenster optimal zu nutzen.
Zentraler Bericht pro Datenbank: Recovery-Modell, letzte DBCC CHECKDB, Backupzeiten, AutoGrowth-Ereignisse, VLF-Anzahl. Perfekt als täglicher Health-Check per SQL Agent.
# Standard-Check (alle User-DBs)
Get-sqmDatabaseHealth -SqlInstance "SQL01"
# Inkl. Systemdatenbanken, CSV-Export nach D:\Reports
Get-sqmDatabaseHealth -SqlInstance "SQL01" -IncludeSystemDatabases -OutputPath "D:\Health"
# Datenbanken ohne Backup in den letzten 2 Tagen finden
Get-sqmDatabaseHealth -SqlInstance "SQL01" | Where-Object { $_.LastFullBackup -lt (Get-Date).AddDays(-2) }
# Verbindungsstatistiken / Blockings
Get-sqmConnectionStats -SqlInstance "SQL01" -GroupBy Application
Get-sqmBlockingReport -SqlInstance "SQL01" | Format-Table
Invoke-sqmPatchAnalysis -SqlInstance "SQL01" gleicht die Buildnummer mit CU-Referenztabelle ab und zeigt, ob die Instanz aktuell ist.
Installiert / aktualisiert die bekannten Ola Hallengren Wartungsskripte (IndexOptimize, DatabaseBackup, IntegrityCheck) und erstellt standardisierte SQL Agent Jobs. Spart Stunden der manuellen Einrichtung.
# Ola Scripts installieren + Jobs erzeugen (Backup, Index, Integrity)
Install-sqmOlaMaintenanceSolution -SqlInstance "SQL01" -InstallJobs
# Nur Index-Wartungs-Job erstellen
New-sqmOlaMaintenanceJobs -SqlInstance "SQL01" -JobType IndexOptimize
# Alle vorhandenen Ola-Jobs testen / Status prüfen
Test-sqmOlaInstallation -SqlInstance "SQL01"
Get-sqmAgentJobHistory -SqlInstance "SQL01" -JobName 'DatabaseBackup-USER_DATABASES' -Since (Get-Date).AddDays(-1) zur Überwachung.
Auditiert SQL- und Windows-Logins: inaktive Logins (Tage ohne Anmeldung), Passwortalter, Verstöße gegen Policies und optional AD-Orphans. Übersichtlich als CSV / TXT.
# Standard Audit (nur SQL Logins)
Invoke-sqmLoginAudit -SqlInstance "SQL01"
# Inaktivitätsschwelle 60 Tage + MaxPasswortalter 90 Tage + AD Orphan-Check
Invoke-sqmLoginAudit -SqlInstance "SQL01" -InactivityThresholdDays 60 -MaxPasswordAgeDays 90 -CheckAdOrphans
# Inventur aller Instanzobjekte (Datenbanken, Jobs, Linked Server)
Export-sqmDatabaseDocumentation -SqlInstance "SQL01" -OutputPath "D:\Inventory"
# SPN-Report für Kerberos konfiguration
Get-sqmSpnReport -ComputerName "SQL01"
🔧 Weitere nützliche Funktionen im sqmSQLTool
Get-sqmTempDbRecommendationSet-sqmDatabaseOwner -AllInvoke-sqmSaObfuscationCompare-sqmServerConfigurationInvoke-sqmExtendedEvents -Create -Template SlowQueries
Wie kann ich…?
mssSQLTool in der Praxis
Praxis-Tipps und fertige Einzeiler für die täglichen Aufgaben des SQL Server-Administrators.
Monitoring & täglicher Status-Check
4 TippsGet-mssDatabaseHealth # → Schreibt TXT + CSV in den OutputPath
Get-mssDatabaseHealth -SqlInstance "SQL01" | Where-Object { $_.Status -ne 'Online' -or $_.LastFullBackup -lt (Get-Date).AddDays(-2) -or $_.VlfCount -gt 1000 } | Format-Table DatabaseName, Status, LastFullBackup, VlfCount
Get-mssOperationStatus
while ($true) { Clear-Host Get-mssOperationStatus -SqlInstance "SQL01" | Format-Table Database, OperationType, PercentComplete, EstTimeRemaining -AutoSize Start-Sleep 15 }
Get-mssAgentJobHistory -Status Failure ` -Since (Get-Date).AddDays(-1) | Format-Table JobName, RunDate, Message -AutoSize
Get-mssAgentJobHistory -JobName '*Backup*' -Status Failure ` -Since (Get-Date).AddDays(-1)
Get-mssDiskSpaceReport -SqlInstance "SQL01" -WarnThresholdPct 10 | Where-Object Status -eq 'Warning' | Sort-Object DaysUntilFull | Format-Table VolumeName, FreeGB, DaysUntilFull, Status -AutoSize
AlwaysOn Availability Groups
4 TippsGet-mssAgHealthReport # Kritische Befunde herausfiltern: Get-mssAgHealthReport -SqlInstance "SQL01" | Where-Object OverallStatus -ne 'Healthy' | Format-Table AgName, ReplicaName, DbSyncState, RedoQueueMB
Invoke-mssAddDatabaseToAvailabilityGroup ` -AvailabilityGroup "AG_Prod" -Database "NeueDB"
Invoke-mssAddDatabaseToAvailabilityGroup ` -AvailabilityGroup "AG_Prod" -All
Sync-mssAgNode # erkennt Primary selbst Sync-mssAgNode -SqlInstance "SQL01" # explizit
Sync-mssAgNode -SqlInstance "SQL01" ` -ExcludeType Jobs,LinkedServers,Operators,Alerts
Repair-mssAlwaysOnDatabases
# Job erstellen (stündlich): New-mssAlwaysOnRepairJob -SqlInstance "SQL01"
Backup & Restore
3 TippsInvoke-mssUserDatabaseBackup -All
Invoke-mssUserDatabaseBackup -SqlInstance "SQL01" ` -Database "SalesDB","InventoryDB"
Invoke-mssRestoreDatabase -SqlInstance "SQL01" ` -BackupFile "D:\Backup\SalesDB.bak" ` -DatabaseName "SalesDB"
$seq = @( "D:\Bak\SalesDB_Full.bak", "D:\Bak\SalesDB_Diff.bak", "D:\Bak\SalesDB_Log.trn" ) Invoke-mssRestoreDatabase -SqlInstance "SQL01" ` -BackupFiles $seq -DatabaseName "SalesDB"
Invoke-mssRestoreDatabase -SqlInstance "SQL01" ` -BackupFile "D:\Bak\SalesDB.bak" ` -DatabaseName "SalesDB" -CreatePreRestoreBackup
Get-ChildItem "D:\Backup\*.bak" | ForEach-Object { $ok = Test-mssBackupIntegrity -SqlInstance "SQL01" ` -BackupPath $_.FullName [PSCustomObject]@{ File = $_.Name; Valid = $ok } } | Format-Table -AutoSize
Performance & Wartung
4 TippsGet-mssIndexFragmentation ` -Database "SalesDB" -MinFragmentationPercent 10 | Sort-Object FragmentationPercent -Descending | Format-Table TableName, IndexName, FragmentationPercent, Recommendation
# 1. Log sichern (bei Full Recovery): Backup-DbaDatabase -SqlInstance "SQL01" ` -Database "SalesDB" -Type Log -BackupDirectory "D:\Backup" # 2. Dann shrink: Invoke-mssLogShrink -Database "SalesDB" -ShrinkTargetPercent 20
Invoke-mssLogShrink -SqlInstance "SQL01" -All -WhatIf
Get-mssTempDbRecommendation -SqlInstance "SQL01"
Get-mssTempDbRecommendation -SqlInstance "SQL01" | Where-Object Status -ne 'OK' | Select-Object Status, Messages
# 1. Installieren Install-mssOlaMaintenanceSolution -SqlInstance "SQL01" # 2. Prüfen Test-mssOlaInstallation -SqlInstance "SQL01" # 3. Maintenance-Jobs anlegen New-mssOlaMaintenanceJobs -SqlInstance "SQL01" ` -ScheduleTime "23:00" -OperatorName "DBAs" # 4. System-DB-Backup-Job New-mssOlaSysDbBackupJob -SqlInstance "SQL01" ` -ScheduleTime "20:00" -OperatorName "DBAs"
Sicherheit & Compliance
3 Tipps$r = Invoke-mssSaObfuscation -SqlInstance "SQL01" # Kennwort SOFORT sicher aufbewahren: $r.GeneratedPassword | Out-File ` "C:\Secure\sa_pw_$(Get-Date -f 'yyyyMMdd').txt" Write-Host "Neuer Name: $($r.NewLoginName)"
"SQL01","SQL02","SQL03" | ForEach-Object { Invoke-mssSaObfuscation -SqlInstance $_ -ContinueOnError } | Select-Object SqlInstance, NewLoginName, Status | Format-Table
Get-mssSysadminAccounts -SqlInstance "SQL01" ` -ExcludeLogin "NT SERVICE\*","NT AUTHORITY\*","msssa" ` -ExcludeSysAccounts | Where-Object Status -in 'Unexpected','BuiltinAdmins' | Format-Table LoginName, LoginType, IsEnabled -AutoSize
Invoke-mssLoginAudit -SqlInstance "SQL01" ` -InactivityThresholdDays 90 ` -MaxPasswordAgeDays 180 ` -ExcludeLogin "NT SERVICE\*"
Invoke-mssLoginAudit -SqlInstance "SQL01" -CheckAdOrphans
Konfiguration & Inventar
4 Tipps$instances = Get-Content "C:\Admin\sql_instances.txt" Invoke-mssInstanceInventory ` -SqlInstance $instances -ContinueOnError # Dateien in: (Get-mssConfig -Key 'OutputPath')
Compare-mssServerConfiguration ` -SourceInstance "SQL01" -TargetInstance "SQL02" | Where-Object { $_.SourceValue -ne $_.TargetValue } | Format-Table Setting, SourceValue, TargetValue -AutoSize
Invoke-mssSetDatabaseRecoveryMode -All -RecoveryMode Full
Invoke-mssSetDatabaseRecoveryMode ` -Database "ArchiveDB" -RecoveryMode Simple
Find-mssDatabaseObject -SqlInstance "SQL01" ` -ObjectName "sp_GetOrders" | Format-Table Database, Schema, ObjectType, ObjectName
Find-mssDatabaseObject -SqlInstance "SQL01" ` -ObjectName "*" -SearchInDefinition ` -SearchText "OPENQUERY"
Tägliche SQL-Admin Checkliste
Morgen-Routine Alle Instanzen in ~5 Minuten
$instances = "SQL01","SQL02","SQL03" # Anpassen! # 1. Fehlgeschlagene Agent-Jobs seit gestern Get-mssAgentJobHistory -Status Failure -Since (Get-Date).AddDays(-1) | Format-Table JobName, RunDate, Message # 2. Datenbanken ohne aktuelles Backup Get-mssDatabaseHealth -SqlInstance $instances -ContinueOnError | Where-Object { $_.LastFullBackup -lt (Get-Date).AddDays(-2) } | Select-Object SqlInstance, DatabaseName, LastFullBackup # 3. Disk-Space-Warnung Get-mssDiskSpaceReport -SqlInstance $instances -WarnThresholdPct 10 -ContinueOnError | Where-Object Status -eq 'Warning' | Sort-Object DaysUntilFull | Format-Table SqlInstance, VolumeName, FreeGB, DaysUntilFull # 4. AG-Status (nur AlwaysOn-Umgebungen) Get-mssAgHealthReport -SqlInstance $instances[0] | Where-Object OverallStatus -ne 'Healthy' | Format-Table AgName, ReplicaName, DbSyncState, RedoQueueMB # 5. Aktive Operationen (läuft noch etwas?) Get-mssOperationStatus -SqlInstance $instances[0]
📋 Instanz-Inventar erstellen
Invoke-mssInstanceInventory ` -SqlInstance $instances -ContinueOnError
🔒 Sysadmin-Audit durchführen
Get-mssSysadminAccounts -SqlInstance $inst ` -ExcludeSysAccounts
🔒 Login-Audit (Policy, Inaktiv)
Invoke-mssLoginAudit -SqlInstance $inst ` -CheckAdOrphans
⚡ Best-Practice-Check
Get-mssSQLInstanceCheck ` -SqlInstance $inst -Detailed
⚡ TempDB-Konfiguration prüfen
Get-mssTempDbRecommendation ` -SqlInstance $inst
💾 Backup-Integrität stichproben
Test-mssBackupIntegrity ` -SqlInstance $inst -BackupPath $bak
🔄 AG-Node-Sync (Logins/Jobs)
Sync-mssAgNode -SqlInstance $inst
📋 Linked-Server-Abhängigkeiten
Get-mssLinkedServerUsage ` -SqlInstance $inst
⚡ Modul-Setup & Konfiguration
# Modul laden Import-Module "C:\Pfad\mssSQLTool\mssSQLTool.psd1" # Einmalige Konfiguration Set-mssConfig ` -LogPath "D:\Logs\SQL" ` -OutputPath "D:\Reports\SQL" ` -CentralPath "\\Fileserver\SQL\Reports" # Konfiguration prüfen Get-mssConfig # Alle Funktionen anzeigen Get-Command -Module mssSQLTool | Sort-Object Name | Format-Table Name