fix: improve error handling in PowerShell guidelines (#280)

Update error handling examples to use $PSCmdlet.WriteError() and
$PSCmdlet.ThrowTerminatingError() instead of Write-Error and throw for better PowerShell cmdlet integration.
This commit is contained in:
oceans-of-time 2025-10-08 11:18:27 +11:00 committed by GitHub
parent c95af033c9
commit 897d61b03f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -5,7 +5,8 @@ description: 'PowerShell cmdlet and scripting best practices based on Microsoft
# PowerShell Cmdlet Development Guidelines
This guide provides PowerShell-specific instructions to help GitHub Copilot generate idiomatic, safe, and maintainable scripts. It aligns with Microsofts PowerShell cmdlet development guidelines.
This guide provides PowerShell-specific instructions to help GitHub Copilot generate idiomatic,
safe, and maintainable scripts. It aligns with Microsofts PowerShell cmdlet development guidelines.
## Naming Conventions
@ -150,7 +151,7 @@ function Update-ResourceStatus {
)
begin {
Write-Verbose "Starting resource status update process"
Write-Verbose 'Starting resource status update process'
$timestamp = Get-Date
}
@ -166,13 +167,13 @@ function Update-ResourceStatus {
}
# Only output if PassThru is specified
if ($PassThru) {
if ($PassThru.IsPresent) {
Write-Output $resource
}
}
end {
Write-Verbose "Resource status update process completed"
Write-Verbose 'Resource status update process completed'
}
}
```
@ -198,6 +199,9 @@ function Update-ResourceStatus {
- Return meaningful error messages
- Use ErrorVariable when needed
- Include proper terminating vs non-terminating error handling
- In advanced functions with `[CmdletBinding()]`, prefer `$PSCmdlet.WriteError()` over `Write-Error`
- In advanced functions with `[CmdletBinding()]`, prefer `$PSCmdlet.ThrowTerminatingError()` over `throw`
- Construct proper ErrorRecord objects with category, target, and exception details
- **Non-Interactive Design:**
- Accept input via parameters
@ -220,7 +224,7 @@ function Remove-UserAccount {
)
begin {
Write-Verbose "Starting user account removal process"
Write-Verbose 'Starting user account removal process'
$ErrorActionPreference = 'Stop'
}
@ -228,7 +232,13 @@ function Remove-UserAccount {
try {
# Validation
if (-not (Test-UserExists -Username $Username)) {
Write-Error "User account '$Username' not found"
$errorRecord = [System.Management.Automation.ErrorRecord]::new(
[System.Exception]::new("User account '$Username' not found"),
'UserNotFound',
[System.Management.Automation.ErrorCategory]::ObjectNotFound,
$Username
)
$PSCmdlet.WriteError($errorRecord)
return
}
@ -241,19 +251,27 @@ function Remove-UserAccount {
Remove-ADUser -Identity $Username -ErrorAction Stop
Write-Warning "User account '$Username' has been removed"
}
}
catch [Microsoft.ActiveDirectory.Management.ADException] {
Write-Error "Active Directory error: $_"
throw
}
catch {
Write-Error "Unexpected error removing user account: $_"
throw
} catch [Microsoft.ActiveDirectory.Management.ADException] {
$errorRecord = [System.Management.Automation.ErrorRecord]::new(
$_.Exception,
'ActiveDirectoryError',
[System.Management.Automation.ErrorCategory]::NotSpecified,
$Username
)
$PSCmdlet.ThrowTerminatingError($errorRecord)
} catch {
$errorRecord = [System.Management.Automation.ErrorRecord]::new(
$_.Exception,
'UnexpectedError',
[System.Management.Automation.ErrorCategory]::NotSpecified,
$Username
)
$PSCmdlet.ThrowTerminatingError($errorRecord)
}
}
end {
Write-Verbose "User account removal process completed"
Write-Verbose 'User account removal process completed'
}
}
```
@ -307,12 +325,12 @@ function New-Resource {
)
begin {
Write-Verbose "Starting resource creation process"
Write-Verbose 'Starting resource creation process'
}
process {
try {
if ($PSCmdlet.ShouldProcess($Name, "Create new resource")) {
if ($PSCmdlet.ShouldProcess($Name, 'Create new resource')) {
# Resource creation logic here
Write-Output ([PSCustomObject]@{
Name = $Name
@ -320,14 +338,19 @@ function New-Resource {
Created = Get-Date
})
}
}
catch {
Write-Error "Failed to create resource: $_"
} catch {
$errorRecord = [System.Management.Automation.ErrorRecord]::new(
$_.Exception,
'ResourceCreationFailed',
[System.Management.Automation.ErrorCategory]::NotSpecified,
$Name
)
$PSCmdlet.ThrowTerminatingError($errorRecord)
}
}
end {
Write-Verbose "Completed resource creation process"
Write-Verbose 'Completed resource creation process'
}
}
```