MS14-025:组策略首选项中的漏洞可能允许特权提升:2014 年 5 月 13 日

应用对象
Windows RT 8.1 Windows 8.1 Windows 8.1 Enterprise Windows 8.1 Pro Windows Server 2012 R2 Datacenter Windows Server 2012 R2 Essentials Windows Server 2012 R2 Foundation Windows Server 2012 R2 Standard Windows 8 Windows 8 Enterprise Windows 8 Pro Windows Server 2012 Datacenter Windows Server 2012 Datacenter Windows Server 2012 Essentials Windows Server 2012 Foundation Windows Server 2012 Foundation Windows Server 2012 Standard Windows Server 2012 Standard Windows 7 Service Pack 1 Windows 7 Enterprise Windows 7 Professional Windows 7 Ultimate Windows 7 Home Premium Windows 7 Home Basic Windows Server 2008 R2 Service Pack 1 Windows Server 2008 R2 Standard Windows Server 2008 R2 Enterprise Windows Server 2008 R2 Datacenter Windows Server 2008 Service Pack 2 Windows Server 2008 for Itanium-Based Systems Windows Server 2008 Datacenter Windows Server 2008 Enterprise Windows Server 2008 Standard Windows Server 2008 Web Edition Windows Vista Service Pack 2 Windows Vista Business Windows Vista Enterprise Windows Vista Home Basic Windows Vista Home Premium Windows Vista Starter Windows Vista Ultimate Windows Vista Enterprise 64-bit Edition Windows Vista Home Basic 64-bit Edition Windows Vista Home Premium 64-bit Edition Windows Vista Ultimate 64-bit Edition Windows Vista Business 64-bit Edition

简介

Microsoft 已发布安全公告 MS14-025。 若要了解有关此安全公告的详细信息:

如何获取此安全更新的相关帮助和支持

有关安装更新的帮助:
Microsoft 更新支持

IT 专业人员安全解决方案:
TechNet 安全疑难解答与支持

帮助保护基于 Windows 的计算机 Windows 免受病毒和恶意软件的侵害:
病毒解决方案和安全中心

基于国家/地区的本地支持:
国际支持

详细信息

有关此安全更新的已知问题和详细信息

以下文章包含有关此安全更新的更多信息,因为它与各个产品版本相关。 文章可能包含已知问题信息。 如果是这种情况,则每个文章链接下都列出了已知问题。

  • 2928120

    MS14-025:适用于安装了更新 2919355 的系统的 Windows 远程服务器管理工具安全更新说明:2014 年 5 月 13 日

  • 2961899

    MS14-025:适用于未安装更新2919355系统的 Windows 远程服务器管理工具安全更新说明:2014 年 5 月 13 日

组策略首选项

概述

某些组策略首选项可存储密码。 由于密码存储不安全,此功能正在删除。 本文介绍了用户界面更改和任何可用的解决方法。

以下组策略首选项将不再允许保存用户名和密码:

  • 行车地图
  • 本地用户和组
  • 计划任务
  • 服务
  • 数据源

这将影响你的环境中依赖于这些首选项中包含的密码的任何现有 组策略 对象 (GPO) 行为。 它还将阻止使用此功能创建新的组策略首选项。

对于驱动器映射、本地用户和组以及服务,你可以通过 Windows 中其他更安全的功能实现类似的目标。

对于计划任务和数据源,你将无法实现通过组策略首选项密码的非安全功能实现的相同目标。

方案

以下组策略首选项将受此更改的影响。 简要介绍了每个首选项,然后会更详细地介绍。 此外,还提供了使您能够执行相同任务的解决方法。

受影响的首选项 适用于用户
适用于计算机
本地用户管理 是 是
映射的驱动器 是 否
服务 否 是
计划任务 (上层) 是 是
计划任务 (下层) 是 是
即时任务 (上层) 是 是
即时任务 (下层) 是 是
数据源 是 是

更改摘要

  • 所有受影响首选项中的密码字段都将被禁用。 管理员无法使用这些密码字段创建新的首选项。
  • 用户名字段在某些首选项中处于禁用状态。
  • 无法更新包含密码的现有首选项。 只能根据特定首选项删除或禁用它们。
  • 首选项的“删除”和“禁用”操作的行为未更改。
  • 当管理员打开任何包含 CPassword 属性的首选项时,管理员将收到以下警告对话框,告知其最近被弃用。 尝试保存对需要 CPassword 属性的新首选项或现有首选项的更改将触发同一对话框。 只有“删除”和“禁用”操作不会触发警告对话框。

             安全警告,指出 CPassword 属性需要不可用的安全功能
            
            
            
          

