powershell 返回在PSObject中具有特定“值”的对象的“名称”

bq3bfh9z  于 2022-11-10  发布在  Shell
关注(0)|答案(1)|浏览(141)

我使用以下命令将JSON文件转换为PSObject:

$json = Get-Content $filepath -Raw | ConvertFrom-Json

下面是PSObject中当前内容的一个示例:

Value           : Production
MemberType      : NoteProperty
IsSettable      : True
IsGettable      : True
TypeNameOfValue : System.String
Name            : Environment
IsInstance      : True

我知道您可以通过使用以下命令来获得它的价值:

$json.psobject.properties["Environment"].Value

这将返回“Products”

问题

有没有一种方法可以根据值返回名称,就像我可以像上面所示那样根据名称返回值?

即如何退还Environment?

作为后台,我正在编写一个脚本,该脚本将遍历所有值,如果值为空,则需要打印名称。

9wbgstp7

9wbgstp71#

Theo的帮助下,您已经找到了解决方案,但让我用一些背景信息来详细说明:


# Read a sample object from JSON text.

$fromJson = @'
{
  "Foo": "Bar",
  "Environment": "Production",
  "Other": "Stuff"
}
'@ | ConvertFrom-Json

# Find the name of the property/ies whose value is 'Production'

# -> 'Environment'

$fromJson.psobject.Properties.Where({ $_.Value -eq 'Production' }).Name

注:

  • 以上依赖于PowerShell在所有对象上公开的内在psobject属性,这是一个丰富的反射来源,例如通过.psobject.Properties对给定对象的属性进行反射,以及用于筛选的内在.Where()方法(Where-Objectcmdlet的一个性能更好、功能更丰富的替代方案)。
    代码仅适用于从JSON解析的对象的顶级属性。如果您需要搜索整个对象*图,即嵌套对象,以查找层次结构中任何级别的值,则需要付出更多努力。

下面的示例假定已经定义了函数Get-PropertyPathByValue(见下文):


# Read a *nested* sample object from JSON text.

$fromJson = @'
{
  "Foo": "Bar",
  "Nested": {
    "More": "Stuff",
    "Environment": "Production"
  },
  "Other": "Stuff"
}
'@ | ConvertFrom-Json

# Find the value 'Production' anywhere in the object hierarchy,

# and return the matching property's name *path* (dot notation).

# -> 'Nested.Environment'

$fromJson | Get-PropertyPathByValue -Value 'Production'

Get-PropertyPathByValue源码-注意可以搜索的值类型限制:


# Finds a *simple* value in the object graphs given and returns the path of

# matching properties in dot notation (e.g., 'foo.bar`).

# Note: *Simple* means a *single* (non-collection) value that is either:

# * a string or

# * an instance of a .NET primitive or similar type (numbers, dates).

function Get-PropertyPathByValue {
  param([Parameter(ValueFromPipeline, Mandatory)] [AllowNull()]  [object] $InputObject, [Parameter(Mandatory)] [AllowNull()] $Value, [string] $NamePath)
  process {   
    if ($null -eq $InputObject -or $InputObject.GetType().IsPrimitive -or $InputObject.GetType() -in [string], [datetime], [datetimeoffset], [decimal], [bigint]) {
      # A null-like value or a primitive / quasi-primitive type -> output.
      if ($Value -eq $InputObject) { return $NamePath }
    }
    elseif ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [System.Collections.IDictionary]) {
      # A collection of sorts (other than a string or dictionary (hash table)), 
      # recurse on its elements.
      $i = 0
      foreach ($o in $InputObject) { Get-PropertyPathByValue $o $Value ($NamePath + '[' + $i++ + ']') }
    }
    else { 
      # A non-quasi-primitive scalar object or a dictionary:
      # enumerate its properties / entries.
      $props = if ($InputObject -is [System.Collections.IDictionary]) { $InputObject.GetEnumerator() } else { $InputObject.psobject.properties }
      $sep = '.' * ($NamePath -ne '')
      foreach ($p in $props) {
        Get-PropertyPathByValue $p.Value $Value ($NamePath + $sep + $p.Name)
      }
    }
  }
}

相关问题