Получение всех Именованных параметров из Powershell, включая пустые и установленные

Я пытаюсь найти способ получить всю информацию о параметрах из powershell script. Ex script:

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

Если бы я мог отфильтровать параметры script и параметры по умолчанию, мне было бы хорошо идти.

Обновление 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;

Ответ 1

Проверьте это решение. Это использует атрибут CmdletBinding(), который предоставляет некоторые дополнительные метаданные с помощью встроенной переменной $PSCmdlet. Вы можете:

  • Динамически получить имя команды, используя $PSCmdlet
  • Получить список параметров для команды, используя Get-Command
  • Изучите значение каждого параметра с помощью командлета Get-Variable

код:

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                                            

Ответ 2

Для динамического считывания значения используйте функцию get-variable/cmdlet

write-host (get-variable "foo")

Чтобы распечатать все параметры, выполните следующие

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

Ответ 3

Я нашел это наиболее полезным для 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"
    }
}

Ответ 4

Надеюсь, некоторые могут найти этот однострочный файл полезным:

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  

Ответ 5

Я играл с двумя решениями, которые мне нравились в этой теме, они оба работают. однако мне нужно было создать ошибку при пропуске параметра для сборки script

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

Ответ 6

                         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;

                    $parameterobj=$ParameterList.Values
                      foreach($parameter in $parameterobj ) { #Write-Host $pr.Name
                            Get-Variable -Name $parameter.Name -ErrorAction SilentlyContinue;

                           }
                        }

                    cls
                    test -asdf blah;

это сработало для меня.

Ответ 7

Для тех из вас, кто не хочет использовать cmdletbinding(), есть вариант с одним вкладышем, который я нашел выше:

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

$ PSCommandPath всегда доступен