Skip to content

EvotecIT/PSPublishModule

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2,689 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PSPublishModule and PowerForge

PSPublishModule started as the Evotec module builder. It has grown into the PowerShell-facing surface for PowerForge: a build, packaging, documentation, release, private-gallery, and static-site automation toolkit used across EvotecIT projects.

Use it when you want repeatable PowerShell module builds, .NET publish matrices, MSI/MSIX/Store packaging, NuGet and PSGallery releases, generated PowerShell help, private gallery onboarding, GitHub housekeeping, or PowerForge.Web static site pipelines without rewriting the same build logic in every repository.

Packages

PowerShell Module

PowerShell Gallery version PowerShell Gallery preview PowerShell Gallery platforms PowerShell Gallery downloads

NuGet Packages and Tools

PowerForge PowerForge downloads PowerForge.PowerShell PowerForge.Build PowerForge.Web PowerForge.Web.Build

Project Information

Build Module DotNet publish tests license top language

Author and Social

Twitter follow Blog LinkedIn Discord

What It Is

PSPublishModule is the PowerShell module you install and import. PowerForge is the reusable engine underneath it. The repo also ships CLI tools:

  • powerforge from the PowerForge.Build .NET tool package.
  • powerforge-web from the PowerForge.Web.Build .NET tool package.

The same contracts are available from PowerShell cmdlets, JSON files, and CLI commands, so a project can start with a simple build script and later move the repeatable rules into checked-in JSON.

Main Capabilities

Area What it does Main entry points
PowerShell module build Builds script and binary modules, merges public/private functions, updates manifests, signs outputs, creates packed/unpacked artifacts, validates imports, runs tests, and generates help. Invoke-ModuleBuild, Build-Module, New-ConfigurationBuild, New-ConfigurationManifest, New-ConfigurationArtefact, New-ConfigurationValidation
Module dependencies and isolation Resolves required/external/approved modules, supports online dependency install, packages required modules, detects missing helpers, and imports selected modules through AssemblyLoadContext isolation profiles. New-ConfigurationModule, Get-MissingFunctions, Import-IsolatedModule, Test-IsolatedModuleProfile
Documentation and delivery Generates Markdown command docs, MAML external help, about topics, and bundled module documentation. It can also copy or render installed module docs from local files, GitHub, or Azure DevOps. New-ConfigurationDocumentation, New-ModuleAboutTopic, Show-ModuleDocumentation, Install-ModuleDocumentation, Install-ModuleScript
Private galleries Onboards users and publishers to private PowerShell module feeds, especially Azure Artifacts, without storing secrets in profiles. Initialize-ModuleRepository, Connect-ModuleRepository, Register-ModuleRepository, Install-PrivateModule, Update-PrivateModule, Publish-NugetPackage
.NET publish and packaging Builds publish matrices for apps, services, tools, bundles, plugins, MSI, MSIX, Microsoft Store packages, appinstaller files, signing, checksums, and manifests. New-DotNetPublishConfig, Invoke-DotNetPublish, Invoke-PowerForgeBundlePostProcess, Invoke-PowerForgePluginExport, Invoke-PowerForgePluginPack
Unified release Coordinates module artifacts, NuGet packages, tool binaries, installers, GitHub releases, staging folders, checksums, Winget manifests/submission, and release manifests from one release config. New-PowerForgeReleaseConfig, Invoke-PowerForgeRelease, Invoke-ProjectRelease, Invoke-ProjectBuild, powerforge release
GitHub housekeeping Prunes Actions artifacts and caches, performs runner cleanup, and provides reusable workflows/actions for cross-repo maintenance. powerforge github housekeeping, .github/workflows/powerforge-github-housekeeping.yml
Static websites and API docs Builds PowerForge.Web sites, docs, blogs, search indexes, API docs, project hubs, SEO assets, sitemaps, quality gates, audits, and deployment artifacts. powerforge-web build, powerforge-web pipeline, powerforge-web verify, powerforge-web audit, powerforge-web scaffold
Project hygiene Checks or fixes line endings/encoding, removes comments or project files, reads versions, and summarizes test failures. Get-ProjectConsistency, Convert-ProjectConsistency, Get-ProjectVersion, Set-ProjectVersion, Get-ModuleTestFailures

Supported Runtimes

Surface Targets
PSPublishModule Windows PowerShell 5.1 and PowerShell 7+
PowerForge .NET Framework 4.7.2, .NET 8, .NET 10
PowerForge.PowerShell .NET Framework 4.7.2, .NET 8, .NET 10
PowerForge.Cli / powerforge .NET 8 and .NET 10
PowerForge.Web / powerforge-web .NET 8 and .NET 10

Install

