2014-09-29 18 views
13

Câu hỏi đơn giản, có thể có ValidateScript tạo thông báo lỗi tùy chỉnh khi thử nghiệm không thành công, như nói Test-Path?Lỗi tùy chỉnh PowerShell từ tham số

Thay vì điều này:

Test-Folder: Không thể xác nhận lập luận trên tham số 'Thư mục'. Tập lệnh xác thực "Test-Path $ _ -Path Type Container" cho đối số có giá trị "blabla" không trả lại kết quả của True. Xác định lý do tại sao kịch bản xác nhận không thành công, và sau đó thử dấu phẩy và một lần nữa.

Nó sẽ được tốt đẹp để có nó báo cáo này thay vì trong biến $Error:

Các 'Thư mục' không được tìm thấy, có thể có những vấn đề mạng?

Code:

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

Giải pháp 1:

tôi có thể loại bỏ các Mandatory=$true và thay đổi nó như dưới đây. Nhưng điều này không cho tôi cú pháp chính xác Get-Help và không thực hiện xác thực Test-Path vì nó chỉ kiểm tra nếu tham số có mặt.

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

Giải pháp 2:

tôi thấy cách giải quyết này trên một blog, nhưng vấn đề là nó tạo ra 2 lỗi thay vì một.

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

Giải pháp 3:

Tôi cũng có thể thử để làm cho nó rõ ràng hơn bằng cách thêm phần nhận xét. Tuy nhiên, đây vẫn không phải là kết quả mong muốn vì lỗi cần phải đọc được đối với người dùng cuối.

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

Đã cùng một vấn đề và tìm thấy bài đăng này. Tôi cũng tìm thấy những gì bạn gọi workaround 2. Không giống như bạn mặc dù tôi chỉ có một lỗi. Có lẽ phiên bản PowerShell đóng vai trò trong đó. 'M: \ Scripts \ Move-MaintenanceData.ps1: Không thể xác thực đối số trên tham số 'Nguồn'. C: \ werwer không xuất hiện như một folder.' hợp lệ – Matt

+1

Bạn nói đúng, tôi không có vấn đề này nữa bây giờ. Vì vậy, nó phải phụ thuộc vào phiên bản PowerShell sử dụng. Đã giải quyết vấn đề :) – DarkLite1

Trả lời

9

bạn ValidateScript trông một cái gì đó như thế này:

[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." 
    } 
})] 

Điều đó sẽ cung cấp cho bạn một tin nhắn như thế này:

Test-Folder: Không thể xác nhận lập luận trên tham số 'Thư mục'. không có thể tìm thấy con đường '\\ server \ Temp \ asdf' vì nó không tồn tại. Có thể có sự cố mạng?

Hoặc:

Test-Folder: Không thể xác nhận lập luận trên tham số 'Thư mục'. Đường dẫn '\\ server \ Temp \ asdf' không phải là một container.

Nếu phiên bản cũ của POSH đang ném một lỗi kép, bạn có thể cần phải kiểm tra bên trong hàm:

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

Phần mà tôi luôn ghét trong Posh đã cố gắng để tìm ra những gì lỗi để bắt lấy; mà không bắt tất cả. Kể từ khi cuối cùng tôi đã tìm nó ra, đây là cách:

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

Đó là một mẹo tuyệt vời VertigoRay! Thx người đàn ông! – DarkLite1

+0

Vui mừng bạn thích nó, @ DarkLite1 ... Tôi chỉ nhận ra tôi không trả lời câu hỏi hoàn toàn vì vậy tôi cập nhật nó. Hy vọng bản sửa đổi này đủ tốt để được đánh dấu là câu trả lời. ;) – VertigoRay

+1

Lưu ý: Điều này không làm việc tốt với Write-Lỗi, theo mặc định nó bỏ qua nó hoàn toàn và nếu bạn sử dụng -ErrorAction bạn nhận được '" Lệnh chạy dừng lại vì biến sở thích 'ErrorActionPreference' hoặc tham số chung được thiết lập để Dừng: 'trước lỗi tùy chỉnh. –

2

Tôi nghĩ bạn đã tìm thấy giải pháp thay thế thẳng về phía trước.

Logic xác thực tham số có thể mở rộng, nhưng yêu cầu một số C#. Nếu bạn triển khai lớp trừu tượng System.Management.Automation.ValidateArgumentsAttribute, việc triển khai của bạn có thể ném một System.Management.Automation.ValidationMetadtaException mà PowerShell sẽ sử dụng để báo cáo lỗi và bạn có thể tự nhiên sử dụng bất kỳ thông điệp nào bạn thích khi tạo ngoại lệ đó.

+1

Thx cho phản hồi Jason. Bạn có thể đưa ra một ví dụ nhỏ về cách thực hiện một lớp trừu tượng như vậy không? Tôi không thực sự là một lập trình viên .. – DarkLite1

0

Không chắc chắn. Một gợi ý: có thể bạn muốn bẫy lỗi, tạo thông điệp của riêng bạn.

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 cho đề xuất. Có, tôi muốn gửi thông điệp của riêng tôi. Nếu tôi sử dụng gợi ý 'bẫy', tôi cần phải làm điều này bên ngoài chức năng của mình, tôi cho rằng? Đây sẽ là một vấn đề, bởi vì tôi có thông báo lỗi khác đến trong kịch bản của tôi .. – DarkLite1

Các vấn đề liên quan