By Tech Ents Team ยท January 8, 2025
IT PowerShell scripts tend to die for predictable reasons: they work on the original author's machine but not elsewhere (implicit dependencies), they fail silently when something changes, they have no logging so failures are invisible, and they aren't tested so a minor API change breaks them unnoticed.
The transition from script to tool starts with wrapping logic in functions with proper parameter validation. PowerShell's CmdletBinding and parameter attributes provide a rich validation framework:
function Set-UserMailboxQuota {
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string]$UserPrincipalName,
[Parameter(Mandatory)]
[ValidateRange(1, 100)]
[int]$QuotaGB
)
process {
if ($PSCmdlet.ShouldProcess($UserPrincipalName, "Set mailbox quota to ${QuotaGB}GB")) {
# implementation
}
}
}
SupportsShouldProcess gives you -WhatIf for free โ essential for safe automation.
PSFramework is the de facto standard for PowerShell logging in automation tooling. It provides structured logging to multiple targets (file, event log, database), log rotation, and a consistent logging API. Replace Write-Host and Write-Verbose with Write-PSFMessage and your scripts become auditable.
Set $ErrorActionPreference = 'Stop' at the top of automation scripts so non-terminating errors become terminating errors that your try/catch blocks can handle. Log errors with full context using $_.Exception.Message and $_.ScriptStackTrace.
Pester is the PowerShell testing framework. Unit tests for PowerShell automation are genuinely practical โ mock external dependencies (Get-ADUser, Send-MailMessage), test your function logic, and run tests in CI before deploying script changes to production. Even 20% code coverage on critical automation is transformative for reliability.
Credentials should never be hardcoded in scripts. Use the Microsoft.PowerShell.SecretManagement module with a vault backend (Azure Key Vault, Windows Credential Manager, or HashiCorp Vault) to retrieve credentials at runtime.