From af505f9299ade5f7eb831262ac485a28e8d6cb1e Mon Sep 17 00:00:00 2001 From: Dimitri Furman Date: Tue, 14 Jul 2026 19:54:50 -0400 Subject: [PATCH 1/2] Add ShrinkDriver sample: parallel DBCC SHRINKFILE with reporting, retries, and tests A PowerShell sample that reclaims unused space from a database's data files by running parallel DBCC SHRINKFILE operations. Includes a report mode, incremental shrinking toward an optional target, progress monitoring, retries, graceful stop handling, and low-priority locking. Supports Entra ID, Windows, and SQL authentication, connects with certificate validation first, and ships unit and integration tests (LocalDB, SQL Server, and Azure SQL Database). --- .../features/shrink/shrink-driver/.gitignore | 2 + .../features/shrink/shrink-driver/README.md | 151 ++ .../shrink/shrink-driver/src/ShrinkDriver.ps1 | 1614 +++++++++++++++++ .../shrink/shrink-driver/tests/README.md | 101 ++ .../tests/ShrinkDriver.Integration.Tests.ps1 | 339 ++++ .../tests/ShrinkDriver.Unit.Tests.ps1 | 507 ++++++ .../tests/fixtures/ShrinkTestDb.psm1 | 333 ++++ 7 files changed, 3047 insertions(+) create mode 100644 samples/features/shrink/shrink-driver/.gitignore create mode 100644 samples/features/shrink/shrink-driver/README.md create mode 100644 samples/features/shrink/shrink-driver/src/ShrinkDriver.ps1 create mode 100644 samples/features/shrink/shrink-driver/tests/README.md create mode 100644 samples/features/shrink/shrink-driver/tests/ShrinkDriver.Integration.Tests.ps1 create mode 100644 samples/features/shrink/shrink-driver/tests/ShrinkDriver.Unit.Tests.ps1 create mode 100644 samples/features/shrink/shrink-driver/tests/fixtures/ShrinkTestDb.psm1 diff --git a/samples/features/shrink/shrink-driver/.gitignore b/samples/features/shrink/shrink-driver/.gitignore new file mode 100644 index 0000000000..e4a1d65eab --- /dev/null +++ b/samples/features/shrink/shrink-driver/.gitignore @@ -0,0 +1,2 @@ +# Run logs produced by Invoke-ShrinkDriver +*.log diff --git a/samples/features/shrink/shrink-driver/README.md b/samples/features/shrink/shrink-driver/README.md new file mode 100644 index 0000000000..982bd25c2b --- /dev/null +++ b/samples/features/shrink/shrink-driver/README.md @@ -0,0 +1,151 @@ +# ShrinkDriver + +Reclaim allocated but unused space from the data files of a MSSQL database +by running parallel `DBCC SHRINKFILE` operations, with progress monitoring, +incremental shrinking, and automatic retries. + +## What it does + +- Runs in two modes: `Report` (default) shows each file's used, allocated, and reclaimable space without changing anything; `Shrink` performs the shrink. +- Shrinks multiple data files at once (one session per file) to reduce total run time. +- Shrinks each file gradually in incremental steps toward an optional target size, instead of in one large operation. +- Retries transient failures with backoff, and moves on from files that cannot shrink further. +- Skips files with little unused space to reclaim. +- Optionally runs shrink at low lock priority to reduce blocking of other queries. +- Writes a status report to the console and a log file at a regular interval, and stops on Ctrl+C or an optional time limit. +- Supports Entra ID, Windows, and SQL authentication when connecting to the database. + +## Requirements + +- SQL Server 2022 or later, Azure SQL Managed Instance, or Azure SQL Database. +- To shrink (`-Mode Shrink`): membership in the `db_owner` database role, or the `sysadmin` server role. +- To report (`-Mode Report`, the default): connection to the database. +- PowerShell 7 or later. +- The `SqlServer` module: + `Install-Module SqlServer -Scope CurrentUser`. + +## Usage + +Load the script, then call `Invoke-ShrinkDriver`: + +```powershell +. .\src\ShrinkDriver.ps1 + +# Report (default): show each file's used, allocated, and reclaimable space, without changing anything +Invoke-ShrinkDriver -ServerName myserver.database.windows.net -DatabaseName MyDb + +# Shrink with Entra ID auth (default) to the smallest possible size, working on up to 5 files concurrently +Invoke-ShrinkDriver -ServerName myserver.database.windows.net -DatabaseName MyDb -Mode Shrink -Sessions 5 + +# Shrink with Windows auth: don't shrink below 500 GiB, working on up to 8 files concurrently +Invoke-ShrinkDriver -ServerName sql01 -DatabaseName MyDb -Mode Shrink -AuthType Windows -FileTargetSizeGiB 500 -Sessions 8 + +# Shrink with SQL auth (prompts securely for the password when it is not supplied) +Invoke-ShrinkDriver -ServerName sql01 -DatabaseName MyDb -Mode Shrink -AuthType SQL -SqlLogin appuser + +# Connect to an instance with a self-signed certificate +Invoke-ShrinkDriver -ServerName devsql01 -DatabaseName MyDb -Mode Shrink -AuthType Windows -TrustServerCertificate +``` + +For the full list of parameters and what they do: + +```powershell +Get-Help Invoke-ShrinkDriver -Full +``` + +## Output + +Progress is written to the console and mirrored to a log file — by default a +timestamped `shrink-