2017-07-03 21 views
1

是否有可能使用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

回答

3

这是可能的,如在about_script_blocks描述:

一样的功能,脚本块可以包括DynamicParam,开始, 过程和结束关键字。欲了解更多信息,请参阅about_Functions 和about_Functions_Advanced。


为了验证这一点,我修改你的脚本块,并运行此:

$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",这将限制在脚本块的范围。之后无需改变。

$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开关CommonParameterInvoke-Command是一个没有去。这使用标准Verbose开关参数,允许你传递$true/$false(或省略)来控制详细的输出。

相关:
about_Functions
about_Functions_Advanced

+1

我一直在寻找你的答案('CmdletBinding')的第二个选项。简短的问题:'CmdletBinding'也可以在'Invoke-Command'下工作吗?我们来说一下'Invoke-Command -session $ remoteSession -scriptblock $ startStopService -verbose'。 – Moerwald

+0

@Moerwald根据文档中的[[CommonParameters]] [[文档]](https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell),简短版本应为_should_。芯/调用命令)。但是,当我尝试它时,它不起作用。搜索,我发现[这篇文章](https://stackoverflow.com/questions/16197021/how-to-write-verbose-from-invoke-command),你已经阅读。它提到这是一个错误;不知道是否是这种情况,或者我们的做法有错误。 – gms0ulman

+0

Thx为答案。是的,我阅读过这篇文章。自从它3岁左右以来,我认为可能有更好的方法。 – Moerwald