在Scriptblock中使用Begin,Process,End

时间:2017-07-03 06:04:01

标签: powershell

是否可以在脚本块中使用adavanced函数功能Begin, Process, End

例如,我有以下脚本块:

$startStopService = {
Param(
    [bool] $startService)    

  if ($startService){
     ...
     Start-Service "My-Service"
  }
  else {
     Stop-Service "My-Service"
  }
}

由于我希望能够控制脚本块的详细输出,我想将块更改为:

$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 
  }
}

这里是否可以使用Begin, Process, End,尽管scriptblock不是cmdlet?我只是希望VerbosePreference恢复到旧值,无论是否发生错误。当然我可以使用try{}finally{}作为替代,但我发现Begin, Process, End更直观。

THX

1 个答案:

答案 0 :(得分:3)

有可能,如about_script_blocks

中所述
  

与函数类似,脚本块可以包含DynamicParam, Begin,   处理和结束关键字。有关更多信息,请参阅about_Functions   和about_Functions_Advanced。

为了测试这一点,我修改了你的scriptblock并运行了这个:

$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"

你追求什么功能?如果要在运行脚本块时打印详细消息但不更改脚本其余部分中的$VerbosePreference,请考虑使用[CmdletBinding()]-Verbose标记:

$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"

编辑 - 调用命令

在您发表评论后,我会查看Invoke-Command的功能。并发现很多不起作用的东西。

我认为对您最有用的简短版本:您可以在脚本块中声明$VerbosePreference = "Continue",这将仅限于scriptblock的范围。之后无需改变。

$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"

尝试将-Verbose开关 CommonParameter 传递给Invoke-Command是不行的。这使用标准Verbose开关参数,允许您传递$true / $false(或省略)来控制详细输出。

<子>相关:
about_Functions
about_Functions_Advanced