Imported from raandree/CopilotAtelier (
skills/sampler-framework/SKILL.md). Install upstream withnpx skills add raandree/CopilotAtelier --skill sampler-framework. Copyright stays with the author.
Sampler PowerShell Module Build Framework
Comprehensive reference for the Sampler build framework. Sampler provides scaffolding, build automation, testing, versioning, and CI/CD pipeline integration using ModuleBuilder, InvokeBuild, Pester 5, and GitVersion.
Note: For enforced coding rules that auto-apply when editing Sampler build files, see
sampler.instructions.md. For debugging build failures, see thesampler-build-debugskill. For migrating legacy modules, see thesampler-migrationskill.
Overview
Sampler serves several purposes:
- Scaffold a PowerShell module project with consistent structure and practices
- Build modules using ModuleBuilder and InvokeBuild tasks
- Test with Pester 5 (unit, integration, and quality assurance tests)
- Version automatically via GitVersion (semantic versioning from git history)
- Package as NuGet packages for PowerShell Gallery publication
- Deploy through Azure Pipelines or GitHub Actions CI/CD
- Works cross-platform on Windows, Linux, and macOS
- Assumes nothing about the local environment (no admin rights required)
Core Dependencies
| Component | Purpose |
|---|---|
| InvokeBuild | Task runner for build automation |
| ModuleBuilder | Compiles source files into a single .psm1 |
| Pester 5 | Testing framework |
| GitVersion | Semantic versioning from git history |
| PSScriptAnalyzer | Static analysis and linting |
| Plaster | Template engine for scaffolding |
| ChangelogManagement | Changelog automation |
Getting Started
Prerequisites
- PowerShell 5.1+ or PowerShell 7.2+
- Git installed and available on
PATH - GitVersion (recommended for automatic versioning):
# Windows (Chocolatey)
choco upgrade gitversion.portable
# macOS/Linux (Homebrew)
brew upgrade gitversion
# .NET tool (cross-platform)
dotnet tool install --global GitVersion.Tool
Installing Sampler
Install-Module -Name 'Sampler' -Scope 'CurrentUser'
Creating a New Project
Use New-SampleModule to scaffold a new project. Choose the template that fits your needs:
| Template | Description |
|---|---|
SimpleModule |
Minimal structure with build pipeline automation |
SimpleModule_NoBuild |
Simple module without build automation |
CompleteSample |
Complete structure with example files |
dsccommunity |
DSC Community baseline with full CI/CD pipeline |
CustomModule |
Interactive prompts for custom scaffolding |
SimpleModule (Recommended Starting Point)
$newSampleModuleParameters = @{
DestinationPath = 'C:\source'
ModuleType = 'SimpleModule'
ModuleName = 'MyModule'
ModuleAuthor = 'Your Name'
ModuleDescription = 'A brief description of the module'
}
New-SampleModule @newSampleModuleParameters
CustomModule (Full Control)
$samplerModule = Import-Module -Name Sampler -PassThru
$invokePlasterParameters = @{
TemplatePath = Join-Path -Path $samplerModule.ModuleBase -ChildPath 'Templates/Sampler'
DestinationPath = 'C:\source'
ModuleType = 'CustomModule'
ModuleName = 'MyModule'
ModuleAuthor = 'Your Name'
ModuleDescription = 'A brief description of the module'
}
Invoke-Plaster @invokePlasterParameters
First Build
Use one line as the inner command of the detached build wrapper, with its
working directory set to C:\source\MyModule:
# Resolve dependencies and build (first run)
./build.ps1 -ResolveDependency -Tasks build
# Resolve dependencies and run full default workflow (build + test)
./build.ps1 -ResolveDependency
Project Structure
Standard Sampler folder layout (source/, tests/, output/, RequiredModules.psd1, build.yaml, build.ps1) and what each path is for — read references/project-structure.md.
Module Manifest Conventions
Conventions for .psd1 manifests under Sampler — ModuleVersion placeholder, FunctionsToExport, PrivateData.PSData, and how ModuleBuilder merges them — read references/module-manifest.md.
Build Configuration (build.yaml)
Full build.yaml schema, every key, code-coverage thresholds, file copy patterns, and worked examples — read references/build-yaml.md.
Dependency Management (RequiredModules.psd1)
RequiredModules.psd1 schema, version-pinning patterns, gallery vs local sources, and dependency-resolution configuration — read references/dependency-management.md.
Dependency Resolution Configuration
Resolve-Dependency.psd1 settings, gallery configuration, allow-pre-release, and proxy options — read references/dependency-resolution.md.
Bootstrap Process (build.ps1)
How build.ps1 bootstraps dependencies, parameter handling, and customisation hooks — read references/bootstrap.md.
Build Workflows and Tasks
Built-in Workflows
| Workflow | Tasks | Invocation |
|---|---|---|
. (default) |
build + test |
./build.ps1 |
build |
Clean → Build_Module → Build_NestedModules → Create_Changelog | ./build.ps1 -Tasks build |
test |
Pester_Tests → Coverage_Convert → Coverage_Threshold | ./build.ps1 -Tasks test |
pack |
build + package_module_nupkg |
./build.ps1 -Tasks pack |
publish |
Publish_Release_To_GitHub + Publish_Module_To_gallery | ./build.ps1 -Tasks publish |
Core Build Tasks
| Task | Source Module | Purpose |
|---|---|---|
Clean |
Sampler | Remove output/ directory |
Build_Module_ModuleBuilder |
Sampler | Compile source files into built module |
Build_NestedModules_ModuleBuilder |
Sampler | Build nested/helper modules |
Create_Changelog_Release_Output |
Sampler | Extract current release notes from CHANGELOG |
package_module_nupkg |
Sampler | Create NuGet package |
Pester_Tests_Stop_On_Fail |
Sampler | Run Pester tests, fail build on test failure |
Convert_Pester_Coverage |
Sampler | Convert coverage to JaCoCo format |
Pester_If_Code_Coverage_Under_Threshold |
Sampler | Fail if coverage below threshold |
Publish_Release_To_GitHub |
Sampler.GitHubTasks | Create GitHub release with assets |
Publish_Module_To_gallery |
Sampler.GitHubTasks | Publish to PowerShell Gallery |
Create_ChangeLog_GitHub_PR |
Sampler.GitHubTasks | Create PR to update changelog |
Create_Release_Git_Tag |
Sampler | Create and push release tag |
Create_Changelog_Branch |
Sampler | Push changelog branch for PR |
Set_PSModulePath |
Sampler | Configure PSModulePath for build |
noop |
Sampler | No operation (bootstrap only) |
Discovering Available Tasks
Use this as the inner command of the detached build wrapper:
# List all available tasks (dependencies must be resolved first)
./build.ps1 -Tasks ?
Custom Build Tasks
Writing custom InvokeBuild tasks, Set-SamplerTaskVariable pattern, task dependencies, and integration with the default workflow — read references/custom-build-tasks.md.
Testing Patterns
Pester 5 test scaffolding, Unit/Integration/QA folder conventions, code coverage configuration, mock patterns, and parametrised test recipes — read references/testing-patterns.md.
Versioning with GitVersion
GitVersion.yml configuration, branch strategies, version source override, and ModuleVersion injection during build — read references/gitversion.md.
CI/CD Integration
Azure Pipelines and GitHub Actions templates, build/test/publish stage layout, artefact handling, and gallery publishing — read references/ci-cd-pipelines.md.
Adding Code Samples with Add-Sample
Use Add-Sample to add scaffolded elements to an existing project:
# Add a public function with unit test
Add-Sample -Sample PublicFunction -PublicFunctionName Get-MyWidget
# Add a private function
Add-Sample -Sample PrivateFunction -PrivateFunctionName ConvertTo-InternalFormat
# Add a class
Add-Sample -Sample ClassResource -ResourceName MyResource
This creates the source file in the appropriate directory and a matching test file.
Multi-Module Repositories
Patterns for repositories that build multiple modules from one Sampler tree — read references/multi-module.md.
DSC and Datum Configuration Data Projects
DscWorkshop/Sampler.DscPipeline structure, Datum hierarchy and merge strategies, role composition, MOF compilation pipeline, and reference-implementation walkthrough — read references/dsc-datum.md.
VSCode Integration
VS Code tasks.json/launch.json templates, PowerShell extension settings, debugger configuration, and recommended extensions for Sampler projects — read references/vscode-integration.md.
Common Pitfalls and Troubleshooting
Build failures, dependency resolution errors, version mismatch symptoms, GitVersion edge cases, and known Sampler bugs with workarounds — read references/troubleshooting.md.
Migration from Legacy Build Systems
Migration Checklist
| Phase | Action | Details |
|---|---|---|
| 1 | Analyze | Inventory manifest, functions, tests, CI config |
| 2 | Restructure source | Move to source/Public/, source/Private/ layout |
| 3 | Create build files | build.ps1, build.yaml, RequiredModules.psd1, Resolve-Dependency.*, GitVersion.yml |
| 4 | Configure CI/CD | azure-pipelines.yml with Build/Test/Deploy stages |
| 5 | Port tests | Migrate to Pester 5 syntax, create QA tests |
| 6 | Add community files | CHANGELOG, CONTRIBUTING, CODE_OF_CONDUCT, SECURITY |
| 7 | Remove legacy files | Delete appveyor.yml, PSDepend.build.psd1, Deploy.PSDeploy.ps1, old *.build.ps1 |
| 8 | Verify | ./build.ps1 -ResolveDependency -Tasks test succeeds |
Pester 4 to Pester 5 Migration
| Pester 4 | Pester 5 |
|---|---|
Should Be $value |
Should -Be $value |
Top-level $variable |
BeforeAll { $script:variable } |
$TestDrive in Describe |
$TestDrive in It (via BeforeAll) |
Mock in Describe |
Mock in BeforeAll or BeforeEach |
-TestCases @{...} |
-ForEach @{...} or -TestCases @{...} |
| Discovery + Run mixed | BeforeDiscovery vs BeforeAll separation |
Key Migration Rules
- Preserve the module GUID — it is the PowerShell Gallery identity
- Explicit
FunctionsToExport— never use wildcards ('*') - Remove
#Requiresfrom source files — use manifestRequiredModulesinstead - Copy
build.ps1andResolve-Dependency.*verbatim from a reference project - Start with
CodeCoverageThreshold: 0— increase after baseline established
Community and Configuration Files
CHANGELOG.md, CODE_OF_CONDUCT.md, CONTRIBUTING.md, SECURITY.md, issue/PR templates, and .editorconfig conventions — read references/community-files.md.
Build Task Variables Reference
These variables influence build task behavior. Set via command line, environment variable, parent scope, or build.yaml.
| Variable | Default | Description |
|---|---|---|
OutputDirectory |
output |
Base directory for all build output |
BuiltModuleSubdirectory |
(empty) | Subdirectory under OutputDirectory for built module |
BuildModuleOutput |
OutputDirectory + BuiltModuleSubdirectory |
Full path where module is built |
ModuleVersion |
GitVersion NuGetVersionV2 |
Module version for the build |
ProjectPath |
$BuildRoot |
Root path of the project |
ProjectName |
Module manifest BaseName |
Project/module name |
SourcePath |
Auto-detected | Path to source/ or src/ folder |
ReleaseNotesPath |
OutputDirectory/ReleaseNotes.md |
Path to release notes output |
Sampler Commands Reference
Full reference for New-SampleModule, Add-Sample, Set-SamplerTaskVariable, Invoke-SamplerTask, and other Sampler cmdlets — read references/commands-reference.md.
Summary Checklist
Use this checklist when creating or auditing a Sampler-based project:
Standard Module Projects
- Project scaffolded with
New-SampleModuleor equivalent structure - Source code in
source/Public/andsource/Private/(one function per file) - Module manifest at
source/<ModuleName>.psd1with explicit exports - Empty
source/<ModuleName>.psm1placeholder -
build.ps1andResolve-Dependency.*present (standard, unmodified) -
build.yamlconfigured with correct workflows and PesterScriptkey -
RequiredModules.psd1lists all build and runtime dependencies -
GitVersion.ymlconfigured for your branching strategy -
ModuleBuildTasksincludes bothSamplerandSampler.GitHubTasks - Tests in
tests/QA/,tests/Unit/, and optionallytests/Integration/ - Tests use Pester 5 syntax with
BeforeAll/BeforeDiscoveryseparation - CI/CD pipeline with Build, Test (multi-edition), and Deploy stages
-
Agent.Source.Git.ShallowFetchDepth: 0in CI configuration - Deploy conditions include org-name filter
- Pipeline secrets configured (
GitHubToken,GalleryApiToken) -
output/in.gitignore - Community files present (CHANGELOG, CONTRIBUTING, CODE_OF_CONDUCT, SECURITY)
- README with badges (build status, gallery version, coverage)
-
.vscode/settings andtasks.jsonconfigured for PSScriptAnalyzer - First build succeeds:
./build.ps1 -ResolveDependency -Tasks test - Code coverage threshold set appropriately (start at 0, increase over time)
- Module GUID preserved from any prior publication
DSC / Datum Configuration Data Projects (Additional)
-
source/Datum.ymldefines resolution precedence and merge strategies - Node definitions in
source/AllNodes/<Environment>/<NodeName>.yml - Role definitions in
source/Roles/<Role>.yml - Baseline configurations in
source/Baselines/ -
RequiredModules.psd1includes Datum, DSC resources, and composite resource modules -
ModuleBuildTasksincludesSampler.DscPipeline,DscResource.Test,DscResource.DocGenerator -
Sampler.DscPipeline.DscCompositeResourceModulesconfigured inbuild.yaml -
SetPSModulePathconfigured withRemovePersonal: trueandRemoveProgramFiles: true -
BuiltModuleSubDirectory: Moduleset inbuild.yaml - PowerShell5Compatibility task present in
.build/for cross-edition builds -
tests/ConfigData/validates YAML structure and composite resource dependencies -
tests/Acceptance/verifies MOF artifacts post-build - HQRM tests configured via
DscTestsection inbuild.yaml - Pipeline publishes separate artifacts (MOF, MetaMOF, CompressedModules, RSOP)
- Build workflow includes DSC tasks (LoadDatumConfigData, CompileDatumRsop, CompileRootConfiguration)
References
- Sampler GitHub Repository
- Sampler on PowerShell Gallery
- ModuleBuilder
- InvokeBuild
- GitVersion Documentation
- Pester 5 Documentation
- PSScriptAnalyzer
- Keep a Changelog
- DSC Community Style Guidelines
- PSResourceGet
- ModuleFast
- DscWorkshop — Blueprint for DSC projects using Sampler + Datum
- Datum — Hierarchical configuration data management for DSC
- Sampler.DscPipeline — DSC pipeline build tasks for Sampler
- DscConfig.Demo — DSC composite resource collection with YAML reference documentation
- DscResource.Test — HQRM testing for DSC resources
- The Release Pipeline Model (Whitepaper)