Template: ps-module¶
Scaffold for a PowerShell module that exports cmdlets or functions. Used by azurelocal-ranger, azurelocal-s2d-cartographer, azurelocal-toolkit, azurelocal-vm-conversion-toolkit.
When to pick this variant¶
- The repo's primary output is a
.psd1+.psm1module. - Consumers are other PS scripts, runbooks, or CI pipelines.
- PSScriptAnalyzer + Pester are the expected test tools.
What's in the template¶
templates/ps-module/
├── .github/workflows/
│ ├── deploy-docs.yml # Calls reusable-mkdocs-deploy.yml
│ ├── validate.yml # Calls reusable-ps-module-ci.yml
│ └── publish-psgallery.yml # Publishes to PSGallery on tag (optional)
├── {{MODULE_NAME}}.psd1 # Manifest, token-substituted
├── {{MODULE_NAME}}.psm1 # Module code, token-substituted
├── mkdocs.yml # Docs site config
└── README.md # Token-substituted
Filename token {{MODULE_NAME}} is replaced at scaffold time — e.g., azurelocal-foo → AzureLocalFoo.psd1.
.psd1 manifest defaults¶
@{
RootModule = '{{MODULE_NAME}}.psm1'
ModuleVersion = '0.1.0'
CompatiblePSEditions = @('Core')
GUID = '{{MODULE_GUID}}'
Author = 'Azure Local'
CompanyName = 'AzureLocal'
Copyright = '(c) {{YEAR}} Azure Local. MIT License.'
Description = '{{DESCRIPTION}}'
PowerShellVersion = '7.2'
FunctionsToExport = @() # ← fill in after authoring
CmdletsToExport = @()
VariablesToExport = @()
AliasesToExport = @()
PrivateData = @{
PSData = @{
Tags = @('AzureLocal')
ProjectUri = 'https://github.com/AzureLocal/{{REPO_NAME}}'
LicenseUri = 'https://github.com/AzureLocal/{{REPO_NAME}}/blob/main/LICENSE'
}
}
}
CI caller — validate.yml¶
name: Validate
on:
pull_request: {}
push:
branches: [main]
jobs:
ci:
uses: AzureLocal/platform/.github/workflows/reusable-ps-module-ci.yml@main
with:
module-manifest: ./{{MODULE_NAME}}.psd1
run-psscriptanalyzer: true
psscriptanalyzer-path: .
run-pester: true
pester-test-path: tests
pester-result-format: NUnitXml
validate-maproom: false # flip to true if MAPROOM consumer
maproom-fixture-path: tests/maproom/fixtures
Docs — mkdocs.yml¶
Includes navigation.tabs, Material theme, GitHub edit icon, code-copy buttons.
PSGallery publish¶
publish-psgallery.yml triggers on tag push and requires NUGET_API_KEY repo secret. Ships empty — authoring the Publish-Module call is a one-time per-repo step.
Tokens used in this variant¶
| Token | Usage |
|---|---|
{{REPO_NAME}} | mkdocs.yml, README.md, .psd1 ProjectUri/LicenseUri |
{{MODULE_NAME}} | Filenames and in-file references |
{{DESCRIPTION}} | Manifest Description, README, mkdocs site description |
{{YEAR}} | Copyright lines |
{{MODULE_GUID}} | Manifest GUID |
{{AUDIT_DATE}} | .azurelocal-platform.yml lastAudited |
Post-scaffold steps¶
- Add actual source to
{{MODULE_NAME}}.psm1or split intoPublic/,Private/,Classes/subfolders. - Populate
FunctionsToExportin the manifest. - Add Pester tests under
tests/. - If publishing to PSGallery: set
NUGET_API_KEYsecret. - Author
docs/index.md(mkdocs will fail without one).
Example consumers¶
azurelocal-ranger— reference implementationazurelocal-s2d-cartographer— also consumes MAPROOMazurelocal-vm-conversion-toolkit
Related¶
- Reusable workflow: ps-module-ci
- MAPROOM overview — if the module produces cluster-shaped output