Windows/Group Policy

Windows/Group Policy

编程方式访问组策略

使用 PolicyFileEditor 这个 PowerShell 模块

本方法 2022-06 在 Windows 11 Enterprise 环境测试有效。

首先安装 PolicyFileEditor 这个 PowerShell 模块(文档),在 PowerShell terminal 里执行:(会多次提示按 Y 确认)

Install-Module -Name PolicyFileEditor -RequiredVersion 3.0.0

模块调用方法:

# 查看 gpedit.msc - Computer Configuration 下所有配置过的组策略项。
Get-PolicyFileEntry -Path "$env:windir\system32\GroupPolicy\Machine\Registry.pol" -All

# 查看 gpedit.msc - User Configuration 下所有配置过的组策略项。
Get-PolicyFileEntry -Path "$env:windir\system32\GroupPolicy\User\Registry.pol" -All

# 将 gpedit.msc 里的 User Configuration > Administrative Templates > Control Panel > Personalization 里的 "Password protect the screen saver" 设为 "Enabled"。
Set-PolicyFileEntry -Path "$env:windir\system32\GroupPolicy\User\Registry.pol" -Key 'Software\Policies\Microsoft\Windows\Control Panel\Desktop' -ValueName 'ScreenSaverIsSecure' -Data '1' -Type 'String'

# 删除上面的组策略配置项。(等于在 gpedit.msc 里将该配置项设为 "Not Configured")
Remove-PolicyFileEntry -Path "$env:windir\system32\GroupPolicy\User\Registry.pol" -Key 'Software\Policies\Microsoft\Windows\Control Panel\Desktop' -ValueName 'ScreenSaverIsSecure'
  • -Path : 组策略文件路径。
    • HKLM (对应 gpedit.msc 里的 Computer Configuration): "$env:windir\system32\GroupPolicy\Machine\Registry.pol"
    • HKCU (对应 gpedit.msc 里的 User Configuration): "$env:windir\system32\GroupPolicy\User\Registry.pol"
  • -Key : 组策略里的树(相对于注册表左侧的文件夹)路径。注意这个路径与 gpedit.msc 里 Sidebar 的树状结构路径并不相同。例如 gpedit.msc 的侧边栏的 User Configuration > Administrative Templates > Control Panel > Personalization 对应的 -Key 为 "Software\Policies\Microsoft\Windows\Control Panel\Desktop"。
  • -ValueName : 组策略(内容区域)配置项名称。注意同样与 gpedit.msc 里不同。例如上面的例子里 gpedit.msc User Configuration > Administrative Templates > Control Panel > Personalization 里的 "Password protect the screen saver" 配置项的 -ValueName 为 "ScreenSaverIsSecure"。
  • -Data : 设置指定的配置项值。值为字符串(用双引号括起来)或数字。
  • -Type : 配置项值的类型。"String" | "DWord"。
  • 大部分开关类型的组策略配置项的类型(-Type)为 "String"。其值(-Data) "1" 为 "Enabled", "0" 为 "Disabled"。
  • Windows 所有组策略配置项的 Key, ValueName 等信息可以从微软官方的 Group Policy Settings Reference 获取(下载的是一个 Excel 数据库文件 Windows10andWindowsServer2016PolicySettings.xlsx)。或者首先在 gpedit.msc 里配置下,然后在 PowerShell 里通过 Get-PolicyFileEntry 在显示的所有已配置的组策略项里找。
  • 如果当前已经打开了 gpedit.msc 窗口,执行上面的 PowerShell 命令修改组策略后当前 gpedit.msc 界面里显示的配置项值不会变化,必须关闭当前窗口然后重新 gpedit.msc 才能看到更新。

补充说明:

上面的这种 PowerShell 方式修改组策略后不会自动生效。例如 gpedit.msc Computer Configuration \ Administrative Templates \ System \ Power Management \ Video and Display Settings : Turn off the display (plugged in) 这个配置项可以配置系统 idle (无鼠标和键盘输入) 多长时间(秒数)后关闭显示器,在 gpedit.msc 界面里配置或修改这个值后立即生效。但通过上面的 PowerShell 设置这个值后无法立即生效:(下面示例命令将这个值设为 3s)

