programing

Powershell에서 빈 매개 변수와 설정된 매개 변수를 포함하여 명명된 모든 매개 변수 가져오기

powerit 2023. 9. 5. 20:50
반응형

Powershell에서 빈 매개 변수와 설정된 매개 변수를 포함하여 명명된 모든 매개 변수 가져오기

파워셸 스크립트에서 모든 매개 변수 정보를 가져올 방법을 찾고 있습니다.설명:

function test()
{
    Param(
        [string]$foo,
        [string]$bar,
        [string]$baz = "baz"
    )

    foreach ($key in $MyInvocation.BoundParameters.keys)
    {
        write-host "Parameter: $($key) -> $($MyInvocation.BoundParameters[$key])"
    }
}
test -foo "foo!"

는 의가를얻싶다니습의 $bar그리고.$baz사전에 매개 변수의 이름을 알지 못하는 동적인 방식으로.

살습니다를 .$MyInvocation설정/통과된 매개 변수 외에는 아무것도 보이지 않습니다.

업데이트 1:

이제 거의 모든 것이 완료되었습니다.

function test()
{
    Param(
        [string]$foo,
        [string]$bar,
        [string]$baz = "baz"
    )
    foreach($var in (get-variable -scope private))
    {
        write-host "$($var.name) -> $($var.value)"
    }
}
test -foo "foo!"

스크립트 매개 변수와 기본 매개 변수를 필터링할 수 있다면 이동할 수 있습니다.

업데이트 2: 최종 작동 솔루션은 다음과 같습니다.

function test {
    param (
          [string] $Bar = 'test'
        , [string] $Baz
        , [string] $Asdf
    )
    $ParameterList = (Get-Command -Name $MyInvocation.InvocationName).Parameters;
    foreach ($key in $ParameterList.keys)
    {
        $var = Get-Variable -Name $key -ErrorAction SilentlyContinue;
        if($var)
        {
            write-host "$($var.name) > $($var.value)"
        }
    }
}

test -asdf blah;

이 솔루션을 확인하십시오.이는 다음을 사용합니다.CmdletBinding()- 의을 - 통해일 추부가제메를 하여 일부 추가 합니다.$PSCmdlet기본 제공 변수입니다.할 수 있는 일:

  1. 을다음검사용색동이적으로다니합름을 사용하여 으로 검색합니다.$PSCmdlet
  2. 변수 . 명령어에 매개 변수 목록은 다음과 .Get-Command
  3. 하기 위해 다 사 파 미 조 사 합 니 다 값 을Get-Variablecmdlet

코드:

function test {
    [CmdletBinding()]
    param (
          [string] $Bar = 'test'
        , [string] $Baz
        , [string] $Asdf
    )
    # Get the command name
    $CommandName = $PSCmdlet.MyInvocation.InvocationName;
    # Get the list of parameters for the command
    $ParameterList = (Get-Command -Name $CommandName).Parameters;

    # Grab each parameter value, using Get-Variable
    foreach ($Parameter in $ParameterList) {
        Get-Variable -Name $Parameter.Values.Name -ErrorAction SilentlyContinue;
        #Get-Variable -Name $ParameterList;
    }
}

test -asdf blah;

산출량

이 명령어의 출력은 다음과 같습니다.

Name                           Value                                           
----                           -----                                           
Bar                            test                                            
Baz                                                                            
Asdf                           blah                                            

값동적읽사용다니합다음을을 합니다.get-variable / / cmdlet

write-host (get-variable "foo")

모든 매개 변수를 인쇄하려면 다음을 수행합니다.

foreach ($key in $MyInvocation.BoundParameters.keys)
{
    $value = (get-variable $key).Value 
    write-host "$key -> $value"
}

일부 사람들은 이 한 줄이 유용하다고 생각할 수도 있습니다.

function test()
{
    Param(
        [string]$foo,
        [string]$bar,
        [string]$baz = "baz"
    )

    $MyInvocation.MyCommand.Parameters | Format-Table -AutoSize @{ Label = "Key"; Expression={$_.Key}; }, @{ Label = "Value"; Expression={(Get-Variable -Name $_.Key -EA SilentlyContinue).Value}; }
}
test -foo "foo!"

