source

사용자 지정 cmdlet에서 -verbose 및 -debug 매개 변수를 적절하게 사용하는 방법

ittop 2023. 9. 19. 21:24
반응형

사용자 지정 cmdlet에서 -verbose 및 -debug 매개 변수를 적절하게 사용하는 방법

기본적으로 [CmdletBinding()] 특성을 가진 명명된 함수는 다음을 허용합니다.-debug그리고.-verbose(및 다른 몇 가지) 파라미터 및 미리 정의된 값을 가지고 있습니다.$debug그리고.$verbose변수들.기능 내에서 호출되는 다른 cmdlet에게 전달하는 방법을 찾고 있습니다.

내게 이런 cmdlet이 있다고 치자.

function DoStuff() {
   [CmdletBinding()]

   PROCESS {
      new-item Test -type Directory
   }
}

한다면-debug아니면-verbose내 기능으로 넘어갔어요, 저는 그 깃발을new-itemcmdlet.이것을 하기에 알맞은 패턴은 무엇입니까?

$PSBoundParameters당신이 찾는 게 아니에요의 사용.[CmdletBinding()]특성을 사용할 수 있습니다.$PSCmdletVerbose 플래그를 제공할 뿐만 아니라 스크립트 내에서도 사용할 수 있습니다.이것은 사실 당신이 사용해야 하는 것과 같은 장황한 말입니다.

통해.[CmdletBinding()], 다음을 통해 바운드 파라미터에 접근할 수 있습니다.$PSCmdlet.MyInvocation.BoundParameters. 여기에는 CmdletBinding을 사용하고 함수 범위 내에서 사용 가능한 변수를 검사하기 위해 즉시 중첩 프롬프트를 입력하는 기능이 있습니다.

PS D:\> function hi { [CmdletBinding()]param([string] $Salutation) $host.EnterNestedPrompt() }; hi -Salutation Yo -Verbose

PS D:\>>> $PSBoundParameters

____________________________________________________________________________________________________
PS D:\>>> $PSCmdlet.MyInvocation.BoundParameters

Key Value                                                                                                                                                                                                           
--- -----                                                                                                                                                                                                           
Salutation Yo                                                                                                                                                                                                              
Verbose   True                                                                                       

예를 들어, 다음과 같은 것을 원하게 됩니다.

function DoStuff `
{
    [CmdletBinding()]
    param ()
    process
    {
      new-item Test -type Directory `
        -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true)
    }
}

여기에서는 -Verbose, -Verbose:$false, -verbose:$true, 스위치가 전혀 없는 경우.

이상하게 들릴지도 모르지만, cmdlet이 장황하거나 디버그 모드를 알 수 있는 쉬운 방법은 없습니다.관련 질문을 살펴봅니다.

cmdlet이 실제로 WriteVerbose()를 호출해야 할 때 어떻게 알 수 있습니까?

완벽하지는 않지만 현실적으로 합리적인 옵션 중 하나는 자신의 cmdlet 파라미터를 도입하는 것입니다(예:$MyVerbose그리고.$MyDebug) 및 코드에 명시적으로 사용합니다.

function DoStuff {
    [CmdletBinding()]
    param
    (
        # Unfortunately, we cannot use Verbose name with CmdletBinding
        [switch]$MyVerbose
    )

    process {

        if ($MyVerbose) {
            # Do verbose stuff
        }

        # Pass $MyVerbose in the cmdlet explicitly
        New-Item Test -Type Directory -Verbose:$MyVerbose
    }
}

DoStuff -MyVerbose

갱신하다

스위치만 필요한 경우(예를 들어, 장황도 레벨 값이 아닌 경우),$PSBoundParameters이 답변의 첫 번째 부분에서 제안한 것보다 더 나은 것 같습니다(추가 파라미터 포함).

function DoStuff {
    [CmdletBinding()]
    param()

    process {
        if ($PSBoundParameters['Verbose']) {
            # Do verbose stuff
        }

        New-Item Test -Type Directory -Verbose:($PSBoundParameters['Verbose'] -eq $true)
    }
}

DoStuff -Verbose

어차피 다 완벽하진 않아요.더 좋은 해결책이 있다면 제가 직접 알고 싶습니다.

그럴 필요 없습니다.PowerShell은 아래 코드가 증명하듯 이미 이 작업을 수행하고 있습니다.

function f { [cmdletbinding()]Param()    
    "f is called"
    Write-Debug Debug
    Write-Verbose Verbose
}
function g { [cmdletbinding()]Param() 
    "g is called"
    f 
}
g -Debug -Verbose

출력은

g is called
f is called
DEBUG: Debug
VERBOSE: Verbose

