Reputation: 11284
Is it possible to use the adavanced function features Begin, Process, End
in a script-block?
For example I've the following script block:
$startStopService = {
Param(
[bool] $startService)
if ($startService){
...
Start-Service "My-Service"
}
else {
Stop-Service "My-Service"
}
}
Since I want to be able to control the verbose output of the scriptblock I want to change the block to:
$startStopService = {
Param(
[bool] $startService)
Begin {
$oldPreference = $VerbosePreference
$VerbosePreference = $Using:VerbosePreference
}
Process {
if ($startService){
...
Start-Service "My-Service"
}
else {
Stop-Service "My-Service"
}
}
End {
# Restore the old preference
$VerbosePreference = $oldPreference
}
}
Is it possible to use Begin, Process, End
here, though the scriptblock isn't a cmdlet? I simply want that the VerbosePreference
gets restored to the old value, regardless an error occurred or not. Of course I could use try{}finally{}
as an alternative, but I find that Begin, Process, End
is more intuitive.
Thx
Upvotes: 2
Views: 2631
Reputation: 10019
It is possible, as described in about_script_blocks:
Like functions, script blocks can include the DynamicParam, Begin, Process, and End keywords. For more information, see about_Functions and about_Functions_Advanced.
To test this out, I modified your scriptblock and ran this:
$startStopService = {
Param(
# a bool needs $true or $false passed AFAIK
# A switch is $true if specified, $false if not included
[switch] $startService
)
Begin {
$oldPreference = $VerbosePreference
Write-Output "Setting VerbosePreference to Continue"
# $Using:VerbosePreference gave me an error
$VerbosePreference = "Continue"
}
Process {
if ($startService){
Write-Verbose "Service was started"
}
else {
Write-Verbose "Service was not started"
}
}
End {
# Restore the old preference
Write-Output "Setting VerbosePreference back to $oldPreference"
$VerbosePreference = $oldPreference
}
}
Write-Verbose "This message will not print if VerbosePreference is the default SilentlyContinue"
. $startStopService -startService
Write-Verbose "This message will not print if VerbosePreference is the default SilentlyContinue"
What functionality are you after? If you would to print verbose messages when running a scriptblock but not change the $VerbosePreference
in the rest of the script , consider using [CmdletBinding()]
and the -Verbose
flag:
$startStopService = {
[CmdLetBinding()]
Param(
[switch] $startService
)
Write-Verbose "This is a verbose message"
}
Write-Verbose "This message will not print if VerbosePreference is the default SilentlyContinue"
. $startStopService -verbose
Write-Verbose "This message will not print if VerbosePreference is the default SilentlyContinue"
Edit - Invoke-Command
After your comment, I looking into the functionality of Invoke-Command
. And found a lot of things that don't work.
The short version that I believe is most useful to you: you can declare $VerbosePreference = "Continue"
within a scriptblock and this will be limited to the scope of the scriptblock. No need to change back after.
$startStopService = {
[CmdLetBinding()]
Param(
[parameter(Position=0)]
[switch]$startStopService,
[parameter(Position=1)]
[switch]$Verbose
)
if($Verbose){
$VerbosePreference = "Continue"
}
Write-Verbose "This is a verbose message"
}
Write-output "VerbosePreference: $VerbosePreference"
Write-Verbose "This message will not print if VerbosePreference is the default SilentlyContinue"
Invoke-Command -Scriptblock $startStopService -ArgumentList ($true,$true)
Write-output "VerbosePreference: $VerbosePreference"
Write-Verbose "This message will not print if VerbosePreference is the default SilentlyContinue"
Trying to pass the -Verbose
switch CommonParameter to Invoke-Command
was a no-go. This uses a standard Verbose
switch parameter that allows you to pass $true
/$false
(or omit) to control the verbose output.
Related:
about_Functions
about_Functions_Advanced
Upvotes: 2