2014-09-29 29 views
13

一個簡單的問題是否有可能讓ValidateScript在測試失敗時生成自定義錯誤消息,比如說說Test-PathPowerShell自定義錯誤參數

取而代之的是:

測試 - 文件夾:無法驗證的參數「文件夾」的說法。值爲「blabla」的參數的「Test-Path $ _ -Path Type Container」驗證腳本未返回True結果。確定驗證腳本失敗的原因,然後再次嘗試逗號。

這將是很好,有它在,而不是$Error變量報告此:

「文件夾」沒有找到,也許有網絡問題?

代碼:

Function Test-Folder { 
    Param (
     [parameter(Mandatory=$true)] 
     [ValidateScript({Test-Path $_ -PathType Container})] 
     [String]$Folder 
    ) 
    Write-Host "The folder is: $Folder" 
} 

解決方法1:

我可以刪除Mandatory=$true和如下更改。但是這不會給我正確的Get-Help語法,並且不會執行Test-Path驗證,因爲它只檢查參數是否存在。

Function Test-Folder { 
    Param (
     [parameter()] 
     [String]$Folder = $(throw "The $_ is not found, maybe there are network issues?") 
    ) 
    Write-Host "The folder is: $Folder" 
} 

解決方法2:

我發現一個blog這個解決辦法,但問題是,它會產生2個錯誤,而不是一個。

Function Test-Folder { 
    Param (
     [parameter(Mandatory=$true)] 
     [ValidateScript({ 
      if (Test-Path $_ -PathType Container) {$true} 
      else {Throw "The $_ is not found, maybe there are network issues?"}})] 
     [String]$Folder 
    ) 
    Write-Host "The folder is: $Folder" 
} 

解決方法3:

我也可以嘗試,使之更加明確通過添加註釋部分。但是,這仍然不是期望的結果,因爲錯誤需要對最終用戶可讀。

Function Test-Folder { 
    Param (
     [parameter(Mandatory=$true)] 
     [ValidateScript({ 
     # The folder is not found, maybe there are network issues? 
     Test-Path $_ -PathType Container})] 
     [String]$Folder 
    ) 
    Write-Host "The folder is: $Folder" 
} 
+1

有同樣的問題,並找到這篇文章。我也發現了你所說的解決方法2.不像你,雖然我只有一個錯誤。也許PowerShell版本是其中的一部分。 'M:\ Scripts \ Move-MaintenanceData.ps1:無法驗證參數'Source'的參數。 C:\ werwer似乎不是一個有效的文件夾。「# – Matt 2015-10-26 19:24:21

+1

你說得對,我現在沒有這個問題了。所以它必須取決於一個使用的PowerShell版本。問題解決了:) – DarkLite1 2015-11-04 07:21:33

回答

9

ValidateScript應該是這個樣子:

[ValidateScript({ 
    try { 
     $Folder = Get-Item $_ -ErrorAction Stop 
    } catch [System.Management.Automation.ItemNotFoundException] { 
     Throw [System.Management.Automation.ItemNotFoundException] "${_} Maybe there are network issues?" 
    } 
    if ($Folder.PSIsContainer) { 
     $True 
    } else { 
     Throw [System.Management.Automation.ValidationMetadataException] "The path '${_}' is not a container." 
    } 
})] 

這會給你這樣一個消息:

測試 - 文件夾:無法驗證的參數 '文件夾' 的說法。不能 查找路徑'\\ server \ Temp \ asdf',因爲它不存在。網絡問題可能有 ?

或者:

測試 - 文件夾:無法驗證的參數 '文件夾' 的說法。路徑 '\\ server \ Temp \ asdf'不是容器。

如果舊版本POSH的都扔了雙誤,則可能需要在函數內部測試:

Function Test-Folder { 
    Param (
     [parameter(Mandatory=$true)] 
     [String]$Folder 
    ) 

    try { 
     $Folder = Get-Item $_ -ErrorAction Stop 
    } catch [System.Management.Automation.ItemNotFoundException] { 
     Throw [System.Management.Automation.ItemNotFoundException] "The '${Folder}' is not found, maybe there are network issues?" 
    } 

    if (-not $Folder.PSIsContainer) { 
     Throw [System.Management.Automation.ApplicationFailedException] "The path '${_}' is not a container." 
    } 

    Write-Host "The folder is: ${Folder}" 
} 

,我總是在POSH討厭的部分試圖找出錯誤抓住;沒有捕捉所有。由於我終於弄明白了,這裏是如何:

PS > Resolve-Path 'asdf' 
Resolve-Path : Cannot find path '.\asdf' because it does not exist. 
At line:1 char:1 
+ Resolve-Path 'asdf' 
+ ~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : ObjectNotFound: (asdf:String) [Resolve-Path], ItemNotFoundE 
    xception 
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand 

PS > $Error[0].Exception.GetType().FullName 
System.Management.Automation.ItemNotFoundException 
+1

這是一個偉大的技巧VertigoRay! Thx男人! – DarkLite1 2016-04-04 14:22:31

+0

很高興你喜歡它,@ DarkLite1 ...我只是意識到我沒有完全回答這個問題,所以我更新了它。希望這個修訂足夠好,可以被標記爲答案。 ;) – VertigoRay 2016-04-05 00:27:06

+1

注意:這與Write-Error不兼容,默認情況下它完全忽略它,如果使用-ErrorAction,則會得到「」由於首選變量「ErrorActionPreference」或通用參數設置爲「停止:在自定義錯誤之前。 – 2017-05-02 11:12:10

2

我認爲你已經找到了直接的解決方法。

參數驗證邏輯是可擴展的,但需要一些C#。如果您實現了抽象類System.Management.Automation.ValidateArgumentsAttribute,那麼您的實現可以拋出一個System.Management.Automation.ValidationMetadtaException,PowerShell將使用它來報告錯誤,並且您可以在創建該異常時自然使用任何您喜歡的消息。

+1

Thx的反饋傑森。你能舉一個關於如何實現這樣一個抽象類的小例子嗎?我不是一個真正的程序員.. – DarkLite1 2014-10-01 06:36:39

0

不確定。 一個建議:也許你想只捕獲錯誤,發表你自己的信息。

trap [Error.Type] { 
    @" 
    The message you want displayed 
    With maybe some info additional info. 
    ie : The full message itself: {0}' -f $_.Error.Message; 
    continue; 
} 
+0

Thx的建議。是的,我想要發表自己的信息。如果我使用「陷阱」建議,我需要在我的功能之外做這件事,我想呢?這將是一個問題,因爲我有其他錯誤信息到達我的腳本.. – DarkLite1 2014-10-01 06:38:33