如何区分未设置参数$ false,0,空字符串?

时间:2017-08-08 14:59:00

标签: powershell powershell-v2.0 powershell-v3.0 powershell-v4.0

我有更新WMI中对象的函数。我希望用户能够在参数中仅指定他想要更新的值。我该怎么办?

function UpdateObject ([bool] $b1, [bool] $b2, [int] $n1, [string] $s1)
{
    $myObject = GetObjectFromWmi #(...)
    #(...)

    #This is bad. As it overrides all the properties.
    $myObject.b1 = $b1
    $myObject.b2 = $b2
    $myObject.n1 = $n1
    $myObject.s1 = $s1

    #This is what I was thinking but don't kwow how to do
    if(IsSet($b1)) { $myObject.b1 = $b1 }
    if(IsSet($b2)) { $myObject.b2 = $b2 }
    if(IsSet($n1)) { $myObject.n1 = $n1 }
    if(IsSet($s1)) { $myObject.s1 = $s1 }

    #(...) Store myObject in WMI.
}

我尝试将$null作为参数传递,但它会自动转换为$false bool0 int和{empty string 1}} string

你有什么建议?

4 个答案:

答案 0 :(得分:5)

检查$PSBoundParameters以查看它是否包含带有参数名称的密钥:

if($PSBoundParameters.ContainsKey('b1')) { $myObject.b1 = $b1 }
if($PSBoundParameters.ContainsKey('b2')) { $myObject.b2 = $b2 }
if($PSBoundParameters.ContainsKey('n1')) { $myObject.n1 = $n1 }
if($PSBoundParameters.ContainsKey('s1')) { $myObject.s1 = $s1 }

$PSBoundParameters的行为类似于哈希表,其中键是参数名称,值是参数'值,但它只包含绑定参数,这意味着显式传递的参数。 不包含用默认值填充的参数(使用$PSDefaultParameterValues传递的参数除外)。

答案 1 :(得分:3)

briantist's answer上构建,如果您知道所有参数都作为目标对象的属性存在,您只需循环遍历$PSBoundParameters哈希表并逐个添加:

foreach($ParameterName in $PSBoundParameters.Keys){
    $myObject.$ParameterName = $PSBoundParameters[$ParameterName]
}

如果只将某些输入参数作为属性值传递,您仍然可以只使用以下内容指定列表一次:

$PropertyNames = 'b1','b2','n1','s1'
foreach($ParameterName in $PSBoundParameters.Keys |Where-Object {$PropertyNames -contains $_}){
    $myObject.$ParameterName = $PSBoundParameters[$ParameterName]
}

答案 2 :(得分:2)

为了节省您自己必须为 想要更改的每个属性创建参数,请考虑使用哈希表或其他对象将此信息传递给您的函数。

例如:

function UpdateObject ([hashtable]$properties){

    $myObject = GetObjectFromWmi

    foreach($property in $properties.Keys){

        # without checking
         $myObject.$property = $properties.$property

        # with checking (assuming members of the wmiobject have MemberType Property.
        if($property -in (($myObject | Get-Member | Where-Object {$_.MemberType -eq "Property"}).Name)){
            Write-Output "Updating $property to $($properties.$property)"
            $myObject.$property = $properties.$property
        }else{
            Write-Output "Property $property not recognised"
        }

    }
}

UpdateObject -properties {"b1" = $true; "b2" = $false}

答案 3 :(得分:1)

如果您希望用户明确指定[Boolean]参数或省略(而不是可以存在的[Switch]参数),则可以使用[Nullable[Boolean]]。例如:

function Test-Boolean {
  param(
    [Nullable[Boolean]] $Test
  )

  if ( $Test -ne $null ) {
    if ( $Test ) {
      "You specified -Test `$true"
    }
    else {
      "You specified -Test `$false"
    }
  }
  else {
    "You did not specify -Test"
  }
}

在此示例函数中,$Test变量将为$null(用户未指定参数),$true(用户指定-Test $true)或{{1} (用户指定$false)。如果用户在没有参数参数的情况下指定-Test $false,PowerShell将抛出错误。

换句话说:这会给你一个三态-Test参数(缺失,显式为true或显式为false)。 [Boolean]只给你两个状态(现在或明确为真,缺席或明确为假)。