【问题标题】:Split property value in Powershell在 Powershell 中拆分属性值
【发布时间】:2017-06-14 04:21:42
【问题描述】:

我目前正在尝试通过Out-GridView 来简单了解我们的组策略对象。为此,我使用了Get-GPO cmdlet,如下所示:

Get-GPO -all |
    Select-Object -Property DisplayName, Description |
    Sort-Object -Property DisplayName |
    Out-GridView

在我们公司,我们使用描述字段的第一行来存储创建策略的管理员的名称,然后所有以下行都包含一个简短的描述。

我希望能够使用列标题Responsability 获取Description 字段的第一行,并将该字段的所有其他行放在单独的列中。所以假设我当前的代码会给我一个这样的表:

DisplayName | Description
-------------------------
GPO1        | Username
            | stuff
            | stuff

我希望它看起来像这样:

DisplayName | Responsability | Description
------------------------------------------
GPO1        | Username       | stuff
            |                | stuff

我怎样才能做到这一点?

【问题讨论】:

  • 您需要使用计算属性来处理从它的声音在换行符上拆分的字符串。
  • 您能向我们展示结果,但不能向我们展示 Out-GridView 中的结果吗?那些处于控制台模式的人

标签: powershell


【解决方案1】:

正如@Matt 建议的那样,您可以使用calculated property

那么由于Description 是一个字符串,而不是一个字符串数组,因此您需要在换行符处拆分行。这可以通过使用-split 来完成,因为它是来自 GPO 的信息,我们可以假设 Windows 行结尾为 `r`n(否则您可以使用 [environment]::newline

第一个属性,使用数组元素[0] 将是第一行。对于第二个属性,我们需要将数组保存在一个变量中。然后我们可以使用该变量的长度来获取第一个元素到最后一个元素。

Get-GPO -all |
    Select-Object -Property DisplayName, @{
            Name = "Responsibility"
            Expression = {($_.Description -split "`r`n")[0]}
        }, @{
            Name = "Description"
            Expression = {
                $linearray = ($_.Description -split "`r`n")
                $linearray[1..($linearray.length - 1)] | Out-String
            }
        } |
    Sort-Object -Property DisplayName |
    Out-GridView

或者,您可以创建一个新对象而不是使用计算的属性。

Get-GPO -all |
    ForEach-Object {
        $linearray = ($_.Description -split "`r`n")
        [pscustomobject]@{
            "DisplayName" = $_.DisplayName
            "Responsibility"= $linearray[0]
            "Description" = $linearray[1..($linearray.length - 1)] | Out-String
        }
    } |
    Sort-Object -Property DisplayName |
    Out-GridView

【讨论】:

  • 您可以添加 |输出字符串以保持描述中的格式$linearray[1..($linearray.length - 1)] | Out-String
  • 使用 Out-String 似乎对我来说很好,因为转换为字符串会删除所有换行符
【解决方案2】:

首先要了解Get-GPO 返回的是什么:一个对象数组,每个对象都有一组属性。

表格中显示的是一系列行(每个对象一个),列是该对象的属性值。

因此,如果您想要一个新列,则需要一个新属性。

有两种方法可以做到这一点:使用Select-Object 创建计算属性或通过Add-Member 向对象添加属性。

计算

您可以将哈希表作为属性提供给Select-Object,并且该哈希表必须有两个键:

  • Name(物业名称)
  • Expression(将执行以确定值的脚本块,其中$_ 指的是对象本身)
Get-GPO -all |
Select-Object -Property DisplayName, Description, @{
    Name = 'Responsibility'
    Expression = {
        ($_.Description -split '\r?\n')[0] # First line
    }
} |
Sort-Object -Property DisplayName |
Out-GridView

新成员

您可以使用 ScriptProperty,它会在每次对对象调用属性时执行一个脚本块。使用$this 来引用此上下文中的对象。

Get-GPO -all |
Add-Member -MemberType ScriptProperty -Name Responsibility -Value {
    ($this.Description -split '\r?\n')[0] # First line
} -Force -PassThru |
Select-Object -Property DisplayName, Responsibility, Description |
Sort-Object -Property DisplayName |
Out-GridView

【讨论】:

  • @BenH 是的,这是真的,但是可以应用相同的逻辑来覆盖描述或创建新的 DisplayDescription 属性或其他任何东西。您的答案已经像我一样显示了解决方案(我在您发布之前就开始写答案,但直到之后才完成); +1。
【解决方案3】:

我可能会使用这样的东西:

Get-GPO -All | ForEach-Object {
  $info = $_.Description
  $pos = $info.IndexOf([Environment]::NewLine)
  if ( $pos -gt 0 ) {
    $responsibility = $info.Substring(0,$pos)
    $description    = $info.Substring($pos + [Environment]::NewLine.Length)
  }
  else {
    $responsibility = ""
    $description    = $info
  }
  [PSCustomObject] @{
    "DisplayName"    = $_.DisplayName
    "Responsibility" = $responsibility
    "Description"    = $description
  }
}

这样您可以保留格式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2012-07-08
    • 1970-01-01
    相关资源
    最近更新 更多