方案 1:本地用户管理

本地用户管理首选项经常用于创建在计算机上具有已知密码的本地管理员。 由于组策略首选项存储密码的方式,此功能并不安全。 因此,此功能不再可用。 以下首选项会受到影响:

  • 计算机配置 -> 控制面板设置 - 本地用户和组 ->> 新建 -> 本地用户
  • 用户配置 -> 控制面板设置 -> 本地用户和组 -> 新建 -> 本地用户

重要更改

操作:创建或替换

  • 将禁用“用户名”、“密码”和“确认密码”字段。
  • 当管理员打开或尝试保存对包含密码的现有首选项所做的任何更改时,将显示警告对话框。

                
                 新“本地用户属性”对话框,其中突出显示了空白用户名和密码字段
                
操作:更新

  • 禁用 “密码” 和“ 确认密码 ”字段。
  • 当管理员打开或尝试保存对包含密码的现有首选项所做的任何更改时,将显示警告对话框。

                
                 “新建本地用户属性”对话框,其中“操作”字段设置为“更新”
                
操作:删除

  • 行为没有变化

解决方法

对于以前依赖组策略首选项设置本地管理员密码的用户,以下脚本作为 CPassword 的安全替代方案。 将内容复制并保存到新的 Windows PowerShell 文件,然后运行脚本,如下所示。示例部分。

Microsoft 的编程示例仅用于说明,不做任何明示或暗示的保证。 这包括但不限于特定用途的适销性或适用性的隐含保证。 本文假定你熟悉所演示的编程语言以及用于创建和调试过程的工具。 Microsoft 支持工程师可以帮助解释特定过程的功能。 但他们不会修改这些示例以提供附加功能或构造满足你的特定要求的过程。