Set-PolicyFileEntry -Path "$env:windir\system32\GroupPolicy\Machine\Registry.pol" -Key 'Software\Policies\Microsoft\Power\PowerSettings\3C0BC021-C8A8-4E07-A973-6B14CBCB2B7E' -ValueName 'ACSettingIndex' -Data 3 -Type 'DWord'

必须执行一次 gpupdate 使所有更改后的组策略值生效。而 gpedit.msc 界面上做的所有更改都会自动调用 gpudate。

gpupdate /Force
gpupdate /Target:Computer
gpupdate /Target:User

注:

  • /Force 参数强制使所有设置的组策略配置项生效。如果不加这个参数则只处理有修改的配置项。但我测试发现用上面的 PowerShell 修改组策略后有时必须加 /Force 才能使修改生效。傻逼微软!

本质上,PowerShell 修改组策略原理就是直接改注册表。所以也可以直接改注册表(但是找到实际最终的注册表路径很麻烦)。例如上面的例子对应的注册表树路径:

Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\{50DC16A1-75E6-4046-8D1E-3C2419041F97}Machine\SOFTWARE\Policies\Microsoft\Power\PowerSettings\3C0BC021-C8A8-4E07-A973-6B14CBCB2B7E

Debug

在 PowerShell 窗口里执行:

Import-Module -name "PolicyFileEditor"

$MachineDir = "$env:windir\system32\GroupPolicy\Machine\Registry.pol"
$UserDir = "$env:windir\system32\GroupPolicy\User\Registry.pol"

$RegPath = 'Software\Policies\Microsoft\Windows\Control Panel\Desktop'
$RegName = 'ScreenSaverIsSecure'
$RegData = '1'
$RegType = 'String'


Set-PolicyFileEntry -Path $UserDir -Key $RegPath -ValueName $RegName -Data $RegData -Type $RegType

常用组策略配置项

# gpedit.msc Computer Configuration \ Administrative Templates \ Systen \ Power Management \ Video and Display Settings : Turn off the display (plugged in) (seconds)
# 这个配置项以及同路径下的 'DCSettingIndex' (Turn off the display (on battery)) 配置项会强制覆盖控制面板 - Power Plan 里的设置。并且控制面板里最低只能设置为1分钟。而组策略里可以设为 1s。
Set-PolicyFileEntry -Path "$env:windir\system32\GroupPolicy\Machine\Registry.pol" -Key 'Software\Policies\Microsoft\Power\PowerSettings\3C0BC021-C8A8-4E07-A973-6B14CBCB2B7E' -ValueName 'ACSettingIndex' -Data 3 -Type 'DWord'

Remove-PolicyFileEntry -Path "$env:windir\system32\GroupPolicy\Machine\Registry.pol" -Key 'Software\Policies\Microsoft\Power\PowerSettings\3C0BC021-C8A8-4E07-A973-6B14CBCB2B7E' -ValueName 'ACSettingIndex'

修改后使生效:

gpupdate /Force

(测试无效) CLI 访问组策略

Update: 测试这种的这种方式需要 Windows 加入 AD域 (Active Directory)。默认的本地账户登录的 Windows 无法使用,PowerShell 执行命令时会报错 "Get-GPPrefRegistryValue : Current security context is not associated with an Active Directory domain or forest." 傻逼微软!

Windows 7+ 系统可以通过 PowerShell 以程序方式访问和修改组策略。首先需要在 Windows Features 里下载启用相关组件:

  • Windows 7 : control - Turn Windows Features on or off: 启用 Remote Server Administraton Tools > Feature Administration Tools > Group Policy Management Tools
  • Windows 11 : Settings - Add on optional feature - 启用 "RSAT: Remote Access Management Tools"。

然后可以在 PowerShell 里 Import-Module GroupPolicy 并使用该模块里的 cmdlet 访问组策略(注:似乎不 Import-Module 也可以直接使用)。参考资料


Last update: 2022-11-30 06:46:58 UTC