Tool Integrations¶
PSScriptBuilder fits naturally into existing PowerShell toolchains. This guide shows how to combine PSScriptBuilder with the most common tools in the PowerShell ecosystem — Invoke-Build as a task runner, PSScriptAnalyzer for post-build linting, and Pester for testing the generated output. A brief comparison with ModuleBuilder explains when each tool is the better fit.
Invoke-Build¶
Invoke-Build is a task runner for PowerShell.
It lets you define named tasks with dependencies and execute them selectively — similar to
make or rake, but in pure PowerShell.
PSScriptBuilder works as an assembly step inside an Invoke-Build pipeline: one task assembles the output script, other tasks handle testing, linting, or publishing. Each task remains independently runnable.
#Requires -Modules PSScriptBuilder, InvokeBuild
task SetRoot {
Set-PSScriptBuilderProjectRoot -Path $BuildRoot
}
task Build SetRoot, {
$script:result = New-PSScriptBuilderContentCollector |
Add-PSScriptBuilderCollector -Type Class -IncludePath 'src\Classes' |
Add-PSScriptBuilderCollector -Type Function -IncludePath 'src\Functions' |
Invoke-PSScriptBuilderBuild -TemplatePath 'build\MyModule.psm1.template' `
-OutputPath 'build\Output\MyModule.psm1'
}
task Analyze Build, {
$issues = Invoke-ScriptAnalyzer -Path 'build\Output\MyModule.psm1'
if ($issues) { throw "PSScriptAnalyzer found $($issues.Count) issue(s)." }
}
task Test Build, {
Invoke-Pester -Path 'tests' -CI
}
task . Build, Analyze, Test
Run the default task (Build → Analyze → Test):
Run only the build step:
PSScriptAnalyzer¶
PSScriptAnalyzer is a static analysis tool for PowerShell scripts. It checks for common coding issues, style violations, and potential bugs using a set of built-in and customizable rules.
Running PSScriptAnalyzer against the assembled output script — rather than the individual source files — verifies the final artifact, including any generated or injected content from the template.
$outputPath = 'build\Output\MyModule.psm1'
# Run with default rules
$issues = Invoke-ScriptAnalyzer -Path $outputPath
# Show results
$issues | Format-Table RuleName, Severity, Line, Message -AutoSize
# Fail if any errors or warnings found
$blocking = $issues | Where-Object { $_.Severity -in 'Error', 'Warning' }
if ($blocking) {
throw "PSScriptAnalyzer: $($blocking.Count) blocking issue(s) found."
}
To suppress specific rules for the entire output file, use a PSScriptAnalyzer settings file:
@{
ExcludeRules = @(
'PSAvoidUsingWriteHost',
'PSAvoidTrailingWhitespace'
)
}
Pass it to the analysis run:
Analyze source files during development
For fast feedback during development, run PSScriptAnalyzer against the individual source
files in src\. Reserve the output-file analysis for CI — it catches issues introduced
by the assembly process itself (e.g. template injection, ordering artifacts).
Pester¶
Pester is the standard testing framework for PowerShell. Tests can
target the assembled output script directly — loading it with using module
confirms that all components load without errors and behave as expected.
using module ..\build\Output\MyModule.psm1
Describe 'MyModule' {
Context 'Class loading' {
It 'loads without errors' {
{ [MyClass]::new() } | Should -Not -Throw
}
}
Context 'Functions' {
It 'Get-MyData returns a result' {
Get-MyData | Should -Not -BeNullOrEmpty
}
}
}
Run the tests:
Run tests in a fresh PowerShell session
using module loads types into the current session and cannot be unloaded. If you
rebuild and retest in the same session, stale types may cause unexpected failures.
Use pwsh -NoProfile -Command "Invoke-Pester -Path tests" in CI or open a new
terminal for each test run locally.
Real-world example
PSScriptBuilder's own test suite follows this exact pattern. See
tests/Invoke-Tests.ps1
in the repository.
ModuleBuilder¶
ModuleBuilder is a well-established tool for
assembling PowerShell modules from multiple files. It handles dot-sourcing, manifest
management, and file ordering using a naming convention (01-ClassName.ps1,
02-AnotherClass.ps1, etc.).
When ModuleBuilder is the better fit:
- Your project uses only functions — no classes or enums
- You prefer convention-based ordering (file prefixes) over automatic dependency analysis
- You need tight integration with the PowerShell module manifest (
.psd1) during the build
When PSScriptBuilder is the better fit:
- Your project has components (classes, enums, functions) with dependencies that require a specific load order
- You want automatic dependency resolution without manual file naming conventions
- You need template-based output, release management, or post-build analysis as part of the same tool
The two tools are not mutually exclusive — ModuleBuilder can handle module structure and manifest management while PSScriptBuilder handles dependency-ordered assembly of the script body.