【问题标题】:Get-GPOReport and Search For Matched Name Value获取 GPOReport 并搜索匹配的名称值
【发布时间】:2021-03-25 22:36:32
【问题描述】:

我正在尝试使用 PowerShell 命令“Get-GPOReport”以 XML 字符串格式获取 GPO 信息,这样我就可以在其中搜索具有未知和不同元素标记名称的子元素值(我不认为 XML 对象格式对我有用,所以我没有使用“[xml]”执行强制转换),但我无法解析 XML 输出,以便我可以在所需的“名称”元素之后获取一两行与我正在搜索的文本匹配的行。

之后,我一直在尝试使用带有 XPath 的“Select-String”或“Select-XML”(格式不清楚,我不知道是否可以为各种策略记录位置使用格式)来匹配文本和抓住一个价值,但我没有运气。

另外,如果有人知道如何搜索 GPMC GUI 名称(即“强制密码历史记录”)而不是需要先找到后端等效名称来搜索(即“PasswordHistorySize”),那也会更有帮助.

以下初始代码是起作用的部分:

$String = "PasswordHistorySize"     # This is an example string, as I will search for various strings eventually from a file, but I'm not sure if I could search for equivalent Group Policy GUI text "Enforce password history", if anyone knows how to do that.
$CurrentGPOReport = Get-GPOReport -Guid $GPO.Id -ReportType Xml -Domain $Domain -Server $NearestDC

If ($CurrentGPOReport -match $String) 
{
    Write-Host "Policy Found: ""$($String)""" -Foregroundcolor Green
    #
    #
    # The following code is what I've tried to use to get value data, without any luck:
    #
    $ValueLine1 = $($CurrentGPOReport | Select-String -Pattern $String -Context 0,2)
    $Value = $($Pattern = ">(.*?)</" ; [regex]::match($ValueLine1, $Pattern).Groups[1].Value)
}

【问题讨论】:

    标签: powershell parsing search match group-policy


    【解决方案1】:

    我从昨天开始就一直在看这个,不明白为什么Select-String 不起作用,今天我想通了...报告存储为多行字符串,而不是数组的字符串。您可以针对该值执行-match,但Select-String 不喜欢它看起来的多行格式。如果你在上面-split '[\r\n]+',你可以得到Select-String 来找到你的字符串。

    如果您想使用 RegEx 来仅窥探设置值,您可以使用多行 regex 搜索来完成,如下所示:

    $String = "PasswordHistorySize"     # This is an example string, as I will search for various strings eventually from a file, but I'm not sure if I could search for equivalent Group Policy GUI text "Enforce password history", if anyone knows how to do that.
    $CurrentGPOReport = Get-GPOReport -Guid $GPO.Id -ReportType Xml -Domain $Domain -Server $NearestDC
    
    $RegEx = '(?s)' + [RegEx]::Escape($String) + '.+?Setting.*?>(.*?)<'
    
    If($CurrentGPOReport -match $RegEx)
    {
        Write-Host "Policy Found: ""$String""" -Foregroundcolor Green
    
        $Value = $Matches[1]
    }
    

    我不确定如何匹配 GPMC 名称,对此感到抱歉,但这应该可以让您更接近您的目标。

    编辑:要尝试将每个设置分离到它自己的文本块中,而不仅仅是在一个策略上工作,我不得不稍微改变我的 RegEx。这个输出有点混乱,但我认为可以简单地清理。这会将 GPO 拆分为单独的设置:

    $Policies = $CurrentGPOReport -split '(\<(q\d+:.+?>).+?\<(?:\/\2))' | Where { $_ -match ':Name' }
    

    这将为您提供如下所示的集合:

    <q1:Account>
              <q1:Name>PasswordHistorySize</q1:Name>
              <q1:SettingNumber>21</q1:SettingNumber>
              <q1:Type>Password</q1:Type>
            </q1:Account>
    

    从那里你只需要过滤你正在寻找的任何设置。

    【讨论】:

    • 谢谢!您的 $RegEx 字符串适用于示例中搜索的特定值,因为 XML 标记与“设置”匹配,但大多数值具有不同的 XML 标记。我要查找的所有值都应该出现在 $String 匹配之后和字符“”之前,回到第一个“>”字符。尽管在某些情况下存在多个字符串值,但理想情况下,在每个“”之前检索每个字符串,直到到达下一个“Name>”。我开始使用 RegEx 来尝试让它工作,但还没有找到一个工作匹配。有什么建议吗?
    • 嗯,你可能正在那里做些什么。直到下一个Name&gt; 的所有事情都可以完成。让我尝试一些事情,我会回复你的。可能要到星期一,我还有一个忙碌的周末。
    【解决方案2】:

    我已经在 XPath 中尝试过这个,因为您可以在 XML 节点中进行更多控制:

    [string]$SearchQuery = "user"
    [xml]$Xml = Get-GPOReport -Name "Default Domain Policy" -ReportType xml
    [array]$Nodes = Select-Xml -Xml $Xml -Namespace @{gpo="http://www.microsoft.com/GroupPolicy/Settings"} -XPath "//*"
    $Nodes | Where-Object -FilterScript {$_.Node.'#text' -match $SearchQuery} | ForEach-Object -Process {
        $_.Name #Name of the found node
        $_.Node.'#text' #text in between the tags
        $_.Node.ParentNode.ChildNodes.LocalName #other nodes on the same level
    }
    

    经过测试,我们发现在 Get-GPOReport cmdlet 的 XML 输出中,设置名称并不总是与 HTML 输出的名称匹配。例如:“作为服务登录”在 XML 输出中被发现为“SeServiceLogonRight”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      • 2021-12-22
      • 2013-01-27
      • 1970-01-01
      相关资源
      最近更新 更多