Powershell 在Scriptblock中使用Begin、Process、End

Powershell 在Scriptblock中使用Begin、Process、End,powershell,Powershell,是否可以在脚本块中使用高级功能功能Begin、Process、End 例如,我有以下脚本块: $startStopService = { Param( [bool] $startService) if ($startService){ ... Start-Service "My-Service" } else { Stop-Service "My-Service" } } 由于我希望能够控制scriptblock的详细输出,因此我

是否可以在脚本块中使用高级功能功能
Begin、Process、End

例如,我有以下脚本块:

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

  if ($startService){
     ...
     Start-Service "My-Service"
  }
  else {
     Stop-Service "My-Service"
  }
}
由于我希望能够控制scriptblock的详细输出,因此我希望将该块更改为:

$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 
  }
}
尽管scriptblock不是cmdlet,但是否可以在此处使用
Begin、Process、End
?我只是希望无论是否发生错误,
VerbosePreference
都恢复为旧值。当然,我可以使用
try{}finally{}
作为替代,但我发现
Begin,Process,End
更直观


Thx是可能的,如中所述:

与函数类似,脚本块可以包括dynamicRAM、Begin、, 进程和结束关键字。有关更多信息,请参阅关于函数 关于"功能"和"高级"


为了测试这一点,我修改了脚本块并运行了以下命令:

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

你想要什么功能?如果在运行脚本块时要打印冗长的消息,但在脚本的其余部分中不更改<代码> $VBueExcel ,请考虑使用<代码> [CMDelbBudIn()] <代码>和<代码> -VBBOSE < /COD>标志:

$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命令的功能。发现了很多不起作用的东西

我认为最有用的简短版本是:您可以在scriptblock中声明
$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传递到
调用命令
是不可能的。这使用标准的
Verbose
开关参数,允许您传递
$true
/
$false
(或省略)以控制详细输出

相关:


我正在寻找您答案的第二个选项(
CmdletBinding
)。简短问题:
CmdletBinding
是否也适用于
调用命令
?比方说
Invoke命令-session$remoteSession-scriptblock$startStopService-verbose
@Moerwald根据
[]
的要求,短版本是应该的。但当我尝试它时,它不起作用。搜索,我找到了你已经读过的。它提到这是一个bug;不确定是这样还是我们做的方式有错误。谢谢回答。是的,我看过这篇文章。“因为它已经有3年的历史了,我想可能有更好的办法来解决它。”莫尔瓦尔德同意。经过一些研究,我并没有发现太多,但看到了编辑后的解决办法的答案。在评论中直接传递
-Verbose
是不可能的<代码>-可以使用ArgumentList
,但尚未成功使其与命名参数一起100%工作。