【问题标题】:How to add a custom property to a PowerShell array?如何将自定义属性添加到 PowerShell 数组?
【发布时间】:2018-02-19 15:28:37
【问题描述】:

假设我有一个 PowerShell 数组 $Sessions = @(),我将用 PSCustomObjects 填充它。如何将自定义属性添加到数组本身?例如。所以我可以拥有内置的$Sessions.Count 和我想设置为活动会话数的$Sessions.Active。

我知道我可以向 PSCustomObjects 添加属性(以一种肮脏的方式)

$MyCustomObject = "" | Select-Object Machine, UserName, SessionTime

但尽管在数组上这样做不会导致属性被添加。

那么我怎样才能实现我的目标呢?有没有办法创建自定义数组?

【问题讨论】:

  • 只用Add-Member -InputObject $sessions ...?这就是它的目的
  • 但请注意,附加到该数组 ($sessions += ...) 将替换该数组,从而删除附加属性。更安全的方法是使用具有不同属性的数组和状态的自定义对象。话虽如此,根据您要使用它的目的,使用不同的列表变量 $activeSessions/$inactiveSessions 而不是向列表中添加属性或向个人添加 Active 属性可能更合适会话对象。
  • @Matt 如果您只想将 postet 作为答案...我实际上出于懒惰而滥用了Select-Object,这使我无法解决问题。谢谢。 @AnsgarWiechers 感谢有关 += 的提示,让我免于误拨 Add-Member 电话。
  • 我忘了提到你所做的Select 是一种完全可以接受的创建空白石板对象的方法。在这方面每个人都有自己的。您的方法的唯一挫折在于它对于类型和复杂属性之类的东西有多基本。还是没有问题。

标签: arrays powershell properties pscustomobject


【解决方案1】:

如上所述,您的问题的答案是在数组对象上使用Add-Member。

Add-Member -InputObject $sessions -MemberType NoteProperty -Name "State" -Value "Fabulous"

在创建对象之后为每个元素添加一个属性是类似的。

$sessions | ForEach-Object{
    $_ | Add-Member -MemberType NoteProperty -Name "State" -Value "Fabulous"
}

这当然带有警告(我忘记了)。来自cmets

但请注意,附加到该数组 ($sessions += ...) 将替换该数组,从而删除附加属性。

Ansgar Wiechers

根据您的用例,还有其他选项可以满足您的需求。您可以将数组元素保存到不同的变量中:

# Check the current object state
$state = $object.Property .....

# Add to the appropriate array.
if($state -eq "Active"){
    $activeSessions += $object
} else {
    $inactiveSessions += $object
}

或者您仍然可以根据需要使用Where-Object 存储您的状态属性和发布流程:

# Process each inactive session
$sessions | Where-Object{$_.State -eq "Active"} | ForEach-Object{}

为避免破坏/重新创建数组问题,这可能会导致性能消耗,您也可以使用数组列表来代替。

$myArray = New-Object System.Collections.ArrayList
Add-Member -InputObject $myArray -MemberType ScriptMethod -Name "NeverTellMeTheOdds" -Value {
    $this | Where-Object{$_ % 2 -ne 0}
}

$myArray.AddRange(1..10)
$myArray.NeverTellMeTheOdds()

请注意,数组添加了它的成员,然后我们添加了它的元素。

【讨论】:

    【解决方案2】:

    正如 Matt 所评论的,您可以通过将 Add-Member 作为位置参数提供给 -InputObject 参数来在可枚举类型上使用它。

    若要在添加新属性后调整大小,请使用通用 List 而不是 @():

    $list = [System.Collections.Generic.List[psobject]]::new()
    $list.AddRange(@(
      [pscustomobject]@{SessionId = 1; Active = $true}
      [pscustomobject]@{SessionId = 2; Active = $false}
      [pscustomobject]@{SessionId = 3; Active = $true}
    ) -as [psobject[]])
    
    Add-Member -InputObject $list -MemberType ScriptProperty -Name ActiveSessionCount -Value {
      return @($this |? Active -eq $true).Count
    }
    

    现在您可以轻松检索活动会话数:

    PS C:\> $list.ActiveSessionCount
    2
    

    【讨论】:

    • 我建议了一个数组列表。我们的想法似乎很相似。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 2012-07-18
    • 2012-11-25
    • 1970-01-01
    相关资源
    最近更新 更多