Florian Feldhaus
Florian Feldhaus

Reputation: 5932

How to ensure that a logging Cmdlet is called for every exception in a PowerShell script module?

In a PowerShell (5.1 and later) Script Module, I want to ensure that every Script and System exception which is thrown calls a logging Cmdlet (e.g. Write-Log). I know that I can wrap all code within the module Cmdlets into try/catch blocks, but my preferred solution would be to use trap for all exceptions thrown while executing Cmdlets of the Module

trap { Write-Log -Level Critical -ErrorRecord $_ }

Using the above statement works as intended if I add it to each Cmdlet inside the module, but I would like to only have one trap statement which catches all exceptions thrown by Cmdlets of the Module to not replicate code and also ensure that I do not miss the statement in any Cmdlet. Is this possible?

Upvotes: 0

Views: 40

Answers (1)

Sage Pourpre
Sage Pourpre

Reputation: 10323

What I would do is this.

  • Set multiple Try/Catch block as needed.
  • Group multiple cmdlet calls under the same block when you can. As you mentionned, we don't want to group everything under 1 giant try/catch block but still, related calls can go together.
  • Design your in-module functions as Advanced functions, so you can make use of the common parameters, such as... -ErrorAction
  • Set $PSDefaultParameterValues = @{'*:ErrorAction'='Stop'} so all cmdlets that support -ErrorAction don't fall through the try/catch block.

(You could also manually set -ErrorAction Stop everywhere but since you want this as default, it make sense to do it that way. In any cases You don't want to touch $ErrorActionPreference as this has a global scope amd your users won't like you if you change defaults outside of the module scope.)

You can also redirect the error stream to a file so instead of showing up in the output, it is written to a file.

Here's a self contained example of this:


& {
    Write-Warning "hello"
    Write-Error "hello"
    Write-Output "hi"
} 2>> 'C:\Temp\redirection.log'

See : About_Redirection for more on this.

(Now I am wondering if you can redirect the stream to something else than a file

Additional note

External modules can help with logging too and might provide a more streamlined approach. I am not familiar with any of them though.

I know PSFramework have some interesting stuff regarding logging. You can take a look and experiment to see if fit your needs.

Otherwise, you can do a research on PSGallery for logging modules (this research is far from perfect but some candidates might be interesting)

find-module *logging* | Select Name, Description, PublishedDate,Projecturi | Sort PublishedDate -Descending

Upvotes: 1

Related Questions