This module is used to build, update and publish modules.
I have switched my workflow for making modules a few times now, from creating a module from the ground up to having a script put the scaffolding together for the PSD1 and PSM1 files.
Currently I am using a method of compiling separate functions into a module along with creating all of the necessary files, this is by far my favorite way of doing it as it is much easier to work on when the modules get larger and more complicated as everything can be separated at the function level. It can also allow you to separate Public and Private functions, I do not currently do this as I have yet to find a need for it in my environment.
Here is an example of how I currently have my code structured. You don’t necessarily have to follow the same structure but the build module may need some adjusting to work with a different structure.
function Build { <# .DESCRIPTION Developer: Mike Polselli PSVersion: 5.0 Language: PowerShell Purpose: This script will compile scripts into a module. Its purpose is to create a module while leaving the "Functions" as individual scripts for easy management and updating. .PARAMETER Help Displays helpful information about the script. .PARAMETER Identity Identifies the module you wish to build. .PARAMETER NewModule Used when you are building a new module, this will create the necessary files and prompt for a description. .PARAMETER Publish Publishes the module to the CompanyName Repository. .PARAMETER Update Updates the module manifest, uses the Microsoft versioning standard. .EXAMPLE Build -Help .EXAMPLE Build -Identity Logging .EXAMPLE Build -Identity Logging -Publish -Update Revision .EXAMPLE Build -Identity SomeModule -NewModule Enter a description for SomeModule.: This is a description of the module. #> [cmdletbinding(DefaultParameterSetName = "Primary")] param ( [Parameter(ParameterSetName = "NewModule", Position = 0, Mandatory = $true)] [Parameter(ParameterSetName = "Publish", Position = 0, Mandatory = $true)] [Parameter(ParameterSetName = "Primary", Position = 0, Mandatory = $true)] [string]$Identity, [Parameter(ParameterSetName = "NewModule", Position = 1)] [switch]$NewModule, [Parameter(ParameterSetName = "Publish", Position = 2)] [switch]$Publish, [Parameter(ParameterSetName = "Publish", Position = 3)] [ValidateSet('Major', 'Minor', 'Build', 'Revision')] [string]$Update, [Parameter(ParameterSetName = "Help")][switch]$Help ) if ($Help) { Get-Help $MyInvocation.MyCommand.Name -Full | more break } $Path = "\\$env:USERDNSDOMAIN\Path\To\Module\Scripts" $NewPath = $Path | Split-Path -Parent if ($NewModule) { # Creates required files and folders for the new module. try { # This will stop existing modules from being overwritten. New-Item -Path $NewPath\$Identity -ItemType Directory -ErrorAction Stop New-Item -Path $NewPath\$Identity\$Identity'.psm1' -ItemType File $Properties = @{ Path = "$NewPath\$Identity\$Identity.psd1" Author = 'YourName' CompanyName = 'CompanyName' Description = Read-Host -Prompt "Enter a description for $Identity." ModuleVersion = '1.0.0.0' RootModule = $Identity } New-ModuleManifest @Properties } catch { Write-Warning "The module $Identity already exists!" break } } $Scripts = Get-ChildItem $Path\$Identity -Include *.ps1 -Recurse $Module = Get-ChildItem $NewPath\$Identity -Include *.psm1 -Recurse $Manifest = Get-ChildItem $NewPath\$Identity -Include *.psd1 -Recurse $Functions = @() Set-Content -Path $Module -Value $null foreach ($Script in $Scripts) { # Adds Functions to the module. # Adds the Function names to an array to export. $Code = Get-Content -Path $Script.FullName Add-Content -Path $Module -Value $Code -Force Add-Content -Path $Module -Value "`n" -Force $Functions += $Script.Name.Split('.')[0] } Update-ModuleManifest -Path $Manifest -FunctionsToExport $Functions $GetFile = Get-ChildItem -Path $NewPath\$Identity *.psd1 Test-ModuleManifest -Path $GetFile.FullName if ($Publish) { # Publishes the module. $GetCurrentVersion = Get-Content -Path $GetFile.FullName | Select-String -Pattern '^ModuleVersion = (.*)' [version]$CurrentVersion = $GetCurrentVersion.Matches.Groups[1].Value.Replace("'", '') switch ($Update) { Major { $UpdatedVersion = "{0}.{1}.{2}.{3}" -f ($CurrentVersion.Major + 1), $CurrentVersion.Minor, $CurrentVersion.Build, $CurrentVersion.Revision } Minor { $UpdatedVersion = "{0}.{1}.{2}.{3}" -f $CurrentVersion.Major, ($CurrentVersion.Minor + 1 ), $CurrentVersion.Build, $CurrentVersion.Revision } Build { $UpdatedVersion = "{0}.{1}.{2}.{3}" -f $CurrentVersion.Major, $CurrentVersion.Minor, ($CurrentVersion.Build + 1), $CurrentVersion.Revision } Revision { $UpdatedVersion = "{0}.{1}.{2}.{3}" -f $CurrentVersion.Major, $CurrentVersion.Minor, $CurrentVersion.Build, ($CurrentVersion.Revision + 1) } } (Get-Content -Path $GetFile.FullName -Raw) -replace $GetCurrentVersion.Matches.Groups[1].Value, $UpdatedVersion.Insert($UpdatedVersion.Length, "'").Insert(0, "'") | Set-Content -Path $GetFile.FullName Publish-Module -Path $NewPath\$Identity -Repository RepositoryName } } $IdentityBlock = { param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameter) $Path = "\\$env:USERDNSDOMAIN\Path\To\Module\Scripts" (Get-ChildItem $Path).Name | Where-Object { $PSItem -like "$WordToComplete*" } | ForEach-Object { "$PSItem" } } Register-ArgumentCompleter -CommandName Build -ParameterName Identity -ScriptBlock $IdentityBlock