Install the PowerShell module from PSGallery:

Install-Module -Name PSPublishModule -Scope CurrentUser

If you are updating an older install or replacing a prerelease build, this is the usual maintainer-friendly command:

Install-Module -Name PSPublishModule -AllowClobber -Force -SkipPublisherCheck

Install the CLI tools when you prefer JSON-first automation from shell scripts or CI:

dotnet tool install --global PowerForge.Build
dotnet tool install --global PowerForge.Web.Build

Update later with:

Update-Module -Name PSPublishModule
dotnet tool update --global PowerForge.Build
dotnet tool update --global PowerForge.Web.Build

If a production build depends on a known-good version, pin and test upgrades intentionally. PSPublishModule and PowerForge expose build/release contracts, so small parameter or manifest changes can affect automation.

Quick Start: Build a PowerShell Module

Scaffold a starter module:

Import-Module PSPublishModule

Build-Module -ModuleName 'MyModule' -Path 'C:\Git'

Build an existing module with a PowerShell DSL:

Invoke-ModuleBuild -ModuleName 'MyModule' -Path 'C:\Git' -Settings {
    New-ConfigurationBuild -Enable
    New-ConfigurationManifest -Description 'My module' -PowerShellVersion '5.1'
    New-ConfigurationDocumentation -Enable -Path 'Docs' -PathReadme 'Docs\Readme.md' -AboutTopicsSourcePath 'Help\About'
    New-ConfigurationArtefact -Type Packed -Enable
    New-ConfigurationValidation -Enable
}

Common module build outputs include:

  • a refreshed module manifest,
  • packed and unpacked artifacts,
  • generated Markdown command docs,
  • generated external help XML,
  • about topic docs,
  • validation/test summaries,
  • signed module files when signing is configured.

See Docs/PSPublishModule.ModuleDocumentation.md and Module/Docs/Invoke-ModuleBuild.md.

Full Module Builder Example

The quick path creates the initial module structure, manifest, and build script:

Import-Module PSPublishModule

Build-Module -ModuleName 'MyGreatModule' -Path 'C:\Support\GitHub'

The scaffold creates the standard folders and starting files needed to build and publish the module.

New module scaffold

The generated structure is intentionally boring: public/private functions, manifest, docs, tests, build script, and artifact locations are laid out in the same way across modules.

Generated module structure

After the scaffold exists, the module can be built repeatedly with a DSL script. This is the pattern used by Evotec modules: the build script owns project-specific values, while PSPublishModule/PowerForge owns the reusable build, validation, packaging, signing, and publishing behavior.

