I have multiple try catch
blocks and all of them are using the same catch
block.
try {
invoke-command -cn $host -Credential $cred -ScriptBlock {
param($name)
statement...
} -ArgumentList $name
} catch {
$formatstring = "{0} : {1}`n{2}`n"
" CategoryInfo : {3}`n"
" FullyQualifiedErrorId : {4}`n"
write-host ($formatstring)
exit 1
}
...
try {
another statement...
} catch {
$formatstring = "{0} : {1}`n{2}`n"
" CategoryInfo : {3}`n"
" FullyQualifiedErrorId : {4}`n"
write-host ($formatstring)
exit 1
}
I want to ask if it is possible to create a function which has the catch
block so that I can call and use the function instead of writing the same catch block
multiple times.
I am using poweshell 5
CodePudding user response:
catch
requires a literal { ... }
block to follow it, but from inside that block you're free to call reusable code, such as a function, or, in the simplest case, a script block:
# Define a script block to use in multiple `catch` blocks.
$sb = {
"[$_]" # echo the error message
}
# Two simple sample try / catch statements:
try {
1 / 0
}
catch {
. $sb # `. <script-block>` invokes the block directly in the current scope
}
try {
Get-Item -NoSuchParam
}
catch {
. $sb
}
Note: .
, the dot-sourcing operator, is used to invoke the script block directly in the current scope, allowing you to directly modify that scope's variables.
If, by contrast, you want to execute the script block in a child scope, use &
, the call operator.
CodePudding user response:
You can create a ScriptBlock which can be called using the Invocation (call - &) Operator.
$callMe = {
$formatstring = "{0} : {1}`n{2}`n"
" CategoryInfo : {3}`n"
" FullyQualifiedErrorId : {4}`n"
Write-Host -Object $formatstring
exit 1
}
try {
Invoke-Command -ComputerName $host -Credential $cred -ScriptBlock {
param($name)
# statement...
} -ArgumentList $name -ErrorAction "Stop"
}
catch {
& $callMe
}
As a side note, if you ever find yourself repeating code, there is probably something you can do about that. I would suggest either setting $ErrorActionPreference to stop, or add a -ErrorAction "Stop"
to your Invoke-Command
to ensure a terminating error is thrown.
- Best practice is to set
$ErrorActionPreference
back to"Continue"
if used. - I also believe you're looking to use the
-f
(format) operator.