函数 Invoke-PasswordRoll
{
<#
.剧情简介

此脚本可用于将远程计算机上的本地帐户密码设置为随机密码。 用户名/密码/服务器组合将保存在 CSV 文件中。
可以使用管理员选择的密码对存储在 CSV 文件中的帐户密码进行加密,以确保明文帐户密码不会写入磁盘。
可以使用此文件中的另一个函数解密加密的密码:ConvertTo-CleartextPassword

功能:Invoke-PasswordRoll
作者:Microsoft
版本: 1.0

.描述

此脚本可用于将远程计算机上的本地帐户密码设置为随机密码。 用户名/密码/服务器组合将保存在 CSV 文件中。
可以使用管理员选择的密码对存储在 CSV 文件中的帐户密码进行加密,以确保明文帐户密码不会写入磁盘。
可以使用此文件中的另一个函数解密加密的密码:ConvertTo-CleartextPassword

.参数 ComputerName

使用 PowerShell 远程处理运行脚本的计算机数组。

.参数 LocalAccounts

应更改其密码的本地帐户数组。

.参数 TsvFileName

要将用户名/密码/服务器组合输出到的文件。

.参数 EncryptionKey

用于加密 TSV 文件的密码。 使用 AES 加密。 只有存储在 TSV 文件中的密码将被加密,用户名和服务器名将是明文的。

.参数 PasswordLength

将为本地帐户随机生成的密码的长度。

.参数 NoEncryption

不要加密存储在 TSV 文件中的帐户密码。 这将导致将明文密码写入磁盘。

.示例

. .\Invoke-PasswordRoll.ps1 #Loads 此脚本文件中的函数
Invoke-PasswordRoll -ComputerName (Get-Content computerlist.txt) -LocalAccounts @ (“administrator”,“CustomLocalAdmin”) -TsvFileName “LocalAdminCredentials.tsv” -EncryptionKey “Password1”

连接到存储在文件“computerlist.txt”中的所有计算机。 如果系统上存在本地帐户“administrator”和/或“CustomLocalAdmin”,则其密码将更改
为默认) (20 的随机生成的密码。 用户名/密码/服务器组合存储在 LocalAdminCredentials.tsv 中,帐户密码使用密码“Password1”进行 AES 加密。

.示例

. .\Invoke-PasswordRoll.ps1 #Loads 此脚本文件中的函数
Invoke-PasswordRoll -ComputerName (Get-Content computerlist.txt) -LocalAccounts @ (“administrator”) -TsvFileName “LocalAdminCredentials.tsv” -NoEncryption -PasswordLength 40

连接到存储在文件“computerlist.txt”中的所有计算机。 如果系统上存在本地帐户“administrator”,则其密码将更改为随机生成的
长度为 40 的密码。 用户名/密码/服务器组合未加密存储在 LocalAdminCredentials.tsv 中。

.注意事项
要求:
- 必须安装 PowerShellv2 或更高版本
-必须在运行脚本的所有系统上启用 PowerShell 远程处理

脚本行为:
- 如果系统上存在本地帐户,但未在 LocalAccounts 参数中指定,则脚本将向屏幕写入警告,提醒你存在此本地帐户。 发生这种情况时,脚本将继续运行。
- 如果在 LocalAccounts 参数中指定了本地帐户,但是该帐户在计算机上不存在,则不会) 创建帐户 (不会发生任何操作。
- 此文件中包含的函数 ConvertTo-CleartextPassword 可用于解密以加密方式存储在 TSV 文件中的密码。
- 如果无法连接到 ComputerName 中指定的服务器,PowerShell 将输出错误消息。
- Microsoft 建议公司定期滚动所有本地和域帐户密码。

#>
    [CmdletBinding (DefaultParameterSetName=“Encryption”) ]
    参数 (
        [Parameter (Mandatory=$true) ]
        [String[]]
        $ComputerName,

        [Parameter (Mandatory=$true) ]
        [String[]]
        $LocalAccounts,

        [Parameter (Mandatory=$true) ]
        [String]
        $TsvFileName,

        [Parameter (ParameterSetName=“Encryption”, Mandatory=$true) ]
        [String]
        $EncryptionKey,

        [参数 () ]
        [ValidateRange (20,120) ]
        [int]
        $PasswordLength = 20,

        [Parameter (ParameterSetName=“NoEncryption”, Mandatory=$true) ]
        [切换]
        $NoEncryption
    )

    #Load 任何需要的 .NET 类
    Add-Type -AssemblyName “System.Web” -ErrorAction 停止

    #This 是在 ComputerName 中指定的每台计算机上执行的脚本块
    $RemoteRollScript = {
        参数 (
            [参数 (强制 = $true,位置 = 1) ]
            [String[]]
            $Passwords,

            [参数 (强制=$true,位置=2) ]
            [String[]]
            $LocalAccounts,

            #This 在这里,这样我就可以记录脚本连接到的服务器名称,有时 DNS 记录会变得一团糟,有这个会很好。
            [参数 (强制 = $true,位置 = 3) ]
            [String]
            $TargettedServerName
        )

        $LocalUsers = Get-WmiObject Win32_UserAccount -Filter “LocalAccount=true” |Foreach {$_.Name}

        #Check 计算机是否具有此脚本不会滚动其密码的任何本地用户帐户
        $LocalUsers) 中的 foreach ($User
        {
            if ($LocalAccounts -inotcontains $User)
            {
                Write-Warning “服务器: '$ ($TargettedServerName) ' 具有本地帐户 '$ ($User) ',此脚本未更改其密码”
            }
        }

        #For 此服务器上存在的每个指定的本地帐户,更改密码
        $PasswordIndex = 0
        $LocalAccounts) 中的 foreach ($LocalAdmin
        {
            $Password = $Passwords[$PasswordIndex]

            if ($LocalUsers -icontains $LocalAdmin)
            {
                试用
                {
                    $objUser = [ADSI]“WinNT://localhost/$ ($LocalAdmin) , user”
                    $objUser.psbase.Invoke (“SetPassword”, $Password)

                    $Properties = @{
                        TargettedServerName = $TargettedServerName
                        用户名 = $LocalAdmin
                        密码 = $Password
                        RealServerName = $env:computername
                    }

                    $ReturnData = New-Object PSObject -Property $Properties
                    Write-Output $ReturnData
                }
                catch
                {
                    Write-Error “服务器上 user:$ ($LocalAdmin) 的密码更改时出错 ($TargettedServerName) ”
                }
            }

            $PasswordIndex++
        }
    }

    在运行此脚本的客户端上(而不是在远程计算机上)#Generate 密码。 System.Web.Security 在 .NET 客户端配置文件中不可用。 进行此调用
    # 客户端上运行脚本可确保只有 1 台计算机需要安装完整的 .NET 运行时 (而不是每个系统都) 密码滚动。
    函数 Create-RandomPassword
    {
        参数 (
            [Parameter (Mandatory=$true) ]
            [ValidateRange (20,120) ]
            [int]
            $PasswordLength
        )

        $Password = [System.Web.Security.Membership]::GeneratePassword ($PasswordLength, $PasswordLength / 4)

        #This 永远不会失败,但无论如何我都在这里放了一个理智检查
        if ($Password.Length -ne $PasswordLength)
        {
            throw new Exception (“GeneratePassword 返回的密码长度与所需长度不同。 所需长度: ($PasswordLength) 美元。 生成长度: $ ($Password.长度) “)
        }

        return $Password
    }

    #Main 功能 - 生成密码并远程访问计算机以更改指定本地帐户的密码
    if ($PsCmdlet.ParameterSetName -ieq “Encryption”)
    {
        试用
        {
            $Sha 256 = 新对象 System.Security.Cryptography.SHA256CryptoServiceProvider
            $SecureStringKey = $Sha 256.ComputeHash ([System.Text.UnicodeEncoding]::Unicode.GetBytes ($EncryptionKey) )
        }
        catch
        {
            Write-Error“创建 TSV 加密密钥时出错”-ErrorAction Stop
        }
    }

    $ComputerName) 中的 foreach ($Computer
    {
        #Need 为每个可更改的帐户生成 1 个密码
        $Passwords = @ ()
        对于 ($i = 0;$i -lt $LocalAccounts.Length;$i++)
        {
            $Passwords += Create-RandomPassword -PasswordLength $PasswordLength
        }

        Write-Output “正在连接到服务器 '$ ($Computer) ' 以滚动指定的本地管理员密码”
        $Result = Invoke-Command -ScriptBlock $RemoteRollScript -ArgumentList @ ($Passwords, $LocalAccounts, $Computer) -ComputerName $Computer
        #If 正在使用加密,请在写入磁盘之前使用用户提供的密钥对密码进行加密
        if ($Result -ne $null)
        {
            if ($PsCmdlet.ParameterSetName -ieq “NoEncryption”)
            {
                $Result |Select-Object 用户名,密码,TargettedServerName,RealServerName |Export-Csv -Append -Path $TsvFileName -NoTypeInformation
            }
            else
            {
                #Filters 返回的$null条目
                $Result = $Result |Select-Object 用户名,密码,TargettedServerName,RealServerName

                $Result) 中的 foreach ($Record
                {
                    $PasswordSecureString = ConvertTo-SecureString -AsPlainText -Force -String ($Record.Password)
                    $Record |Add-Member -MemberType NoteProperty -Name EncryptedPassword -Value (ConvertFrom-SecureString -Key $SecureStringKey -SecureString $PasswordSecureString)
                    $Record.PSObject.Properties.Remove (“Password”)
                    $Record |Select-Object Username,EncryptedPassword,TargettedServerName,RealServerName |Export-Csv -Append -Path $TsvFileName -NoTypeInformation
                }
            }
        }
    }
}

