microsoft/pester-mandatory-param-testing
Test mandatory parameters via parameter metadata inspection, not by invoking with missing args
npx skills add https://github.com/microsoft/ActiveDirectoryTierModel --skill pester-mandatory-param-testing
When testing that a cmdlet parameter is mandatory, there is an anti-pattern that works in CI/non-interactive environments but breaks in interactive consoles: invoking the cmdlet with the mandatory parameter missing and expecting Should -Throw.
In non-interactive hosts (CI pipelines, -NonInteractive mode), PowerShell throws a ParameterBindingException. However, in interactive consoles, PowerShell prompts the user for the missing value ("Supply values for the following parameters: ParameterName:") and blocks indefinitely waiting for input. This hangs test automation.
ANTI-PATTERN (DO NOT USE):
It "Mandatory parameters enforced: missing -Config throws" {
{ Get-SomeCommand -OtherParam "value" } | Should -Throw
}
✗ Works in CI; hangs in interactive console
RECOMMENDED PATTERN:
It "Config parameter is mandatory" {
$attr = (Get-Command Get-SomeCommand).Parameters['Config'].Attributes |
Where-Object { $_ -is [System.Management.Automation.ParameterAttribute] }
($attr.Mandatory -contains $true) | Should -BeTrue
}
✓ Works in both CI and interactive consoles; no cmdlet invocation risk; tests the declaration directly
VARIANT (More Explicit):
It "Config parameter has Mandatory attribute" {
$param = (Get-Command Get-SomeCommand).Parameters['Config']
$param | Should -Not -BeNullOrEmpty
$param.Attributes.ParameterAttribute.Mandatory | Should -Contain $true
}
✓ Equivalent; slightly more defensive guard
File: tests/Unit.WinLapsAclOperations.Tests.ps1
Before (Problematic):
It "Mandatory parameters enforced: missing -Config throws" {
{ Get-TierModelWinLapsAcl -DomainController $script:TestDC } | Should -Throw
}
It "Mandatory parameters enforced: missing -DomainController throws" {
{ Get-TierModelWinLapsAcl -Config $script:WinLapsConfig1 } | Should -Throw
}
After (Fixed):
It "Config parameter is mandatory" {
$attr = (Get-Command Get-TierModelWinLapsAcl).Parameters['Config'].Attributes |
Where-Object { $_ -is [System.Management.Automation.ParameterAttribute] }
($attr.Mandatory -contains $true) | Should -BeTrue
}
It "DomainController parameter is mandatory" {
$attr = (Get-Command Get-TierModelWinLapsAcl).Parameters['DomainController'].Attributes |
Where-Object { $_ -is [System.Management.Automation.ParameterAttribute] }
($attr.Mandatory -contains $true) | Should -BeTrue
}
Result: Tests still verify the parameter is [Parameter(Mandatory)], but now run cleanly in both CI and interactive consoles without hanging.
Mandatory=$true) without ambiguous invocation semanticsThis pattern applies to all mandatory parameter tests in Pester-based test suites. It is particularly important in repos with interactive development workflows (e.g., Hyper-V labs, manual test runs) where tests may run in interactive consoles alongside CI execution.
Take microsoft/pester-mandatory-param-testing from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.