2011-11-02 28 views
7

Tôi đã cố gắng viết mã an toàn hỗ trợ -whatif với phương pháp ShouldProcess để người dùng của tôi có một ý tưởng về những gì một cmdlet là nghĩa vụ phải làm trước khi chúng chạy nó cho thật.Powershell: Làm thế nào để có được -whatif để truyền cho cmdlets trong mô-đun khác

Tuy nhiên, tôi đã gặp phải một chút vướng mắc. Nếu tôi gọi một kịch bản với -whatif như một đối số, $ pscmdlet.ShouldProcess sẽ trả về false. Tất cả tốt và tốt. Nếu tôi gọi một lệnh ghép ngắn được định nghĩa trong cùng một tệp (có SupportsShouldProcess = $ true) thì nó cũng sẽ trả về false.

Tuy nhiên, nếu tôi gọi một lệnh ghép ngắn được xác định trong mô-đun khác tôi đã tải bằng cách sử dụng Mô-đun nhập, mô-đun sẽ trả về giá trị đúng. Ngữ cảnh -whatif dường như không được chuyển qua các cuộc gọi trong mô-đun khác.

Tôi không muốn phải tự gắn cờ vào mỗi cờ cho mỗi lệnh ghép ngắn. Có ai có một giải pháp tốt hơn?

Sự cố này có vẻ liên quan đến điều này question. Tuy nhiên, họ không nói về vấn đề mô-đun chéo.

Ví dụ Script:

#whatiftest.ps1 
[CmdletBinding(SupportsShouldProcess=$true)] 
param() 

Import-Module -name .\whatiftest_module -Force 

function Outer 
{ 
    [CmdletBinding(SupportsShouldProcess=$true)] 
    param() 
    if($pscmdlet.ShouldProcess("Outer")) 
    { 
     Write-Host "Outer ShouldProcess" 
    } 
    else 
    { 
     Write-Host "Outer Should not Process" 
    } 

    Write-Host "Calling Inner" 
    Inner 
    Write-Host "Calling InnerModule" 
    InnerModule 
} 

function Inner 
{ 
    [CmdletBinding(SupportsShouldProcess=$true)] 
    param() 

    if($pscmdlet.ShouldProcess("Inner")) 
    { 
     Write-Host "Inner ShouldProcess" 
    } 
    else 
    { 
     Write-Host "Inner Should not Process" 
    } 
} 

    Write-Host "--Normal--" 
    Outer 

    Write-Host "--WhatIf--" 
    Outer -WhatIf 

Module:

#whatiftest_module.psm1 
function InnerModule 
{ 
    [CmdletBinding(SupportsShouldProcess=$true)] 
    param()  

    if($pscmdlet.ShouldProcess("InnerModule")) 
    { 
     Write-Host "InnerModule ShouldProcess" 
    } 
    else 
    { 
     Write-Host "InnerModule Should not Process" 
    } 
} 

Output:

F:\temp> .\whatiftest.ps1 
--Normal-- 
Outer ShouldProcess 
Calling Inner 
Inner ShouldProcess 
Calling InnerModule 
InnerModule ShouldProcess 
--WhatIf-- 
What if: Performing operation "Outer" on Target "Outer". 
Outer Should not Process 
Calling Inner 
What if: Performing operation "Inner" on Target "Inner". 
Inner Should not Process 
Calling InnerModule 
InnerModule ShouldProcess 
+0

Theo kinh nghiệm của tôi, ngay cả khi đi qua các thông số chung '-WhatIf: $ WhatIF -Xác nhận: $ Xác nhận -debug: $ gỡ lỗi -verbose: $ Verbose', họ sẽ bị bỏ qua trên thập tự giá ranh giới -module ... –

Trả lời

6

Để làm điều này, bạn có thể sử dụng một kỹ thuật tôi gọi là "callstack nhìn trộm". Sử dụng Get-PSCallStack để tra cứu mọi thứ được gọi là hàm. Mỗi mục sẽ có một InvocationInfo, và một bên trong đó sẽ là một thuộc tính được gọi là "BoundParameters". Điều này có các thông số @ mỗi cấp độ. Nếu -WhatIf được chuyển cho bất kỳ người nào trong số họ, bạn có thể hành động như -WhatIf đã được chuyển cho chức năng của bạn.

Hope this helps

+0

Cách tiếp cận này sẽ sớm dẫn đến những khiếm khuyết tinh tế. Điều gì sẽ xảy ra khi '-WhatIf' hoặc' -Xác nhận' được chỉ định, nhưng một hàm ở giữa ngăn xếp cuộc gọi có logic yêu cầu không sử dụng '-WhatIf'? Và bạn có tìm kiếm tất cả các thông số phổ biến khác, như '-Verbose',' -Debug' không? Điều gì sẽ xảy ra khi một tham số chung mới được giới thiệu? Bạn có tính đến giá trị $ ConfirmPreference toàn cầu không? –