【问题标题】:How can I use splatting in a parameterized function?如何在参数化函数中使用飞溅?
【发布时间】:2014-07-28 08:21:39
【问题描述】:

我正在编写一个参数化函数并尝试使用 splatting 来重用参数集。

$Computername='localhost'

$params = @{'computername'=$Computername;
           'credential'='administrator'}

function Get-Diskinfo {
    Param ($drive,$computername,$credential)

    Get-WmiObject win32_logicaldisk -Filter "DeviceID = '$drive'" @params
}

这样执行失败,无法识别用户输入的服务器名称。它仍然采用最初指定的$Computername 的值。

Get-Diskinfo -drive c: Server1 administrator

如何让它识别用户输入的计算机名?我错过了什么吗?

【问题讨论】:

    标签: powershell parameters parameter-passing powershell-3.0


    【解决方案1】:

    您需要使用 PowerShell 自动定义的东西来代替随机散列表:

    function Get-Diskinfo {
    Param ($drive,$computername,$credential)
    
    # Need to remove any parameter that is used "internally" and don't exist on cmdlet
    $PSBoundParameters.Remove('drive') | Out-Null
    
        Get-WmiObject win32_logicaldisk -Filter "DeviceID = '$drive'" @PSBoundParameters
    
    }
    
    Get-Diskinfo -drive c: Server1 administrator
    

    或者:使用传递的参数在你的函数中构建 $parms:

    function Get-Diskinfo {
    Param ($drive,$computername,$credential)
    
    $parms = @{
        computername = $Computername
        credential = $credential
    }
    
    Get-WmiObject win32_logicaldisk -Filter "DeviceID = '$drive'" @parms
    }
    

    【讨论】:

      【解决方案2】:

      在你的函数内部之前,你不会调用@parms

      这应该可以工作,使用函数中的参数来提取 WMI 查询:

      $Computername='localhost'
      $parms = @{'computername'=$Computername;
          'credential'='administrator'}
      
      function Get-Diskinfo {
          Param ($drive,$computername,$credential)
          Get-WmiObject win32_logicaldisk -Filter "DeviceID = '$drive'" -ComputerName $computername -Credential $credential
          }
      

      然后使用splatting运行函数:

      Get-Diskinfo -drive c: @parm
      

      函数还是可以直接使用参数运行的:

      Get-Diskinfo -drive c: Server1 administrator
      

      【讨论】:

      • 但这超出了目的。脚本的用户需要能够输入他选择的服务器名称。
      • 您仍然可以使用带有 splatting 的哈希表或 -ComputerName 参数将计算机名称传递给函数。您的脚本的问题是 $parm 设置在函数外部,在函数内部调用,但从未传递给函数。
      • 最终用户不必使用@parms 数组。我正在尝试编写多个类似的函数并重用这个通用参数集。所以必须在函数外设置,在函数内调用。
      • 我回答了被问到的问题。 $parms 中包含 $Computername。如果你想要不同的东西,你应该编辑问题。
      • Params 甚至不应该是一个数组。为什么不直接使用 PowerShell 的内置参数功能?
      【解决方案3】:

      您的$params 哈希表在您创建它时获得它的价值,而不是在使用它时。您的 $computername,$credential 参数永远不会在您的函数中被引用,这意味着它们是死参数。

      您不能同时对同一个参数使用 splatting 和普通函数调用。您应该只在函数脚本块中使用参数。喷溅仅适用于最终用户。 @Tim Ferril 向您展示了如何正确编写函数。

      如果您需要能够同时使用两个默认值并且能够更改 ex. ComputerName 对于一个 cmdlet,那么您应该使用默认值而不是 splatting。例如:

      function Test-Global {
      param(
          $ComputerName = $global:PC,
          $Username = $global:username
      )
      
      "Computername is '$ComputerName'"
      "Username is '$UserName'"
      }
      
      #Set the reusable variables in global scope and call your function
      $global:Username = "Frode"
      $global:PC = "MyPC"
      
      PS C:\Users\Frode> Test-Global
      Computername is 'MyPC'
      Username is 'Frode'
      
      #If I need to modify the server for one function, I'd simply specify that parameter
      PS C:\Users\Frode> Test-Global -ComputerName server1
      Computername is 'server1'
      Username is 'Frode'
      

      为了让用户更容易设置默认值,您也可以为此创建一个函数。

      #Create your reusable parameters
      function Set-Params {
      param(
          $ComputerName,
          $Username
      )
          if($Username) { $global:Username = $Username }
          if($ComputerName) { $global:PC = $ComputerName }
      }
      
      PS C:\Users\Frode> Set-Params -ComputerName Test1 -Username Test1
      
      PS C:\Users\Frode> Test-Global
      Computername is 'Test1'
      Username is 'Test1'
      
      PS C:\Users\Frode> Set-Params -ComputerName Test2
      
      PS C:\Users\Frode> Test-Global
      Computername is 'Test2'
      Username is 'Test1'
      

      【讨论】:

      • "你不能同时对同一个参数使用 splatting 和正常的函数调用。" ...这是我需要知道的。
      • 我正在编写多个使用$Computername$Credentials 参数的函数。我想我可以使用 splatting 将它们声明为全局参数集,然后在所有函数中重用它们。如果可以的话,对我的代码进行重复数据删除......
      • 你仍然可以.. 看看我的答案.. 通过使用函数或模块脚本来声明 som 全局变量并将它们指定为函数参数中的默认值,你可以让你的全局参数集和能够在需要时修改值。
      • 但是用户必须运行 2 个命令而不是一个?我可以在每个函数中调用Set-Params 吗?
      • 是的。您只能使用Set-Params 更改默认值。如果您需要为一个函数调用指定另一台计算机,您只需像 test-globals -computername anothercompuer 一样指定它。
      猜你喜欢
      • 2022-08-10
      • 1970-01-01
      • 2020-08-02
      • 2021-07-18
      • 2018-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多