函数 ConvertTo-CleartextPassword
{
<#
.剧情简介
此函数可用于解密由函数 Invoke-PasswordRoll 加密存储的密码。

功能:ConvertTo-CleartextPassword
作者:Microsoft
版本: 1.0

.描述
此函数可用于解密由函数 Invoke-PasswordRoll 加密存储的密码。

.参数 EncryptedPassword

存储在 TSV 文件中的加密密码。

.参数 EncryptionKey

用于加密的密码。

.示例

. .\Invoke-PasswordRoll.ps1 #Loads 此脚本文件中的函数
ConvertTo-CleartextPassword -EncryptionKey “Password1” -EncryptedPassword 76492d1116743f0423413b16050a5345MgB8AGcAZgBaAHUAaQBwADAAQgB2AGgAcABNADMASwBaAFoAQQBzADEAeABjAEEAPQA9AHwAZgBiAGYAMAA1ADYANgA2ADEANwBkADQAZgAwADMANABjAGUAZQAxAGIAMABs iADkANgBiADkAMAA4ADcANwBhADMAYQA3AGYAOABkADcAMQA5ADQAMwBmAGYANQBhADEAYQBjADcANABkADIANgBhADUANwBlADgAMAAyADQANgA1ADIAOQA0AGMAZQA0ADEAMwAzADcANQAyADUANAAzADYAMAA1AGEANgAzADEAMQA5ADAAYwBmADQAZAA2AGQA”

解密存储在 TSV 文件中的加密密码。

#>
    参数 (
        [Parameter (Mandatory=$true) ]
        [String]
        $EncryptedPassword,

        [Parameter (Mandatory=$true) ]
        [String]
        $EncryptionKey
    )

    $Sha 256 = 新对象 System.Security.Cryptography.SHA256CryptoServiceProvider
    $SecureStringKey = $Sha 256.ComputeHash ([System.Text.UnicodeEncoding]::Unicode.GetBytes ($EncryptionKey) )

    [SecureString]$SecureStringPassword = ConvertTo-SecureString -String $EncryptedPassword -Key $SecureStringKey
    Write-Output ([System.Runtime.InteropServices.Marshal]::P trToStringAuto ([System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode ($SecureStringPassword) ) )
}
   管理员可以通过创建 Active Directory 组并通过“组策略首选项 - 本地组”将其添加到本地组策略帐户 -> 本地组来向计算机添加本地管理员帐户。 此操作不会缓存凭据。 对话框类似于以下内容。 此解决方法确实需要在用户使用这些凭据登录时连接到 Active Directory 域服务。

管理员内置组属性对话框,其中包含“添加当前用户”选项

方案 2:映射的驱动器

管理员使用驱动器映射将网络位置分配给用户。 密码保护功能用于确保对驱动器的授权访问。 以下首选项会受到影响:

  • 用户配置 -> Windows 设置 -> 驱动器地图 -> 新建 -> 映射的驱动器

重要更改

操作:创建、更新或替换

  • 将禁用“用户名”、“密码”和“确认密码”字段。

                 目标系统要求 分区拆分和合并的决策流程图
                
操作:删除

  • 行为没有变化

解决方法

可以使用 Windows 资源管理器管理共享权限并将权限分配给用户,而不是使用密码方法进行身份验证。 可以使用 Active Directory 对象控制对文件夹的权限。

方案 3:服务

您可以使用服务首选项来更改服务属性,使其在原始安全上下文以外的上下文中运行。 以下首选项会受到影响:

  • 计算机配置 -> 控制面板设置 -> 服务 - 新建 ->> 服务

重要更改

启动:无更改、自动或手动

  • 密码和确认密码字段处于禁用状态。
  • 管理员只能使用内置帐户。

                 IPsec 站点到站点拓扑,网关 R1 和 R2 通过隧道连接
                
启动:禁用

  • 行为没有变化

新建对话框

  • 尝试将非内置用户用于此帐户“的管理员收到以下警告:

                 指出 CPassword 属性已弃用的警告对话框
                
                
              

解决方法

                
                
服务仍可以作为本地系统帐户运行。 服务权限可以更改,如 Microsoft 知识库中的以下文章所述:

256345 如何配置组策略设置以设置系统服务的安全性

注意 如果要配置的服务不存在,则必须在运行该服务的计算机上配置设置。 

方案 4:计划任务和即时任务 (上层)

它们用于在特定的安全环境中运行计划任务。 无法存储计划任务的凭据,以便在该用户未登录时以任意用户身份运行。 以下首选项会受到影响。 (请注意,在某些平台上,“至少 Windows 7”被替换为“Windows Vista 及更高版本”。)

  • 计算机配置 -> 控制面板设置 -> 计划任务 -> 新建 -> 计划任务 (至少 Windows 7)
  • 计算机配置 -> 控制面板设置 -> 计划任务 -> 新建 -> 即时任务 (至少 Windows 7)
  • 用户配置 -> 控制面板 设置 -> 计划任务 -> 新建 -> 计划任务 (至少 Windows 7)
  • 用户配置 -> 控制面板设置 -> 计划任务 -> 新建 -> 即时任务 (至少 Windows 7)

重要更改

操作:创建、更新或替换

  • 选择“ 无论用户登录与否运行” 选项时,对话框不再提示管理员输入凭据。
  • “不存储密码”检查框处于禁用状态。 默认情况下,该框也处于选中状态。

                 包含可选用户凭据字段的新驱动器属性对话框
                
操作:删除

行为没有变化

解决方法

对于“ (至少 Windows 7) 的计划任务”和“ (至少 Windows 7) 的即时任务”任务,管理员可以在指定用户登录时使用特定的用户帐户。 或者,他们只能以该用户身份访问本地资源。 这些任务仍然可以在本地服务的上下文中运行。

            
方案 5:计划任务和即时任务 (下层) 这是用于在特定安全环境中运行计划任务的首选项的下层版本。 无法存储计划任务的凭据,以便在该用户未登录时以任意用户身份运行。 以下首选项会受到影响:

  • 计算机配置 -> 控制面板设置 -> 计划任务 -> 新建 -> 计划任务
  • 计算机配置 -> 控制面板设置 -> 计划任务 - 新建 -> 立即任务 (> Windows XP)
  • 用户配置 -> 控制面板设置 -> 计划任务 -> 新建 -> 计划任务
  • 用户配置 -> 控制面板 设置 -> 计划任务 - 新建 ->> 即时任务 (Windows XP)

重要更改

操作:创建、更新或替换

  • 禁用“运行身份”检查框。 因此, 用户名、 密码和 确认密码 字段都将被禁用。

                 突出显示“运行身份”选项的“新任务属性”对话框
                
操作:删除

 行为没有变化

解决方法

对于“计划任务”和“Windows XP) (即时任务”项,使用本地服务当前可用的权限运行计划任务。 

方案 6:数据源

“数据源”首选项用于将数据源与计算机或用户关联。 此功能不再存储凭据来访问受密码保护的数据源。 以下首选项会受到影响:

  • 计算机配置 -> 控制面板设置 -> 数据源
  • 用户配置 -> 控制面板设置 -> 数据源

重要更改

操作:创建、更新或替换

  • 禁用“用户名”、“密码”和“确认密码”字段:

                 突出显示了用户名和密码字段的“新数据源属性”对话框
                
操作:删除

  • 行为没有变化

解决方法

没有任何解决方法。 此首选项不再存储凭据以允许访问受密码保护的数据源。 

CPassword 的弃用

删除 CPassword

此 Microsoft 知识库文章中包含的 Windows PowerShell 脚本可检测域是否包含任何可能使用 CPassword 的组策略首选项。 如果在给定首选项中检测到 CPassword XML,则它将显示在此列表中。 

检测 CPassword 首选项

此脚本必须从要清理的域控制器上的本地目录运行。 将内容复制并保存到新的 Windows PowerShell 文件,确定系统驱动器,然后按照以下用法运行脚本。

  <#
.剧情简介
域中的组策略对象可以具有存储不同任务密码的首选项,例如:
1. 数据源
2. 行车地图
3. 本地用户
4. 计划任务 (XP 和高级)
5. 服务
这些密码作为 GP 首选项的一部分存储在 SYSVOL 中,并且由于 32 字节 AES) 的弱加密 (因此不安全。
因此,我们建议你不要在域环境中部署此类首选项并删除任何此类现有
首选项。 此脚本用于帮助管理员在其域的包含密码的 SYSVOL 中查找 GP 首选项。

.描述
此脚本应在 DC 或随 RSAT 一起安装的客户端计算机上运行,以打印包含
包含 GPO、首选项名称、定义此首选项的 GPEdit 路径等信息的密码。
获得受影响首选项的列表后,可以使用组策略管理控制台中的编辑器删除这些首选项。

.语法
Get-SettingsWithCPassword.ps1 [-path <string>]
.示例
Get-SettingsWithCPassword.ps1 -Path %WinDir%\SYSVOL\domain
Get-SettingsWithCPassword.ps1 -Path <GPO 备份文件夹路径>

.注意事项
如果未找到组策略 PS 模块,则输出将包含 GPO GUID,而不是 GPO 名称。 可以运行
或在安装 RSAT 和 Certificate 之后在客户端上重新运行此脚本。
启用了组策略模块。
或者,也可以使用 GPO GUID 通过 Get-GPO cmdlet 获取 GPO 名称。

.链接
http://go.microsoft.com/fwlink/?LinkID=390507

#>
#----------------------------------------------------------------------------------------------------------------
# 输入参数 #--------------------------------------------------------------------------------------------------------------
param (
    [string]$Path = $ (throw “-Path is required.”) # GPP 所在的目录路径。
 )
#---------------------------------------------------------------------------------------------------------------
$isGPModuleAvailable = $false
$impactedPrefs = { “Groups.xml”, “ScheduledTasks.xml”,“Services.xml”, “DataSources.xml”, “Drives.xml” }
#----------------------------------------------------------------------------------------------------------------
# import Group olicy 模块(如果可用) #----------------------------------------------------------------------------------------------------------------
if (-not (Get-Module -name “GroupPolicy”) )
{
   if (Get-Module -ListAvailable |
         Where-Object { $_.Name -ieq “GroupPolicy” })
    {
        $isGPModuleAvailable = $true
        Import-Module“GroupPolicy”
    }
    else
    {
        Write-Warning“无法导入 PowerShell 的组策略模块。 因此,将报告 GPO guid。
                       在 DC 上运行此脚本以获取 GPO 名称,或使用 DC) 上的 Get-GPO cmdlet (从 GPO guid 获取 GPO 名称。”
    }
}
else
{
    $isGPModuleAvailable = $true
}
Function Enum-SettingsWithCpassword ( [string]$sysvolLocation )
{
    # GPMC 树路径
    $commonPath = “ -> 首选项 -> 控制面板设置 -> ”
    $driveMapPath = “ -> 首选项 -> Windows 设置 -> ”

    # 以递归方式获取 SYVOL 位置中的所有 xml 文件
    $impactedXmls = Get-ChildItem $sysvolLocation -Recurse -Filter “*.xml” |Where-Object { $impactedPrefs -cmatch $_.名称 }

    # 每个 xml 文件包含多个首选项。 循环访问每个首选项以检查其是否
    # 包含 cpassword 属性并显示它。
    $impactedXmls ) 中的 foreach ( $file
    {
        $fileFullPath = $file。FullName

        # 设置 GPP 类别。 如果文件位于 SYSVOL 中的计算机文件夹下
        # 该设置在“计算机配置”下定义,否则,
        # 设置是对用户的配置
        if ( $fileFullPath.Contains (“Machine”) )
        {
            $category = “计算机配置”
        }
        elseif ( $fileFullPath.Contains (“User”) )
        {
            $category = “用户配置”
        }
        else
        {
            $category = “未知”
        }
        # 以 XML 格式获取文件内容
        试用
        {
            [xml]$xmlFile = get-content $fileFullPath -ErrorAction 继续
        }
        catch [Exception]{
            Write-Host $_。Exception.Message
        }
        if ($xmlFile -eq $null)
        {
            继续
        }
        切换 ( $file。BaseName )
        {
            组
            {
                $gppWithCpassword = $xmlFile.SelectNodes (“Groups/User”) |where-Object { [String]::IsNullOrEmpty ($_.Properties.cpassword) -eq $false }
                $preferenceType = “本地用户”
            }
            ScheduledTasks
            {
                $gppWithCpassword = $xmlFile.SelectNodes (“ScheduledTasks/*”) |where-Object { [String]::IsNullOrEmpty ($_.Properties.cpassword) -eq $false }
                $preferenceType = “计划任务”
            }
            数据源
            {
                $gppWithCpassword = $xmlFile.SelectNodes (“DataSources/DataSource”) |where-Object { [String]::IsNullOrEmpty ($_.Properties.cpassword) -eq $false }
                $preferenceType = “数据源”
            }
            驱动器
            {
                $gppWithCpassword = $xmlFile.SelectNodes (“Drives/Drive”) |where-Object { [String]::IsNullOrEmpty ($_.Properties.cpassword) -eq $false }
                $preferenceType = “行车地图”
            }
            服务
            {
                $gppWithCpassword = $xmlFile.SelectNodes (“NTServices/NTService”) |where-Object { [String]::IsNullOrEmpty ($_.Properties.cpassword) -eq $false }
                $preferenceType = “Services”
            }
            默认
            { # 清除下一项的 gppWithCpassword 和 preferenceType。
                试用
                {
                    Clear-Variable -Name gppWithCpassword -ErrorAction SilentlyContinue
                    Clear-Variable -Name preferenceType -ErrorAction SilentlyContinue
                }
                catch [Exception]{}
            }
        }
        if ($gppWithCpassword -ne $null)
        {
            # 根据从 filePath 提取的 GUID 生成 GPO 名称
            $guidRegex = [正则表达式]“\{ (.*) \}”
            $match = $guidRegex.match ($fileFullPath)
            如果 ($match。成功)
            {
               $gpoGuid = $match.groups[1].value
               $gpoName = $gpoGuid
            }
            else
            {
               $gpoName = “未知”
            }
            if ($isGPModuleAvailable -eq $true)
            {
                试用
                {
                    $gpoInfo = Get-GPO -Guid $gpoGuid -ErrorAction 继续
                    $gpoName = $gpoInfo.DisplayName
                }
                catch [Exception] {
                    Write-Host $_。Exception.Message
                }
            }
            # 显示包含 CPASSWORD 的预项
            $gppWithCpassword ) 中的 foreach ( $gpp
            {
                if ( $preferenceType -eq “Drive Maps” )
                {
                    $prefLocation = $category + $driveMapPath + $preferenceType
                }
                else
                {
                    $prefLocation = $category + $commonPath + $preferenceType
                }
                $obj = New-Object -typeName PSObject
                $obj |Add-Member –membertype NoteProperty –name GPOName –value ($gpoName) –passthru |
                       Add-Member -MemberType NoteProperty -name Preference -value ($gpp.Name) -passthru |
                       Add-Member -MemberType NoteProperty -name Path -value ($prefLocation)
                Write-Output $obj
            }
        } # 如果$gppWithCpassword则结束
    } # 结束 foreach $file
} # end functions Enum-PoliciesWithCpassword
#-----------------------------------------------------------------------------------
# 检查路径是否有效。 枚举包含 cpassword 的所有设置。 #-----------------------------------------------------------------------------------
if (Test-Path $Path )
{
    Enum-SettingsWithCpassword $Path
}
else
{
    Write-Warning “无此类目录:$Path”
}

示例用法 (假定系统驱动器为 C)

.\Get-SettingsWithCPassword.ps1 –path “C:\Windows\SYSVOL\domain” |Format-List
注意,还可以将 任何 备份 GPO 作为路径而不是域的目标。

检测脚本将生成类似于以下内容的列表:

命令行输出列表组策略首选项位置

对于较长的列表,请考虑将输出保存到文件:

.\Get-SettingsWithCPassword.ps1 –path “C:\Windows\SYSVOL\domain” |ConvertTo-Html > gpps.html

删除 CPassword 首选项

若要删除包含 CPassword 数据的首选项,我们建议你在域控制器上或从安装了远程服务器管理工具的客户端使用组策略管理控制台 (GPMC) 。 可以在这些主机上通过五个步骤删除任何首选项。 请按以下步骤完成此操作:

  1. 在 GPMC 中,打开包含 CPassword 数据的首选项。
  2. 根据首选项将操作更改为 “删除 ”或 “禁用”。
  3. 单击“确定”保存所做的更改。
  4. 等待一个或两个组策略刷新周期,以允许更改传播到客户端。
  5. 在所有客户端上应用更改后,删除首选项。
  6. 根据需要重复步骤 1 到 5 以清理整个环境。 当检测脚本返回零结果时,您就完成了操作。
文件哈希信息
文件名 SHA1 哈希 SHA256 哈希
Windows6.0-KB2928120-ia64.msu B2A74305CB56191774BFCF9FCDEAA983B26DC9A6 DCE8C0F9CEB97DBF1F7B9BAF76458B3770EF01C0EDC581621BC8C3B2C7FD14E7
Windows6.0-KB2928120-x64.msu 386457497682A2FB80BC93346D85A9C1BC38FBF7 1AF67EB12614F37F4AC327E7B5767AFA085FE676F6E81F0CED95D20393A1D38D
Windows6.0-KB2928120-x86.msu 42FF283781CEC9CE34EBF459CA1EFE011D5132C3 016D7E9DBBC5E487E397BE0147B590CFBBB5E83795B997894870EC10171E16D4
Windows6.1-KB2928120-ia64.msu 5C2196832EC94B99AAF9B074D3938525B7219690 9958FA58134F55487521243AD9740BEE0AC210AC290D45C8322E424B3E5EBF16
Windows6.1-KB2928120-x64.msu EA5332F4E289DC799611EAB8E3EE2E86B7880A4B 417A2BA34F8FD367556812197E2395ED40D8B394F9224CDCBE8AB3939795EC2A
Windows6.1-KB2928120-x86.msu 7B7B6EE24CD8BE1AB3479F9E1CF9C98982C8BAB1 603206D44815EF2DC262016ED13D6569BE13D06E2C6029FB22621027788B8095
Windows8-RT-KB2928120-x64.msu E18FC05B4CCA0E195E62FF0AE534BA39511A8593 FCAED97BF1D61F60802D397350380FADED71AED64435D3E9EAA4C0468D80141E
Windows8-RT-KB2928120-x86.msu A5DFB34F3B9EAD9FA78C67DFC7ACACFA2FBEAC0B 7F00A72D8A15EB2CA70F7146A8014E39A71CFF5E39596F379ACD883239DABD41
Windows8.1-KB2928120-x64.msu A07FF14EED24F3241D508C50E869540915134BB4 6641B1A9C95A7E4F0D5A247B9F488887AC94550B7F1D7B1198D5BCBA92F7A753
Windows8.1-KB2928120-x86.msu DE84667EC79CBA2006892452660EB99580D27306 468EE4FA3A22DDE61D85FD3A9D0583F504105DF2F8256539051BC0B1EB713E9C
Windows8.1-KB2961899-x64.msu 10BAE807DB158978BCD5D8A7862BC6B3EF20038B EC26618E23D9278FC1F02CA1F13BB289E1C6C4E0C8DA5D22E1D9CDA0DA8AFF51
Windows8.1-KB2961899-x86.msu 230C64447CC6E4AB3AD7B4D4655B8D8CEFBFBE98 E3FAD567AB6CA616E42873D3623A777185BE061232B952938A8846A974FFA7AF