Skip to content

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.

.build.ps1
#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):

Invoke-Build

Run only the build step:

Invoke-Build Build

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:

PSScriptAnalyzerSettings.psd1
@{
    ExcludeRules = @(
        'PSAvoidUsingWriteHost',
        'PSAvoidTrailingWhitespace'
    )
}

Pass it to the analysis run:

$issues = Invoke-ScriptAnalyzer -Path $outputPath -Settings .\PSScriptAnalyzerSettings.psd1

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.

tests\MyModule.Tests.ps1
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:

Invoke-Pester -Path 'tests' -Output Detailed

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.