2017-07-03 48 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