그러나 디버그를 다음 cmdlet으로 전달하는 것만큼 직접적으로 수행되지는 않습니다.$DebugPreference 및 $VerbrosePreference 변수를 통해 수행됩니다.Write-Debug 및 Write-Verbose는 여러분이 기대하는 것처럼 작용하지만, 만약 여러분이 디버그 또는 상세한 것으로 무언가 다른 것을 하고 싶다면, 여러분은 여기에서 여러분 스스로 확인하는 방법을 읽을 수 있습니다.

제 해결책은 이렇습니다.

function DoStuff {
    [CmdletBinding()]
    param ()

    BEGIN
    {
        $CMDOUT = @{
            Verbose = If ($PSBoundParameters.Verbose -eq $true) { $true } else { $false };
            Debug = If ($PSBoundParameters.Debug -eq $true) { $true } else { $false }
        }

    } # BEGIN ENDS

    PROCESS
    {
        New-Item Example -ItemType Directory @CMDOUT
    } # PROCESS ENDS

    END
    {

    } #END ENDS
}

이것이 다른 예들과 다른 점은 "-Verbose:$false" 또는 "-Debug:$false"입니다.다음을 사용할 경우 -Verbose/-Debug만 $true로 설정됩니다.

DoStuff -Verbose
DoStuff -Verbose:$true
DoStuff -Debug
DoStuff -Debug:$true

바인딩된 디버그 또는 상세 매개 변수를 기반으로 새 해시 테이블을 작성한 다음 내부 명령으로 분할할 수 있습니다.스위치만 지정하고 $debug:$false와 같이 잘못된 스위치를 전달하지 않는 경우 디버그 또는 상세한 디버그가 있는지 확인할 수 있습니다.

function DoStuff() { 
   [CmdletBinding()] 

   PROCESS { 
        $HT=@{Verbose=$PSBoundParameters.ContainsKey'Verbose');Debug=$PSBoundParameters.ContainsKey('Debug')}
      new-item Test -type Directory @HT
   } 
} 

매개 변수 값을 전달하려면 더 복잡하지만 다음 작업을 수행할 수 있습니다.

function DoStuff {  
   [CmdletBinding()]  
   param()
   PROCESS {  
   $v,$d = $null
   if(!$PSBoundParameters.TryGetValue('Verbose',[ref]$v)){$v=$false}
   if(!$PSBoundParameters.TryGetValue('Debug',[ref]$d)){$d=$false}
   $HT=@{Verbose=$v;Debug=$d} 
   new-item Test -type Directory @HT 
   }  
}  

은 입니다.$VerbosePreference이렇게 할 수 있습니다 이렇게 하면 전체 스크립트에 대해 상세 수준을 사용할 수 있습니다.스크립트가 끝날 때까지 사용하지 않도록 설정하는 것을 잊지 마십시오.

Function test
{
    [CmdletBinding()]
    param($param1)

    if ($psBoundParameters['verbose'])
    {
        $VerbosePreference = "Continue"
        Write-Verbose " Verbose mode is on"
    }
    else
    {
        $VerbosePreference = "SilentlyContinue"
        Write-Verbose " Verbose mode is Off"
    }


    # <Your code>

}

스크립트를 시작할 때 Verbose Preference를 전역 변수로 설정한 다음 사용자 지정 cmdlet에서 전역 변수를 확인할 수 있습니다.

스크립트:

$global:VerbosePreference = $VerbosePreference
Your-CmdLet

CmdLet:

if ($global:VerbosePreference -eq 'Continue') {
   # verbose code
}

가 '' (를) 와 수 .-verbose:$false에서 CmdLet때()$null)

검사나 비교를 수행할 필요가 없습니다.-Verbose(및 -Debug)는 [스위치] 유형이지만 $true 및 $false뿐만 아니라 선호 변수도 이해하는 것 같습니다.기본 설정 변수는 호출되는 모든 하위 함수에도 올바르게 상속됩니다.파워셸 버전 7.3.2에서 사용해봤는데 예상대로 작동합니다.

function Parent {
    [CmdletBinding()]param()
    Child
}

function Child {
    [CmdletBinding()]param()
    New-Item C:\TEST\SomeDir -Force -ItemType Directory -Verbose:$VerbosePreference -Debug:$DebugPreference
}

Parent -Verbose
Parent -Debug

이것이 가장 쉬운 방법이라고 생각합니다.

Function Test {
    [CmdletBinding()]
    Param (
        [parameter(Mandatory=$False)]
        [String]$Message
    )

    Write-Host "This is INFO message"

    if ($PSBoundParameters.debug) {
        Write-Host -fore cyan "This is DEBUG message"
    }

    if ($PSBoundParameters.verbose) {
        Write-Host -fore green "This is VERBOSE message"
    }

    ""
}
Test -Verbose -Debug

언급URL : https://stackoverflow.com/questions/4301562/how-to-properly-use-the-verbose-and-debug-parameters-in-a-custom-cmdlet

반응형