将 powershell Select-Object 与包含方括号的 属性 一起使用

Using powershell Select-Object with a property that contains a square bracket

我正在通过 AdomdClient 从 SSAS 模型中获取数据集,这为我提供了一个对象,该对象的属性名称中包含方括号。这使我无法将 Select-Object 仅用于 select 属性子集(或者更具体地说,使用计算属性重命名它们,以便它们与另一个 dataset/obj 匹配)

我知道有关在文件名中使用方括号的问题,并尝试转义方括号。理想情况下,我想学习一种处理这些属性的 powershell 方法,尽管任何解释如何在没有括号的情况下获取 adomdclient 到 return 数据的答案也对我的特定内容非常有帮助重命名属性的目标。

下面的代码片段可以在没有 SSAS/adomdclient 依赖项的情况下重新创建我所看到的内容。由于程序集依赖性,我为此代码使用 powershell 5.1:

$bracketedTestObj = New-Object PSObject -Property @{
    "MyProperty[WithBrackets]" = "bracketedValue"
    "MyPropertyWithoutBrackets" = "nonbracketedValue"
}

Write-host "The whole obj"
$bracketedTestObj | ft

Write-host "Select just the non bracketed property"
$bracketedTestObj | select-Object "MyPropertyWithoutBrackets" | ft

# I cannot figure out how to escape the [] and select only the bracketed property 
Write-host "Select just the bracketed property"
$bracketedTestObj | select-Object "MyProperty[WithBrackets]" | ft

Write-host "Select just the bracketed property, 1 backtick"
$bracketedTestObj | select-Object "MyProperty`[WithBrackets`]" | ft

Write-host "Select just the bracketed property, 2 backtick"
$bracketedTestObj | select-Object "MyProperty``[WithBrackets``]" | ft

Write-host "Select just the bracketed property, 3 backtick"
$bracketedTestObj | select-Object "MyProperty```[WithBrackets```]" | ft

Write-host "Select just the bracketed property, 4 backtick"
$bracketedTestObj | select-Object "MyProperty````[WithBrackets````]" | ft

results(我没有包含反引号大于`的结果,但是结果是一样的:

The whole obj

MyPropertyWithoutBrackets MyProperty[WithBrackets]
------------------------- ------------------------
nonbracketedValue         bracketedValue          


Select just the non bracketed property

MyPropertyWithoutBrackets
-------------------------
nonbracketedValue        


Select just the bracketed property

MyProperty[WithBrackets]
------------------------
                        


Select just the bracketed property, 1 backtick

MyProperty[WithBrackets]
------------------------
                        

如果方括号是通配符的一部分,例如 Select-Object MyProp*,那么也许...

PS C:\> $bracketedTestObj|Select-Object 'MyProperty[[]WithBrackets[]]'

MyProperty[WithBrackets]
------------------------
bracketedValue

[编辑:感觉它不应该工作,就像 []] 应该打破它,或者整个外部 [...] 应该以乱序的顺序接收其中的任何字母,但是快速测试这些问题似乎都没有发生。

解决方法,匹配单个字符的通配符:

Select-Object "MyProperty?WithBrackets?"

据我所知,无法强制 Select-Object 尝试扩展 属性 名称中的通配符序列。

最安全的解决方法是使用计算的 属性 计算输入项上的目标 属性:

$object = [pscustomobject]@{
  'MyProperty[WithBrackets]' = 123
  'OtherProperty' = 456
}

$object |Select-Object @{Name='MyProperty[WithBrackets]';Expression={$_.'MyProperty[WithBrackets]'}}

为了保持干燥,您可能需要编写一个小的实用函数来生成这样的计算 属性 定义:

function New-LiteralPropertySelector {
  param([string[]]$PropertyName)

  foreach($name in $PropertyName){
    if([WildcardPattern]::ContainsWildcardCharacters($name)){
      # Property name contains wildcard characters -> special handling required
      Write-Output @{Name=$name;Expression={$_.$name}.GetNewClosure()}
    }
    else {
      # No wildcards, return as-is
      Write-Output $name
    }
  }
}

现在你可以做:

$object = [pscustomobject]@{
  'MyProperty[WithBrackets]' = 123
  'OtherProperty' = 456
  'ImportantProperty' = 789
}

$object |Select-Object @(New-LiteralPropertySelector 'MyProperty[WithBrackets]','ImportantProperty')

并得到预期的结果:

MyProperty[WithBrackets] ImportantProperty
------------------------ -----------------
                     123               789