首页  编辑  

组策略设置命令行工具

Tags: /超级猛料/OS.操作系统/   Date Created:
Group Policy命令行设置工具,类似 reg 指令。
可以对本地组策略进行编辑,但是如果计算机加入了域,那么如果编辑域中定义的策略,是不起作用的,最终是域中策略优先!
暂时未找到忽略、覆盖域组策略的方法。
Windows 组策略的优先级 OU Policy> Domain Policy > Site Policy > Local Group Policy
正常情况下,域策略优先级高于本地策略,否则无法通过服务器管控客户端电脑了。

有个合法手段可以绕过域组策略就是使用 ntuser.man ,即强制用户配置文件,具体请自行搜索。其原理是在 %userprofile% 目录下放置一个处理过的 ntuser.dat ,然后保存为 ntuser.man 来实现的。Windows 登录的时候会优先加载  ntuser.man 文件,如果不存在才会加载  ntuser.dat。但这样做的缺点就是你的任何修改无法保存。这本来就是为了学校、网吧等需要恢复配置的情况使用的。

windows - Can I override domain group policy with local group policy as a local admin? - Server Fault
当然对于一些不是特别的注册表选项,你可以通过下面的方式来忽略掉(可能需要管理员权限,取决于对应注册表在HKCU还是HKLM):
新建一个触发器为On an event(发生事件时)的计划任务,日志设置为:Microsoft-Windows-GroupPolicy/Operational,源设置为:GroupPolicy,事件ID设置为 5016(应用组策略故障排除指南 - Windows Server | Microsoft Learn如下图:
然后你可以在操作中用个批处理修改掉对应的注册表,例如:
REG ADD "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v fDisableClip /t REG_DWORD /d 0 /f
上述即可强制远程桌面启用远程剪切板粘贴功能。

下载命令行工具: Poledit.exe
源代码:
#include <Windows.h>
#include <ObjBase.h>
#include <initguid.h>
#include <gpedit.h>
#include <shlwapi.h>
#include <iostream>

#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "ole32.lib")

void check(DWORD errorCode)
{
	if (SUCCEEDED(errorCode)) return;

	LPSTR messageBuffer = nullptr;
	size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

	if (size > 0)
	{
		std::cout << "Error: " << messageBuffer << std::endl;
		LocalFree(messageBuffer);
	}
	else
	{
		std::cout << "Error: Unknown error code " << errorCode << std::endl;
	}
	exit(errorCode);
}

void help(int argc, wchar_t* argv[]) {
	std::wcout << "Group policy editor v1.0" << std::endl;
	std::wcout << "Usage: " << argv[0] << " <Root> <Path> <Name> <Type> <Value>" << std::endl;
	std::cout << R"(
	Root	Registry root, 0 - Root, 1 - User, 2 - Machine
	Path	Registry path, Quote it if contain space.
	Name	Name of the value
	Type	Value type, Options: dword, string
	Value	Data

Example:
)";;
	std::wcout << "	" << argv[0] << " 2 \"SOFTWARE\\Policies\\Microsoft\\Windows NT\\Terminal Services\" fDisableClip dword 0" << std::endl;
	exit(1);
}

int wmain(int argc, wchar_t* argv[])
{
	if (argc < 5) help(argc, argv);

	HRESULT hr;
	hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
	check(hr);

	IGroupPolicyObject* pGPO;
	hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL, CLSCTX_INPROC_SERVER, IID_IGroupPolicyObject, (LPVOID*)&pGPO);
	check(hr);

	hr = pGPO->OpenLocalMachineGPO(GPO_OPEN_LOAD_REGISTRY);
	check(hr);

	HKEY hRoot;
	hr = pGPO->GetRegistryKey(_wtoi(argv[1]), &hRoot);
	check(hr);

	HKEY hSubKey;
	hr = RegCreateKeyExW(hRoot, argv[2], 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hSubKey, NULL);
	check(hr);

	if (_wcsicmp(argv[4], L"string") == 0) {
		const wchar_t* value = argv[5];
		check(RegSetValueExW(hSubKey, argv[3], 0, REG_SZ, (BYTE*)value, (wcslen(value) + 1) * sizeof(wchar_t)));
	}

	if (_wcsicmp(argv[4], L"dword") == 0) {
		DWORD value = _wtoi(argv[5]);
		check(RegSetValueExW(hSubKey, argv[3], 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD)));
	}
	RegCloseKey(hSubKey);

	check(RegCloseKey(hRoot));

	GUID registryExtensionGuid = REGISTRY_EXTENSION_GUID;
	GUID clsidGpeSnapIn = CLSID_GPESnapIn;
	hr = pGPO->Save(TRUE, TRUE, &registryExtensionGuid, &clsidGpeSnapIn);
	pGPO->Release();
	check(hr);
	SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"Policy", SMTO_NORMAL, 2000, NULL);

	CoUninitialize();
	return 0;
}

附一个老工具,不一定还有效,见附件 gpdisable.zip
以受限用户身份规避组策略 - Microsoft 社区中心
绕过组策略?- SDM软件 (sdmsoftware.com)

Poledit.exe (22.0KB)
gpdisable.zip (33.8KB)