결과

Keys Value
---- -----
foo  foo! 
bar       
baz  baz  

PS4(Windows 2012 R2)에 가장 유용한 기능으로, 기본값 / 옵션 매개 변수가 포함되어 있습니다.

$cmdName = $MyInvocation.InvocationName
$paramList = (Get-Command -Name $cmdName).Parameters
foreach ( $key in $paramList.Keys ) {
    $value = (Get-Variable $key -ErrorAction SilentlyContinue).Value
    if ( $value -or $value -eq 0 ) {
        Write-Host "$key -> $value"
    }
}

cmdletbinding()을 사용하지 않으려는 분들을 위해 위에서 찾은 하나의 라이너에 대한 변형이 있습니다.

(Get-Command -Name $PSCommandPath).Parameters | Format-Table -AutoSize @{ Label = "Key"; Expression={$_.Key}; }, @{ Label = "Value"; Expression={(Get-Variable -Name $_.Key -EA SilentlyContinue).Value}; }

$PSCommandPath는 항상 사용 가능합니다.

이 스레드에서 마음에 드는 두 가지 솔루션을 사용하여 플레이했는데, 둘 다 작동합니다.그러나 빌드 스크립트에 대한 매개 변수가 누락되었을 때 오류를 생성해야 했습니다.

   $cmdName = $MyInvocation.InvocationName 
   $paramList = (Get-Command -Name $cmdName).Parameters
     foreach ( $key in $paramList.Keys ) {
     $value = (Get-Variable $key -ErrorAction Stop)
     #Write-Host $value.Value #remove comment for error checking
        if ([string]::IsNullOrEmpty($value.Value)){ 
        $(throw ("$key is a mandatory value please declare with -$key <Required value> " ))
        }
       }

어떤 주장이 통과될지, 몇 개가 통과될지 모르면 어떻게 하나요?예를 들어, 함수는 다음과 같이 호출될 수 있습니다.

test -foo "value1" -bar "value2" -baz "value3"

그리고 다른 사람은 다음과 같이 부를 수 있습니다.

test -variable1 "somevalue" -variable2 "somevalue2" -variable3 "somevalue3" -variable4 "value4"

나는 보았습니다.$MyInvocation그리고 인수는 UnboundArguments로 전달되므로 이론적으로 인수 0과 인수 1, 2, 3 등을 "쌍으로" 구성할 수 있으며, 홀수의 UnboundArguments가 있으면 오류가 발생할 수 있습니다.

비슷한 일을 하려고 하다가 우연히 발견했고 제가 선호하는 선택지를 발견했습니다.

Function ParamTest {
    Param (
        $t1 = '1234',
        $t2,
        [switch]$3
    )
    
    $MyInvocation |Add-Member -Name:'Param' -MemberType:'NoteProperty' -Value:(
        (Get-Variable -Scope:'Local' -Include:@($MyInvocation.MyCommand.Parameters.keys)|
            ForEach-Object -begin:{$h=@{}} -process:{$h.add($_.Name,$_.Value)} -end:{$h}
    ))

    $MyInvocation.Param
}

결과

Name                           Value                                                                                                                                                                                                                                                                                                                      
----                           -----                                                                                                                                                                                                                                                                                                                      
t1                             1234                                                                                                                                                                                                                                                                                                                       
3                              False                                                                                                                                                                                                                                                                                                                      
t2

                          

PS 버전 표

Name                           Value                                                                                                                                                                                                                                                                                                                      
----                           -----                                                                                                                                                                                                                                                                                                                      
PSVersion                      5.1.19041.1320                                                                                                                                                                                                                                                                                                             
PSEdition                      Desktop                                                                                                                                                                                                                                                                                                                    
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                                                                                                                                                                                                    
BuildVersion                   10.0.19041.1320                                                                                                                                                                                                                                                                                                            
CLRVersion                     4.0.30319.42000                                                                                                                                                                                                                                                                                                            
WSManStackVersion              3.0                                                                                                                                                                                                                                                                                                                        
PSRemotingProtocolVersion      2.3                                                                                                                                                                                                                                                                                                                        
SerializationVersion           1.1.0.1

