【问题标题】:How to dynamically create an array and use it in Powershell如何动态创建数组并在 Powershell 中使用
【发布时间】:2013-07-29 15:49:18
【问题描述】:

我需要创建然后使用数组,但我需要动态创建。我正在开发脚本来获取应用程序池内存,但是当我们有超过 1 个工作进程时,我需要将内存存储在数组中,然后计算平均值。

我正在使用它来创建它

New-Variable -Name "Array_$($AppPoolName)" -Value @()

但我不知道如何使用动态名称将数据添加到数组中,就像我使用固定名称 ($var += <Value>) 时那样。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    你可以使用Get-Variable:

    $var = Get-Variable -Name "Array1_$($AppPoolName)" -ValueOnly
    $var += <Value>
    

    最后通知-ValueOnly。否则你会得到一个变量PSObject。来自technet

    Get-Variable cmdlet 在当前控制台中获取 Windows PowerShell 变量。您可以通过指定 ValueOnly 参数来仅检索变量的值...

    【讨论】:

    • 如果我没记错的话,我认为这个想法是实际修改动态命名的数组,而不是将其分配给具有固定名称的变量并对其进行修改。
    • 为了修改变量,您首先必须根据“动态”名称将其检索到然后操作的变量中。虽然您可以使用Set-Variable,但该语法比仅使用常规变量更麻烦。一般来说,我不会首先使用动态命名的变量。我更有可能使用哈希表。
    • 如果您考虑一下,这样做与首先将其命名为 $var 没有什么不同,因为您正在创建一个动态命名的空数组,然后为了向其中添加元素,您将该空数组分配给具有预定名称的变量,然后对其进行修改。这实际上让我重新思考我的答案......
    • 这就是为什么我说我首先会使用哈希表。 :-)
    【解决方案2】:

    使用Get-Variable 检索动态命名的变量,例如:

    $var = Get-Variable "Array_$AppPoolName" -ValueOnly
    $var += <value>
    

    为了完整起见,您还可以使用 Set-Variable 但它不直接支持数组 concat 语法,例如:

    Set-Variable "Array_$AppPoolName" (Get-Variable "Array_$AppPoolName" -ValueOnly) += <value>)
    

    是的,这是一个喷子。也许更好的选择是只使用哈希表:

    $ht = @{"Array_$($AppPoolName)" = @()}
    $ht."Array_$($AppPoolName)" += 1,2,3
    

    【讨论】:

      【解决方案3】:

      您可以先将动态名称存储在变量中,然后使用Invoke-Expression添加到变量中,如下:

      $dynamicname = "Array1_$AppPoolName"
      New-Variable -Name $dynamicname -Value @()
      Invoke-Expression "`$$dynamicname += 'new value'"
      

      (请注意,$AppPoolName 周围不需要 $();您可以自行插入变量。)

      或者,您可以使用 Invoke-Expression 重新派生动态名称并修改具有该派生名称的变量:

      New-Variable -Name "Array_$AppPoolName" -Value @()
      Invoke-Expression "`$Array1_$AppPoolName += 'new value'"
      

      【讨论】:

      • 我通常对使用Invoke-Expression 非常谨慎,因为它可用于脚本注入攻击。虽然在您的场景中不太可能尝试以下操作:将 {} 放在 iex 字符串中的 dynamicname 周围,例如${dynamicname} 然后将 $dynamicname 设置为 $dynamicName = "Array_Foo;del foo.ps1 -wh;`$var" 现在执行 iex 语句。 :-)
      • 我想,但它是否必须是脚本采用动态值以在变量名称中使用的情况,该变量名称由人源确定,而不是脚本所在的上下文跑步?任何可以直接调用脚本并将其用于注入攻击的用户都可以更方便地在 shell 提示符下破坏系统,如果他愿意的话....
      • 是的,这就是为什么我说在这种情况下不太可能。但是,每当您使用 iex 时,您都应该考虑一下。
      • 这是一个很好的警告,在极少数情况下传递给 iex 的变量可能来自恶意来源。在这些情况下,可以在 iex 语句之前将其用作一种安全机制:if ($variable_to_be_used_in_iex -match '[;&gt;|]') {throw "The value you supplied contains a $($matches[0]) character. What are you trying to pull?!"}(将任何其他可能被滥用的字符添加到类中)
      【解决方案4】:

      您可以在没有哈希表和 Invoke-Expression 的情况下做到这一点:

      New-Variable -Name "Array_$($AppPoolName)" -Value @()
      ( Get-Variable -Name "Array_$($AppPoolName)" ).Value += <Value>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-30
        • 2021-03-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多