Functions, modules and reuse
As the ZEUS probes grow, copying the same functions between scripts becomes a problem. The solution is modules — packages of functions with a clearly defined public API. This lesson shows how we build them.
From a script to a function
We extract a reusable piece of logic into a Verb-Noun function with
[CmdletBinding()].
function ConvertTo-LsnResult {
[CmdletBinding()]
param(
[Parameter(Mandatory)] $Data,
[switch]$AsJson
)
if ($AsJson) {
$Data | ConvertTo-Json -Depth 6 -Compress
} else {
$Data
}
}
Script module (.psm1)
We group related functions in a .psm1 module file. A module is imported once,
and its functions are available like built-in cmdlets.
LsnProbe/
├── LsnProbe.psd1 # manifest (metadata, version, exports)
├── LsnProbe.psm1 # implementation
├── Public/ # exported functions
│ ├── Get-LsnForest.ps1
│ ├── Get-LsnInventory.ps1
│ └── Get-LsnPerf.ps1
└── Private/ # helper functions (not exported)
└── Invoke-LsnLdapPaged.ps1
In .psm1 we load the files and explicitly export only the public functions:
# LsnProbe.psm1
$public = Get-ChildItem "$PSScriptRoot/Public/*.ps1"
$private = Get-ChildItem "$PSScriptRoot/Private/*.ps1"
foreach ($file in @($public + $private)) {
. $file.FullName
}
Export-ModuleMember -Function $public.BaseName
ProfessNet standard: we split a module into
Public/(the external API) andPrivate/(helpers). We export only the public functions viaExport-ModuleMember. Helpers likeInvoke-LsnLdapPagedstay internal.
Manifest (.psd1)
The manifest describes the module: version, dependencies, which functions it exports.
@{
RootModule = 'LsnProbe.psm1'
ModuleVersion = '1.4.0'
PowerShellVersion = '5.1'
FunctionsToExport = @('Get-LsnForest', 'Get-LsnInventory', 'Get-LsnPerf')
PrivateData = @{ PSData = @{ Tags = @('ZEUS', 'AD', 'inventory') } }
}
ProfessNet standard: we list
FunctionsToExportexplicitly (not'*') — this speeds up loading and documents the public API. We bump the module version according to SemVer.
Comment-based help
We document public functions with a comment that feeds Get-Help.
function Get-LsnInventory {
<#
.SYNOPSIS
Collects a host inventory from an AD forest.
.PARAMETER Forest
The forest name, e.g. corp.local.
.EXAMPLE
Get-LsnInventory -Forest corp.local -AsJson
#>
[CmdletBinding()]
param([Parameter(Mandatory)][string]$Forest, [switch]$AsJson)
# ...
}
| File | Contains |
|---|---|
*.psd1 (manifest) | metadata, version, the export list |
*.psm1 (module) | loading files, Export-ModuleMember |
Public/*.ps1 | API functions |
Private/*.ps1 | helpers, not exported |
Tip: test the module with Pester (the PowerShell test framework). Import the module in tests via
Import-Module ./LsnProbe -Forceand check the public functions.
Verb-Noun functions, the Public/Private split, a manifest with an
explicit export and comment-based help — that's how we build reusable probe
modules. One module instead of ten copies of the same logic.