(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisbon
PowerShell
PowerShell 1 min

Pester: automated tests for PowerShell scripts and infrastructure

João Barros 12 de May de 2026 1 min read

Pester is the native PowerShell testing framework, included in Windows by default and used to validate scripts, modules and infrastructure configuration. Pester tests make PowerShell scripts production-ready.

Install and basic structure

Install-Module Pester -Force -Scope CurrentUser

# Structure of a test file (Get-UserInfo.Tests.ps1)
BeforeAll {
    . "$PSScriptRoot/Get-UserInfo.ps1"  # import the script under test
}

Describe "Get-UserInfo" {
    Context "Valid user" {
        It "Returns an object with DisplayName" {
            $result = Get-UserInfo -UPN "admin@company.com"
            $result.DisplayName | Should -Not -BeNullOrEmpty
        }
        It "Returns the correct email" {
            $result = Get-UserInfo -UPN "admin@company.com"
            $result.Mail | Should -Be "admin@company.com"
        }
    }

    Context "Invalid user" {
        It "Throws an error for an invalid UPN" {
            { Get-UserInfo -UPN "doesnotexist@company.com" } | Should -Throw
        }
    }
}

Mocking — isolate external dependencies

BeforeAll { . "$PSScriptRoot/Send-Report.ps1" }

Describe "Send-Report" {
    It "Calls Send-MailMessage with the correct recipient" {
        Mock Send-MailMessage { }  # does not send a real email

        Send-Report -To "manager@company.com" -Subject "Report"

        Should -Invoke Send-MailMessage -Times 1 `
            -ParameterFilter { $To -eq "manager@company.com" }
    }
}

Azure infrastructure tests

Describe "Azure infrastructure — rg-analytics-prod" {
    BeforeAll { Connect-AzAccount -Identity }

    It "Storage Account exists" {
        Get-AzStorageAccount -ResourceGroupName "rg-analytics-prod" `
            -Name "stadatalakeprod" | Should -Not -BeNullOrEmpty
    }
    It "Key Vault has soft-delete enabled" {
        $kv = Get-AzKeyVault -VaultName "kv-bconcepts-prod"
        $kv.EnableSoftDelete | Should -Be $true
    }
}

Integrate into Azure DevOps

- task: PowerShell@2
  inputs:
    targetType: inline
    script: |
      Install-Module Pester -Force -Scope CurrentUser
      $result = Invoke-Pester -Path ./tests -PassThru
      if ($result.FailedCount -gt 0) { exit 1 }

Conclusion

PowerShell scripts without tests are a risk in production. Pester makes it trivial to write unit tests (with mocks to isolate APIs) and infrastructure tests (to validate post-deploy state). Integrate them into CI/CD pipelines to prevent regressions.

Share: