sqmSQLTool · Inventory & Documentation · 2026
Transparency at the push of a button.
Who runs what, on which server, at which patch level, with which databases - answered in seconds instead of hours.
Uwe Janke · Senior SQL Server DBA · dtcSoftware
Motivation
Which databases live on SQL03? Who owns "OldArchive"? Is the recovery model set correctly? Without documentation, the search starts from zero.
Patch level of every instance? Privileged accounts? Certificate expiry dates? Without a tool, every audit question means hours of manual work across dozens of servers.
"Was it like this yesterday?" Without regular snapshots, there's no way to tell if a configuration deviation is old or new. Root-cause analysis takes hours instead of minutes.
Databases grow quietly. The first sign is when space runs out - by then it's too late. Forecast data simply doesn't exist.
Overview
A full snapshot of an instance: version, databases, logins, AG, jobs, configuration.
Per database: files, sizes, autogrowth, backup times, objects, users - as an HTML report.
Compares the installed build against current CUs. Traffic-light status per instance and version.
Disk forecasting, AG health, certificate expiry, autogrowth, SPN status - automated daily.
Inventory
A full snapshot of a SQL Server instance - TXT (readable) + CSV (machine-readable). Filed in the central archive automatically.
| ℹ️ Instance info | Version, edition, patch level, collation, auth mode, MAXDOP, max/min memory, CPU count |
| 💾 Databases | Name, status, recovery model, size (MB), last full backup, owner, creation date |
| 🔑 Logins | Name, type (Windows/SQL), active/inactive, server roles |
| 🔗 Linked servers | Name, product, provider, data source |
| 🗓️ Agent jobs | Name, active/inactive, owner, last run + status |
| ⚙️ sp_configure | Only deviations from default - immediately visible what changed |
| 🔄 AlwaysOn | AG name, primary, replicas + roles, listener (port/IP), sync status |
# A single instance
Invoke-sqmInstanceInventory `
-SqlInstance 'SQL01\PROD' `
-OutputPath 'C:\Reports\SQL'
# Every instance from a list
'SQL01','SQL02','SQL03' | Invoke-sqmInstanceInventory
Filename: InstanceInventory_SQL01_PROD_2026-05-20.txt
Database documentation
A self-contained HTML report per instance - no external CSS, opens straight in a browser. Color-coded status badges.
| Properties | Status, recovery, collation, owner, creation date, compat level |
| File sizes | Data / log separately, including autogrowth settings and growth type |
| Backup age | Last FULL / DIFF / LOG with an age indicator - instantly visible if a backup is missing |
| CHECKDB | Date of the last integrity check, with an age warning |
| VLF count | Number of virtual log files (SQL 2016+) - excessive values are flagged |
| Objects | Count of tables, views, procs, functions, triggers, synonyms |
| DB users | Name, login name, type - orphaned users spotted immediately |
Export-sqmDatabaseDocumentation `
-SqlInstance 'SQL01' `
-Database 'Finance*' `
-OutputPath 'C:\Reports'
Filename: DatabaseDoc_SQL01_20260520_2015.html
Compliance
Invoke-sqmPatchAnalysis - compares the installed build against an embedded reference table of every known CU. Traffic-light status and a concrete recommendation per instance.
| Instance | Version | Build | Status | Recommendation |
|---|---|---|---|---|
| SQL01 | 2022 | 16.0.4175 | CU17 - current | No action needed |
| SQL02 | 2022 | 16.0.4135 | CU14 - 3 behind current | CU update recommended |
| SQL03 | 2019 | 15.0.2000 | RTM - 29 behind current | Patch immediately |
| SQL04 | 2019 | 15.0.4405 | CU29 - current | No action needed |
Reference table embedded: SQL 2016 SP3, 2017 up to CU40, 2019 up to CU29, 2022 up to CU17.
# Analyze every instance, save CSV
'SQL01','SQL02','SQL03','SQL04' |
Invoke-sqmPatchAnalysis `
-OutputPath 'C:\Reports\Patch'
# Show only outdated ones
'SQL01','SQL02','SQL03','SQL04' |
Invoke-sqmPatchAnalysis |
Where-Object { -not $_.IsLatest }
BuildsBehind: the exact number of missed CUsRecommendation: a directly quotable recommendationConfiguration comparison
A planned-vs-actual comparison of two instances. Before/after a migration, production vs. test, node 1 vs. node 2 in an AG pair.
# Compare production vs. test
Compare-sqmServerConfiguration `
-SourceInstance 'SQL01\PROD' `
-TargetInstance 'SQL02\TEST' `
-CompareDatabases
# Result: differences only
Setting SourceValue TargetValue
MaxMemory 32768 8192 <-- Different
MaxDOP 4 8 <-- Different
Collation Latin1... Latin1... (OK)
CostThreshold 50 25 <-- Different
-CompareDatabases: instance configuration only. With the switch, database-level settings too (owner, recovery model, collation).Compare the source and target server - confirm every relevant setting has been carried over.
Both nodes of an AlwaysOn pair need to be configured identically. Deviations are risks.
After a change request, prove that only the planned values were changed.
A golden standard server vs. a production instance. Deviations exported as CSV for the auditor.
Daily operations
Get-sqmDiskSpaceReport
| D:\ | 68% free |
| E:\ | 18% free |
| F:\ | 8% — 11 days |
Shows the growth rate and "days until full" based on a 30-day history.
Get-sqmAutoGrowthReport
Flags percentage-based growth, steps that are too small (<64 MB), and unbounded log files as warnings.
Get-sqmAgHealthReport
| Finance | SYNC • 0 MB |
| Reporting | SYNC • 82 MB |
Redo queue and send queue per database. Warning thresholds are configurable.
Get-sqmBlockingReport
Blocking chains with the head blocker, SQL text, wait duration, and affected resources - for immediate diagnosis.
Get-sqmCertificateReport
| HADR_Cert | 248 days |
| TDE_Cert | 62 days |
| SB_Cert | EXPIRED |
Covers: AlwaysOn / TDE / Service Broker / backup. An ALERTS.csv with critical entries only.
Get-sqmSpnReport
Checks Kerberos SPN registration. Missing SPNs come with ready-to-run setspn.exe commands.
Central archive
CentralPath: every report function automatically copies its result to the configured target path - no extra steps.
# Set the central archive (once)
Set-sqmConfig `
-CentralPath '\\fileserver\SQLReports' `
-OutputPath 'C:\Reports\Local'
# From now on: every function copies automatically
Invoke-sqmInstanceInventory -SqlInstance 'SQL01'
# Result lands in:
# C:\Reports\Local\InstanceInventory_SQL01_...txt
# \\fileserver\SQLReports\InstanceInventory_SQL01_...txt
\\fileserver\SQLReports\
InstanceInventory_SQL01_PROD_2026-05-20.txt
InstanceInventory_SQL01_PROD_2026-05-20.csv
InstanceInventory_SQL02_PROD_2026-05-20.txt
InstanceInventory_SQL03_TEST_2026-05-20.txt
DatabaseDoc_SQL01_PROD_20260520_2015.html
DatabaseDoc_SQL01_PROD_20260520_2015.csv
PatchAnalysis_20260520_2014.csv
DiskSpaceReport_SQL01_PROD_2026-05-20.txt
DiskSpaceReport_SQL01_PROD_2026-05-20.csv
CertReport_SQL01_PROD_20260520_2013.txt
CertReport_SQL01_PROD_20260520_2013_ALERTS.csv
AgHealthReport_SQL01_PROD_2026-05-20.txt
Scale
Every report function is pipeline-capable. An instance list from a file, database, or AD - sqmSQLTool processes them all in parallel.
# Instance list from a text file
Get-Content 'C:\Config\instances.txt' |
Invoke-sqmInstanceInventory
# Patch analysis of every production instance
Get-Content 'C:\Config\prod_instances.txt' |
Invoke-sqmPatchAnalysis `
-OutputPath '\\fileserver\SQLReports\Patch'
# Only outdated ones, as a table - for a ticket
Get-Content 'C:\Config\prod_instances.txt' |
Invoke-sqmPatchAnalysis |
Where-Object { -not $_.IsLatest } |
Select-Object SqlInstance,PatchStatus,BuildsBehind,Recommendation |
Format-Table -AutoSize
-ContinueOnError: an unreachable instance doesn't interrupt the entire run.| Job | Cadence | Command |
|---|---|---|
| Inventory | Weekly | Invoke-sqmInstanceInventory |
| DB docs | Weekly | Export-sqmDatabaseDocumentation |
| Patch analysis | Weekly | Invoke-sqmPatchAnalysis |
| Disk forecast | Daily | Get-sqmDiskSpaceReport |
| AG health | Daily | Get-sqmAgHealthReport |
| Certificates | Daily | Get-sqmCertificateReport |
Every job can be set up as a SQL Agent job or a Windows Task Scheduler task - configure once, they run fully automatically and save to CentralPath.
Reference
| Task | Function | Output |
|---|---|---|
| Instance snapshot | Invoke-sqmInstanceInventory | TXT + CSV |
| DB documentation | Export-sqmDatabaseDocumentation | HTML + CSV |
| Patch compliance | Invoke-sqmPatchAnalysis | Console + CSV |
| Config comparison | Compare-sqmServerConfiguration | Console |
| Disk forecast | Get-sqmDiskSpaceReport | TXT + CSV |
| AG health | Get-sqmAgHealthReport | TXT + CSV |
| Certificate expiry | Get-sqmCertificateReport | TXT + CSV + ALERTS.csv |
| Autogrowth check | Get-sqmAutoGrowthReport | Console |
| Blocking analysis | Get-sqmBlockingReport | Console + CSV |
| SPN audit | Get-sqmSpnReport | TXT + CSV |
| Hardware report | Get-sqmServerHardwareReport | HTML + CSV + TXT |
| Central archive | Set-sqmConfig -CentralPath | automatic |
-OutputPath | Target directory for report files |
-ContinueOnError | Skip errors per instance |
-CompareDatabases | Compare at the database level too |
-WarnThresholdPct | Disk-space warning threshold (default: 20%) |
-CriticalThresholdPct | Critical threshold (default: 10%) |
-WarningThresholdDays | Certificate warning (default: 90 days) |
-HistoryDays | Time span for disk growth forecasting |
# Reports in English
Set-sqmConfig -Language 'en-US'
# Back to German
Set-sqmConfig -Language 'de-DE'
Hardware configuration
A detailed hardware report via CIM/WMI — no PowerShell remoting required.
| 💻 Operating system | Version, build, uptime, domain |
| ⚙ Processor | Model, socket, cores, clock speed |
| 💾 Memory | Total, free, DIMM details (type, speed) |
| 💿 Drives | Physical (SSD/HDD) + logical with utilization bars |
| 🌐 Network | IP, MAC, DNS, gateway |
| 🗄 SQL Server | Instances, status, startup type (no SQL login needed) |
| ☁ VM detection | Hyper-V, VMware, VirtualBox, KVM/QEMU, physical |
-OutputFormat# Local server, open HTML in the browser
Get-sqmServerHardwareReport
# Remote server, CSV for Excel
Get-sqmServerHardwareReport `
-ComputerName "SQL01" `
-OutputFormat CSV -NoOpen
# Multiple servers, every format
Get-sqmServerHardwareReport `
-ComputerName "SQL01","SQL02","SQL03" `
-OutputFormat All -NoOpen
# Pipeline from an AD OU
Get-ADComputer -SearchBase "OU=DB,DC=corp,DC=local" `
-Filter '*' |
Select-Object -ExpandProperty Name |
Get-sqmServerHardwareReport `
-OutputFormat All -NoOpen
Summary
Always available: which instances are out of date, how urgent is the action needed?
The forecast gives 10+ days of lead time - enough for capacity planning without middle-of-the-night emergencies.
Certificates, logins, configuration - all current on the share. The auditor helps themselves.
New colleagues get the current inventory report - no weeks of getting up to speed.
Compare-sqmServerConfiguration proves after every change that only the planned values changed.
A planned-vs-actual comparison before every migration - no more forgotten settings on the target system.