다음과 같은 간소화된 솔루션:

  • 질문의 하단에 표시된 독자적인 접근 방식을 기반으로 합니다.

  • 또한 각 매개 변수가 호출 시 바인딩되었는지 여부, 즉 바인딩된 매개 변수와 값(value)을 포함하는 사전인 자동 변수의 존재를 기반으로 인수가 전달되었는지 여부와 같은 추가 정보를 포함합니다.

    • 참고:$PSBoundParameters기본값으로 바인딩된 매개 변수를 포함하지 않으며, 인수가 명시적으로 전달된 매개 변수만 포함합니다. 사용 사례의 경우 기본값과 명시적 매개 변수를 구별하기 위해 반드시 바람직합니다.그러나 인수가 전달되어야 하는 시나리오에서는 기본값 매개 변수를 포함하는 것이 바람직할 수 있습니다. GitHub 문제 #3285를 참조하십시오.
function test {
  param (
    [string]$foo,
    [string]$bar,
    [string]$baz = "baz"
  )
  foreach ($paramName in $MyInvocation.MyCommand.Parameters.Keys) {
    $bound = $PSBoundParameters.ContainsKey($paramName)
    [pscustomobject] @{
      ParameterName = $paramName
      ParameterValue = if ($bound) { $PSBoundParameters[$paramName] }
                       else { Get-Variable -Scope Local -ErrorAction Ignore -ValueOnly $paramName }
      Bound = $bound
    }
  }
}

test -foo "foo!"

위의 값은 다음과 같습니다.

ParameterName ParameterValue Bound
------------- -------------- -----
foo           foo!            True
bar                          False
baz           baz            False

참고: 이 솔루션은 동적 매개 변수도 올바르게 처리합니다.

  • 이러한 는 이한매변다반음영다니됩에 .$MyInvocation.MyCommand.Parameters상황에 따라 적용되지만 일반 정적 매개 변수와 달리 스코프 로컬 변수에 반영되지 않는 경우.만약 그들이 적용되고 또한 구속된다면, 그들과 그들의 가치는 반영됩니다.$PSBoundParameters.
  • - 수 할 때 - 따서라 - 가한동적매개변수바때가 -Get-Variable정적 매개 변수를 나타내는 범위 로컬 변수를 찾기 위해 호출합니다.
    • 명 으 야 니 다 로 적 합 -Scope Local바인딩되지 않은 동적 매개 변수에 대해 조상 범위에서 동일한 이름의 관련 없는 변수를 실수로 픽업하지 않도록 합니다.
    • 에서 변수를 해야 합니다. 를 하여 변수를 찾을 수 있습니다.-ErrorAction Ignore.

오류가 발생했을 때 쓸 수 있는 매개 변수 키/값 쌍의 압축 문자열을 원했습니다.다른 답변의 내용을 사용하여 다음과 같이 생각해냈습니다.

$parameters = (Get-Variable -Scope:'Local' -Include:@($MyInvocation.MyCommand.Parameters.keys) |
        Select-Object Name, Value | ForEach-Object { "$($_.Name) : $($_.Value)" }) -join ' | '

샘플 출력:

ComputerName : SomePC | Directory : C:\Tools\LogExpert | UserName : Hans Wurst | YesOrNo : False

위의 훌륭하고 유용한 답변을 담은 다른 모든 포스터들 덕분입니다!저는 제 요구 사항을 충족하기 위해 위의 게시물 중 일부를 정리하고 있습니다.Powershell 언어 호환 형식으로 Params를 표시하여 이 Params를 쉽게 보고 표시한 다음 Params() Defaults(ParamsFormat1) 또는 명령줄/함수 호출(CommandFormat2)로 +pasta를 다시 복사합니다.저는 이것 때문에 한동안 고생했는데, 이것이 누군가에게 시간을 좀 절약해 줬으면 좋겠습니다.

위의 다양한 스크립트 모음:

# Note: there are some subtle differences between these versions below
# Specifically in the first line for *which* object you're checking for Parameters, and subsequently what type of Parameters you're looking at.


