当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 使用 PowerShell 测试 GPO 读取权限 (MS16-072 – KB3159398)

作者:精品下载站 日期:2024-12-14 07:15:08 浏览:14 分类:玩电脑

使用 PowerShell 测试 GPO 读取权限 (MS16-072 – KB3159398)


上周二补丁,微软发布了安全公告 MS16-072。此更新更改了将组策略下载到计算机的方式,这可能会导致 GPO 无法应用。

这种情况的一个常见症状是用户不再通过 GPO 映射其驱动器。

引用知识库文章 KB3159398:

如果组策略对象缺少经过身份验证的用户组的读取权限,或者如果您正在使用安全筛选并且缺少域计算机组的读取权限,则可能会出现此问题。

组策略不起作用可能是一个大问题,但不用担心,这当然是一个解决方案。再次引用 KB 文章:

要解决此问题,请使用组策略管理控制台 (GPMC.MSC) 并执行以下步骤之一:

- 添加对组策略对象 (GPO) 具有读取权限的经过身份验证的用户组。

- 如果您使用安全过滤,请添加具有读取权限的域计算机组。

-“但是如果我有数百个 GPO 怎么办?这可能要花我一整天的时间! ”

-“如果您使用 PowerShell,则不会! ”

使用 PowerShell 获取 GPO 的权限

首先,我们需要获取域中所有 GPO: 的列表。为此,我们需要 GroupPolicy 模块,该模块随用于组策略的 RSAT 工具一起提供。我通过运行以下命令来确保我拥有该模块:

Get-Module -Name GroupPolicy -ListAvailable

现在我可以使用命令 Get-GPO 和参数 -All 列出域中的所有 GPO。

为了获取 GPO 的权限,我使用命令 Get-GPPermission 以及参数 Id(GPO 的 ID)、TargetType(获取用户、计算机或组的权限)和 TargetName(要获取权限的主体的名称)。在这种情况下,我想确保经过身份验证的用户组对我的所有 GPO 具有读取访问权限,以便这将成为我的目标,并且我想从所有 GPO 获取权限,因此我必须循环遍历所有运行 Get-GPPermission 的 GPO每个 GPO 一次。

Import-Module -Name GroupPolicy
# Get all GPOs
$GPOList = Get-GPO -All
$GroupName = 'Authenticated Users'
# Loop
foreach($GPO in $GPOList)
{
    Get-GPPermission -Guid $GPO.Id -TargetType Group -TargetName $GroupName
}

这将为我提供所有 GPO 上经过身份验证的用户的权限,在某些情况下,我可能会收到一条错误消息,指出 GPO 没有我要求的安全主体,这意味着经过身份验证的用户无权访问 GPO。啊哈!这就是我正在寻找的不是吗?

如果我将 Get-GPPermission 命令包装在 Try 块中并添加 -ErrorAction Stop 以使所有错误终止,并且通过可捕获,我有一个良好的开始。

获得权限后,我想确保经过身份验证的用户实际上具有“读取”或“应用”权限(“应用”也意味着根据 MSDN 上的文档进行读取)。

如果命令 Get-GPPermission 引发错误或权限不包含“读取”或“应用”,我们将希望确保 GPO 具有正确的权限集,以便返回 GPO 对象。

这导致代码如下所示:

$GPOList = Get-GPO -All
$VerbosePreference = 'Continue'
$GroupName = 'Authenticated Users'
$InvalidGPOList = foreach($GPO in $GPOList)
{
    Try
    {
        $GPPermission = Get-GPPermission -Guid $GPO.Id -TargetType Group -TargetName $GroupName -ErrorAction Stop
        if(
            $GPPermission.Permission.HasFlag([Microsoft.GroupPolicy.GPPermissionType]::GpoRead)
        )
        {
            $Message = 'GPO: [{0}] is OK!' -f $GPO.DisplayName
        }
        else
        {
            $Message = 'No read access found group {0} in GPO: [{1}]' -f $GroupName, $GPO.DisplayName
            $GPO
        }
    }
    Catch
    {
        if($_.FullyQualifiedErrorId -like 'NoSecurityGroupFoundInGpoWithId*')
        {
            $GPO
            $Message = 'No access found group {0} in GPO: [{1}]' -f $GroupName, $GPO.DisplayName
        }
        else
        {
            throw
        }
    }
    Finally
    {
        Write-Verbose -Message $Message
    }
}
Write-Output -InputObject $InvalidGPOList

现在我意识到这远非完美,它会给我一个关于经过身份验证的用户具有自定义权限的所有 GPO 的误报,但它会给我一个存在潜在问题的 GPO 列表。

您可以通过使用 ActiveDirectory 模块和 Get-Acl 来获取 GPO 的实际 ACL、检查多个组(您可能希望授予该组“所有计算机”访问权限)甚至使用 Set- 来做得更好。 GPPermission 自动修改任何有问题的 GPO 的权限。如果您做了其中任何一项,请写一篇关于您是如何做的博客文章,然后立即告诉我!

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