A dependency-aware script builder for PowerShell. Combines multi-file PowerShell projects into a single, deployable script with automatic dependency resolution, topological sorting, and full support for classes, enums, and functions.
The Problem: PowerShell class definitions must appear in the correct order in a script file — base classes before derived classes, dependencies before dependents. Managing this manually across dozens of files is error-prone and breaks as the project grows. PSScriptBuilder solves this automatically using AST analysis.
- Automatic Dependency Ordering - AST analysis resolves class inheritance and type dependencies; output is always in valid load order — no manual sorting required
- Cycle Detection - Detects fatal circular dependencies (inheritance, static initializers) before any output is written; type reference cycles are resolved automatically
- Cross-Dependency Support - Detects when classes and functions must be interleaved and switches to a unified ordered output block automatically
- Flexible Templates - Define your output structure once using a template with token placeholders; supports any output format (.psm1, .ps1, .txt)
- Multiple Collectors - Dedicated collectors for Classes, Functions, Enums, Using statements, and raw Files
- Release Management - Built-in SemVer version bumping, Git metadata extraction, and file update automation
- PS 5.1 and 7+ Compatible - Runs on Windows PowerShell 5.1 and PowerShell 7+ (Windows, Linux, macOS)
Install-Module -Name PSScriptBuilder -Scope CurrentUserAlways use using module -- not Import-Module -- to import PSScriptBuilder.
# Correct -- classes and enums are available
using module PSScriptBuilder
# Wrong -- classes and enums will NOT be available
Import-Module PSScriptBuilderPowerShell only loads class and enum definitions when a module is imported with using module.
The using statement must appear at the very top of your script, before any other code.
1. Install and import
Install-Module -Name PSScriptBuilder
using module PSScriptBuilder2. Create configuration (first-time setup)
New-PSScriptBuilderConfiguration3. Configure collectors
$contentCollector = New-PSScriptBuilderContentCollector |
Add-PSScriptBuilderCollector -Type Class -IncludePath "src/Classes" |
Add-PSScriptBuilderCollector -Type Function -IncludePath "src/Public"4. Build
Invoke-PSScriptBuilderBuild `
-ContentCollector $contentCollector `
-TemplatePath "build/MyModule.psm1.template" `
-OutputPath "build/Output/MyModule.psm1"Note: PSScriptBuilder resolves relative paths (like
src/Classes) against the project root. Run these commands from your project directory, or callSet-PSScriptBuilderProjectRoot -Path "C:\Projects\MyModule"first to set it explicitly.
| Type | Description |
|---|---|
Using |
Collects using statements |
Enum |
Collects enumeration definitions |
Class |
Collects class definitions with dependency order |
Function |
Collects standalone function definitions |
File |
Includes complete file contents as-is |
Each collector accepts -IncludePath, -ExcludePath, -IncludeFile, -ExcludeFile, and an optional -CollectionKey for use as a template token.
See the Collectors Guide for details on filtering, custom keys, and advanced collector configuration.
A template is any plain text file with {{Token}} placeholders. The output file can have any extension (.psm1, .ps1, .txt, etc.) — PSScriptBuilder simply replaces each placeholder with the correctly ordered, resolved content of the corresponding collector.
Default CollectionKey per collector type:
| Collector Type | Default Token |
|---|---|
Using |
{{USING_STATEMENTS}} |
Enum |
{{ENUM_DEFINITIONS}} |
Class |
{{CLASS_DEFINITIONS}} |
Function |
{{FUNCTION_DEFINITIONS}} |
File |
{{FILE_CONTENTS}} |
Example template (build/MyModule.psm1.template):
{{USING_STATEMENTS}}
{{ENUM_DEFINITIONS}}
{{CLASS_DEFINITIONS}}
{{FUNCTION_DEFINITIONS}}
{{FILE_CONTENTS}}Use -CollectionKey on Add-PSScriptBuilderCollector to define a custom token name, e.g. {{DOMAIN_CLASSES}}.
When classes and functions have mutual dependencies that require interleaving in the output, PSScriptBuilder automatically switches to Ordered Mode. Replace the individual per-type placeholders with a single {{ORDERED_COMPONENTS}} token:
{{USING_STATEMENTS}}
{{ORDERED_COMPONENTS}}Hybrid Mode lets you adopt this layout proactively — even when no cross-dependencies currently exist — making the template resilient to future dependency changes without restructuring. See the Templates Guide for details.
PSScriptBuilder includes cmdlets for SemVer version management:
# Bump the version (Major / Minor / Patch)
Update-PSScriptBuilderReleaseData -Minor
# Propagate version tokens across all registered files
Update-PSScriptBuilderBumpFiles
# Then run your build
Invoke-PSScriptBuilderBuild `
-ContentCollector $contentCollector `
-TemplatePath "build/MyModule.psm1.template" `
-OutputPath "build/Output/MyModule.psm1"See the Release Management Guide for details on bump configuration, token replacement, and the full release pipeline.
git clone https://github.com/PSScriptBuilder/PSScriptBuilder.git
cd PSScriptBuilder
.\build.ps1 -ProjectRoot $PWDThis GitHub repository is a mirror of the primary development repository hosted on GitLab. Pull requests submitted here will not be merged. Please use GitHub Issues for bug reports and feature requests.
For code conventions, testing instructions, and contribution guidelines, see CONTRIBUTING.md.
PSScriptBuilder focuses on script building and pairs well with:
- Invoke-Build - a general-purpose task runner that orchestrates the full build pipeline; PSScriptBuilder fits naturally as one step within it
- Pester - the standard PowerShell testing framework; use alongside PSScriptBuilder to test the generated output
- ModuleBuilder - covers similar ground for simpler projects; choose PSScriptBuilder when your project uses class inheritance or requires dependency-aware ordering
See CHANGELOG.md.
MIT — see LICENSE.
Tim Hartling
For questions, bug reports, or feature requests, please open an Issue on GitHub.
