mcpbeat

Pester Mandatory Param Testing

microsoft/pester-mandatory-param-testing

Test mandatory parameters via parameter metadata inspection, not by invoking with missing args

1k tokens
context cost
the whole folder, loaded on every use
1
files
instructions only
0
copies elsewhere
how many repositories repackaged it
343
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/microsoft/ActiveDirectoryTierModel --skill pester-mandatory-param-testing

The instruction itself

7 sections, as written by the author

Context

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.

Patterns

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

Examples

Real-World Example: Windows LAPS Cmdlet Tests

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.

Anti-Patterns

  • Invoking cmdlet with missing mandatory params + Should -Throw → Use metadata inspection instead
  • Assuming CI behavior (throw) applies to interactive hosts → Always test both environments or use host-agnostic patterns
  • Mocking Get-Command to fake parameter metadata → Get-Command is stable; test it directly

Why This Matters

  • Test Automation: Hanging tests block CI/CD pipelines and interactive development workflows
  • Host Agnosticism: Tests should pass the same way regardless of PowerShell host (console, ISE, CI runner, etc.)
  • Clarity: Metadata inspection is explicit — the test directly verifies the intended declaration (Mandatory=$true) without ambiguous invocation semantics
  • Defensibility: No reliance on exception handling behavior, which can change across PowerShell versions or host contexts

Scope

This 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.

How to use it

Copy the folder

Take microsoft/pester-mandatory-param-testing from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

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.