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