Build-Module -ModuleName 'MyGreatModule' -Path 'C:\Support\GitHub' {
    $Manifest = [ordered] @{
        ModuleVersion        = '1.0.0'
        CompatiblePSEditions = @('Desktop', 'Core')
        GUID                 = '330e259e-799f-415d-8247-4843127620a1'
        Author               = 'Author'
        CompanyName          = 'CompanyName'
        Copyright            = "(c) 2011 - $((Get-Date).Year) Author @ CompanyName. All rights reserved."
        Description          = 'Simple project MyGreatModule'
        PowerShellVersion    = '5.1'
        Tags                 = @('Windows', 'MacOS', 'Linux')
        ProjectUri           = 'https://github.com/CompanyName/MyGreatModule'
    }
    New-ConfigurationManifest @Manifest

    New-ConfigurationModule -Type RequiredModule -Name 'PSSharedGoods' -Guid 'Auto' -Version 'Latest'

    New-ConfigurationModule -Type ApprovedModule -Name @(
        'PSSharedGoods'
        'PSWriteColor'
        'Connectimo'
        'PSUnifi'
        'PSWebToolbox'
        'PSMyPassword'
    )

    New-ConfigurationModuleSkip -IgnoreFunctionName 'Invoke-Formatter', 'Find-Module'

    $format = [ordered] @{
        RemoveComments                              = $false
        PlaceOpenBraceEnable                        = $true
        PlaceOpenBraceOnSameLine                    = $true
        PlaceOpenBraceNewLineAfter                  = $true
        PlaceOpenBraceIgnoreOneLineBlock            = $false
        PlaceCloseBraceEnable                       = $true
        PlaceCloseBraceNewLineAfter                 = $true
        PlaceCloseBraceIgnoreOneLineBlock           = $false
        PlaceCloseBraceNoEmptyLineBefore            = $true
        UseConsistentIndentationEnable              = $true
        UseConsistentIndentationKind                = 'space'
        UseConsistentIndentationPipelineIndentation = 'IncreaseIndentationAfterEveryPipeline'
        UseConsistentIndentationIndentationSize     = 4
        UseConsistentWhitespaceEnable               = $true
        UseConsistentWhitespaceCheckInnerBrace      = $true
        UseConsistentWhitespaceCheckOpenBrace       = $true
        UseConsistentWhitespaceCheckOpenParen       = $true
        UseConsistentWhitespaceCheckOperator        = $true
        UseConsistentWhitespaceCheckPipe            = $true
        UseConsistentWhitespaceCheckSeparator       = $true
        AlignAssignmentStatementEnable              = $true
        AlignAssignmentStatementCheckHashtable      = $true
        UseCorrectCasingEnable                      = $true
    }

    New-ConfigurationFormat -ApplyTo 'OnMergePSM1', 'OnMergePSD1' -Sort None @format
    New-ConfigurationFormat -ApplyTo 'DefaultPSD1', 'DefaultPSM1' -EnableFormatting -Sort None
    New-ConfigurationFormat -ApplyTo 'DefaultPSD1', 'OnMergePSD1' -PSD1Style 'Minimal'

    New-ConfigurationDocumentation `
        -Enable `
        -PathReadme 'Docs\Readme.md' `
        -Path 'Docs' `
        -AboutTopicsSourcePath 'Help\About'

    New-ConfigurationImportModule -ImportSelf -ImportRequiredModules

    New-ConfigurationBuild `
        -Enable `
        -DeleteTargetModuleBeforeBuild `
        -MergeModuleOnBuild `
        -SignModule:$false

    New-ConfigurationArtefact `
        -Type Unpacked `
        -Enable `
        -Path "$PSScriptRoot\..\Artefacts" `
        -RequiredModulesPath "$PSScriptRoot\..\Artefacts\Modules"

    New-ConfigurationArtefact `
        -Type Packed `
        -Enable `
        -Path "$PSScriptRoot\..\Releases" `
        -IncludeTagName

    New-ConfigurationPublish `
        -Type PowerShellGallery `
        -FilePath 'C:\Support\Important\PowerShellGalleryAPI.txt' `
        -Enabled:$false

    New-ConfigurationPublish `
        -Type GitHub `
        -FilePath 'C:\Support\Important\GitHubAPI.txt' `
        -UserName 'CompanyName' `
        -Enabled:$false
}

The older hashtable-style configuration is still supported for compatibility, but the New-Configuration* DSL is the preferred style for new and actively maintained modules.

Quick Start: Private PowerShell Galleries

Create a non-secret private gallery profile for Azure Artifacts:

Initialize-ModuleRepository -ProfileName Company -Organization contoso -Project Platform -Feed Modules -InstallPrerequisites

Export/import the same settings for other users or build machines:

Export-ModuleRepositoryProfile -Name Company -Path .\Company.profile.json -Force
Import-ModuleRepositoryProfile -Path .\Company.profile.json -Overwrite
Connect-ModuleRepository -ProfileName Company -InstallPrerequisites

Install and update modules through the profile:

Install-PrivateModule -ProfileName Company -Name ModuleA
Update-PrivateModule -ProfileName Company -Name ModuleA

Publish packages to the saved feed:

Publish-NugetPackage -Path .\Artifacts -ProfileName Company -SkipDuplicate

See Docs/PSPublishModule.PrivateGalleries.md and Get-Help about_PrivateGalleries.

Quick Start: .NET Publish and Packaging

Scaffold a JSON config:

New-DotNetPublishConfig -ProjectRoot '.' -PassThru

Plan and run:

Invoke-DotNetPublish -ConfigPath '.\powerforge.dotnetpublish.json' -Validate
Invoke-DotNetPublish -ConfigPath '.\powerforge.dotnetpublish.json' -Plan
Invoke-DotNetPublish -ConfigPath '.\powerforge.dotnetpublish.json' -ExitCode

The same flow is available through the CLI:

powerforge dotnet scaffold --project-root . --output json
powerforge dotnet publish --config .\powerforge.dotnetpublish.json --plan
powerforge dotnet publish --config .\powerforge.dotnetpublish.json --output json

The DotNet publish engine can produce publish folders, zip files, service scripts, bundle layouts, plugin folders/packages, generated MSI authoring, MSI outputs, MSIX/Store packages, appinstaller files, manifests, checksums, and signing reports.

See Docs/PSPublishModule.DotNetPublish.Quickstart.md.

Quick Start: Unified Release

Generate a starter release config:

New-PowerForgeReleaseConfig -ProjectRoot . -PassThru

Plan or run the release:

Invoke-PowerForgeRelease -ConfigPath .\Build\release.json -Plan
Invoke-PowerForgeRelease -ConfigPath .\Build\release.json

CLI equivalent:

powerforge release --config .\Build\release.json --plan

The unified release engine is designed for repositories that need several outputs at once: module packages, NuGet packages, portable tools, installers, GitHub release uploads, Winget manifests/submission, checksums, and categorized upload-ready staging folders.

See Docs/PSPublishModule.ProjectBuild.md.

Quick Start: PowerForge.Web

PowerForge.Web is the static-site engine in this repository. It is used for documentation sites, API reference portals, project hubs, blog/news content, search, SEO assets, sitemaps, quality gates, and CI-friendly audits.

Create or standardize a site:

powerforge-web scaffold --out .\Website --name "My Site" --base-url "https://example.com" --engine scriban

Run a local pipeline:

powerforge-web pipeline --config .\pipeline.json --mode dev

Run CI-style gates locally:

powerforge-web pipeline --config .\pipeline.json --mode ci

Recommended site contracts include:

  • explicit Features in site.json,
  • pipeline.json with dev and CI modes,
  • committed .powerforge/verify-baseline.json,
  • committed .powerforge/audit-baseline.json,
  • strict CI gates with failOnNewWarnings and failOnNewIssues,
  • a theme manifest with feature contracts.

See Docs/PowerForge.Web.WebsiteStarter.md, Docs/PowerForge.Web.QualityGates.md, and Docs/PowerForge.Web.Roadmap.md.

GitHub Housekeeping

PowerForge can clean GitHub Actions artifacts, caches, and runner workspace pressure with safe dry-run defaults:

powerforge github artifacts prune --name "test-results*,coverage*,github-pages"
powerforge github caches prune --key "ubuntu-*,windows-*" --keep 1 --max-age-days 14
powerforge github runner cleanup --apply --min-free-gb 20
powerforge github housekeeping --config .\.powerforge\github-housekeeping.json --apply

Reusable workflow example:

permissions:
  contents: read
  actions: write

jobs:
  housekeeping:
    uses: EvotecIT/PSPublishModule/.github/workflows/powerforge-github-housekeeping.yml@main
    with:
      config-path: ./.powerforge/github-housekeeping.json
    secrets: inherit

Command Families

PSPublishModule exports commands in these families:

  • Invoke-*: run build, test, publish, release, plugin, and repository workflows.
  • New-Configuration*: create DSL objects for module, .NET publish, release, installer, signing, documentation, validation, and compatibility configuration.
  • New-*Config: scaffold JSON configuration files.
  • Get-* / Test-*: inspect module metadata, repository profiles, compatibility, project consistency, versions, isolated module profiles, and test failures.
  • Install-* / Update-* / Register-* / Connect-*: manage module docs/scripts and private gallery repositories.
  • Publish-* / Send-*: publish NuGet packages and GitHub release assets.
  • powerforge: JSON-first CLI for release, .NET publish, GitHub housekeeping, plugin export/pack, bundle post-process, and related automation.
  • powerforge-web: static-site and API-docs CLI.

Generated command reference lives in Module/Docs/Readme.md.

Repository Layout

Path Purpose
PSPublishModule/ Binary PowerShell module cmdlets.
PowerForge/ Host-neutral build, release, packaging, and workflow engine.
PowerForge.PowerShell/ PowerShell runtime adapters, module build execution, help extraction, signing, Pester, and repository tooling.
PowerForge.Cli/ powerforge command-line tool.
PowerForge.Web/ Static-site, API-docs, search, SEO, audit, and verification engine.
PowerForge.Web.Cli/ powerforge-web command-line tool.
PowerForgeStudio.* Current PowerForge Studio experiments and hosts.
Module/ Packaged PSPublishModule output, generated command docs, external help, tests, and module build script.
Docs/ Durable design notes, quickstarts, roadmaps, and workflow documentation.
Schemas/ JSON schemas for PowerForge configs.
Build/ Repo release/build entrypoints and release configuration.

Build This Repository

Run the full solution tests:

dotnet test .\PSPublishModule.sln -c Release

Run the module build:

.\Module\Build\Build-Module.ps1

Run the unified release plan:

.\Build\Build-Project.ps1 -Plan

Build release artifacts:

.\Build\Build-Project.ps1

Build only the CLI tools:

.\Build\Build-Project.ps1 -ToolsOnly

Documentation

Start here:

Support This Project

If PSPublishModule or PowerForge saves you time, sponsorship helps keep the project maintained and improving:

Sponsorship is optional. The project remains open-source and available for everyone.

License

PSPublishModule and PowerForge are released under the license in LICENSE.

About

This module is a module builder helper that helps build PowerShell modules "Evotec way". It allows us to make sure our modules are built the same way every time making the process really easy to build and publish new versions.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Sponsor this project

 

Contributors

Languages