# PSCmdlet version REQUIRES [CmdletBinding()] on your function!!!
# $($(Get-Command -Name $($PSCmdlet.MyInvocation.InvocationName)).Parameters) | `
#   %{ Get-Variable -Name $_.Values.Name -ErrorAction SilentlyContinue; } 

# -Scope:'Local' FILTERS out any global params
# (Get-Variable -Scope:'Local' -Include:@($MyInvocation.MyCommand.Parameters.keys)) | ft

# PSCommandPath supposedly available/usable "in all situations" - so this may be the most useful of all of them, BUT it shows global params [Debug, ErrorAction, etc...]
# (Get-Command -Name $PSCommandPath).Parameters  | `
#    %{ Get-Variable -Name $_.Values.Name -ErrorAction SilentlyContinue; } 

ParamsFormat1 / Hybrid VERSION: 함수 정의에 표시되는 대로 "기본 Params"를 출력합니다.-Scope를 결합합니다."로컬 및 "항상 사용 가능한" 버전은 두 매개변수 유형과 이름, 값을 모두 가져옵니다.

Write-Host "Params("
# TBD Figure out how to expand @{} of System.Collections.Hashtable

# HYBRID VERSION: Combine the -Scope:"Local" and "always available" versions to get BOTH param TYPES as well as Name, Value

# If you remove LocalList Filter here, it will also show "Global" function properties like Debug, ErrorAction, etc...
$LocalList = $(Get-Variable -Scope:'Local' -Include:@($MyInvocation.MyCommand.Parameters.keys) | Select-Object -ExpandProperty Name) -join "|"
# VERSION: Wrapper script with DEFAULTS : normally DOES include Global vars [Debug, ErrorAction, etc]. but DOES preserve param order as-written.
((Get-Command -Name $PSCommandPath).Parameters | `
    Select -ExpandProperty Values | `
    Where-Object { $_.Name -Match $LocalList } | `
    Format-Table -HideTableHeaders -AutoSize `
    @{ Label="Type"; Expression={"[$($_.ParameterType )]"}; }, `
    @{ Label="Name"; Expression={"`t`$$($_.Name)"}; }, `
    @{ Label="Equals"; Expression={"="}; }, `
    @{ Label="Value"; Expression={ If( $_.ParameterType -Match "String" ) { "`"$((Get-Variable -Name $_.Name -EA SilentlyContinue).Value)`"" } Else{ $((Get-Variable -Name $_.Name -EA SilentlyContinue).Value)}; }; }, `
    @{ Label="RowEndComma"; Expression={ "," }; }
    #@{ Label="Value"; Expression={ $((Get-Variable -Name $_.Name -EA SilentlyContinue).Value) }; } # (OPTIONAL) Values only, no wrapping quotes
)
Write-Host ")";

CommandFormat2 / SIMPLER VERSION: 명령줄 인수로 호출(TYPE은 필요하지 않음).이렇게 하면 전역 변수가 필터링되고 매개 변수 순서가 유지되지 않습니다.(알파벳 순으로 표시?)

# VERSION: Call with CommandLine Args (TYPES not available - TBD needs more work to display String, Array, and Hashmap/PsCustomObject ["", @() and {}] types better): filters out Global vars, does NOT preserve param ordering.
# If needed, cut+paste OPTIONAL lines down above Format-Table line.
# Where-Object { $_.Value } | `     # (Optional) remove any Null items.  
# Sort-Object -Property Name | `    # (Optional) sort output
    (Get-Variable -Scope:'Local' -Include:@($MyInvocation.MyCommand.Parameters.keys) | `    
        Format-Table -HideTableHeaders -AutoSize `
        @{ Label="Name"; Expression={"`t-$($_.Name)"}; }, `
        @{ Label="Equals"; Expression ={":"}; }, `
        @{ Label="Value"; Expression={ If( $_.ParameterType -NotMatch "String" ) { $_.Value; } Else {"`"$($_.Value)`"";} }; Alignment="left"; }
    )

언급URL : https://stackoverflow.com/questions/21559724/getting-all-named-parameters-from-powershell-including-empty-and-set-ones

반응형