C++를 사용하여 Windows에서 그룹 정책의 다양한 작업을 수행하는 방법을 알려주세요.

내 마지막 습지 게시물:

/dsadsi/archive/2009/07/23/working-with-group-policy-objects-programmatically-determining-registry-values-to -enable-disable-set-a-special-policy.aspx

레지스트리 기반 그룹 정책을 활성화/비활성화/설정하기 위해 레지스트리에 써야 하는 값을 결정하는 경험적 방법에 대해 논의했습니다. . 이번 게시물에서는 GPO에 핵심 정보를 쓰는 방법을 보여주는 간단한 C++ 함수를 제공하겠습니다.

지금은 GPO 수정을 위한 C++ 코드에 집중하겠습니다.

이 함수에는 3가지 정보가 필요합니다:

수정할 GPO 개체에 대한 ADsPath

모드 제어 값, 0=구성되지 않음, 1=활성화, 2=비활성화

p>

모드 제어 값을 나타내는 키에 쓸 실제 값입니다.

함수의 소스는 다음과 같습니다. 주석은 코드 작동 방식에 대한 통찰력을 제공해야 합니다. p> 한 가지 중요한 점은 특정 레지스트리 키 트리에 대한 여러 설정이 포함된 기존 GPO를 수정하는 경우 전체 키 트리를 삭제할 수 없으며 현재 설정에 영향을 미치는 값만 삭제해야 한다는 점을 인식하는 것입니다. 작업합니다.

또 다른 미묘한 문제는 IGroupPolicyObject::GetRegistryKey 및 IGroupPolicyObject::Save 메서드를 사용하는 방식입니다. GetRegistryKey에서 해당 섹션을 나타내는 플래그는 서명되지 않은 값(GPO_SECTION_ROOT, GPO_SECTION_USER 또는 GPO_SECTION_MACHINE)입니다. ) , Save 메서드의 섹션을 나타내는 플래그는 boo입니다.

Lean(머신 구성을 작성하려면 TRUE, 사용자 구성을 작성하려면 FALSE) 두 위치 모두에서 동일한 값을 사용하는 실수를 저질렀으며 IGroupPolicyObject 인터페이스에서 버그를 쫓고 있다고 생각했습니다.

찾기 경로가 어려울 수 있습니다. 다음 블로그 게시물에서는 GPMC 개체 모델 또는 BrowseForGPO 기능을 사용하여 특정 정보를 기반으로 AD에서 GPO 개체를 찾는 방법에 대한 세부 정보를 제공합니다.

C++ 소스 코드는 다음과 같습니다. :

HRESULT ModifyUserPolicyForPreventAccessToCmdPrompt( BSTR bGPOPath, intiMode, DWORD lData)

{

HRESULT hr=S_OK;

//

// IGroupPolicyObject를 사용하여 레지스트리 설정을 검색하고 수정합니다.

// gpoInfo.lpDsPath가 나타내는 GPO의 경우

//

IGroupPolicyObject* p = NULL;

hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL,

CLSCTX_INPROC_SERVER, IID_IGroupPolicyObject,

(LPVOID*)&p);

if (SUCCEEDED(hr))

{

//

// 수정하려는 GPO 값은

//

// 사용자 구성

// +> 정책

// +>관리 템플릿

// +->시스템

// +->명령 프롬프트에 대한 액세스 방지

//

DWORD dwSection = GPO_SECTION_USER;

HKEY hGPOSectionKey = NULL;

DWO

RD dwData;

HKEY hSettingKey;

LSTATUS rStatus;

hr = 0;

//

//GPO를 열고 컴퓨터와 사용자 모두에 대한 레지스트리 값을 로드합니다.

//

hr = p->OpenDSGPO( bGPOPath, GPO_OPEN_LOAD_REGISTRY);

//

// GPO에 대한 사용자 Registy 하이브 요청

//

hr = p->GetRegistryKey(dwSection, &hGPOSectionKey);

//

// 구성하지 않음으로 설정할지 결정합니다.

// GPO 자체에 대해 활성화 또는 비활성화합니다.

//

// 두 번째 호출인 RequestSetting은 "예" 또는 "아니요"를 제공합니다.

// 설정 값

// GPO 편집기에 표시된 정책

//

// iMode

// 0=구성되지 않음, 1=활성화, 2=비활성화

//

스위치(iMode)

{

사례 0:

//

// GPO를 구성하고 싶지는 않지만

// 동일한 키의 다른 GPO에 영향을 주고 싶지는 않습니다.

// 따라서 값만 삭제하세요. ​​이

// 특정 GPO 설정과 연결됩니다.

//

rStatus = RegDeleteValue(hGPOSectionKey,

L"Software \\Policies\ \Microsoft\\Windows\\System\\DisableCMD"

);

rStatus = RegDeleteValue(hGPOSectionKey,

L"Software\\Policies\\Microsoft\\Windows\\System\\**del.DisableCMD"

);

break;

사례 1 :

{

//

// 정책을 활성화하려면 비활성화CMD 값이 있어야 합니다

// 존재하고 ** del.DisableCMD 값은 허용되지 않아야 합니다.

//

// lData:

//

// 이 정책에 대한 키가 존재합니다.

// 핸들이 있으면 핸들을 검색합니다.

// 핸들이 없으면 생성합니다.

//

if( RegOpenKeyEx( hGPOSectionKey,

L"Software\\Policies\\Microsoft\\Windows\\System", 0,

KEY_WRITE, &hSettingKey) != ERROR_SUCCESS )

{

rStatus = RegCreateKeyEx(

hGPOSectionKey,

L"Software\\Policies\\Microsoft\\Windows\\ 시스템",

0,

NULL,

REG_OPTION_NON_VOLATILE,

KEY_WRITE,

NULL,

p> p>

&hSettingKey,

NULL );

}

//

// 값을 비활성화CMD로 설정하고 허용, 허용하지 않음

//스크립

t CMD 실행

//

rStatus = RegSetValueEx(hSettingKey, L"DisableCMD",

NULL, REG_DWORD, (BYTE *)(&lData),

sizeof(DWORD));

//

// 하이브에서 구성되지 않은 값 표시기를 제거합니다.

// 존재하지 않을 수 있으므로 RegDeleteValue는

// 오류를 반환할 수 있으며, 이는 무시할 수 있습니다.

//

rStatus = RegDeleteValue(hGPOSectionKey,

L"Software\\Policies\\Microsoft\\Windows\\System\\**del.DisableCMD"

);

rStatus = RegCloseKey(hSettingKey );

break;

}

사례 2:

{

//

// 정책을 비활성화합니다.

// 비활성화CMD 값을 제거하고

// **del.DisableCMD 값을 추가해야 합니다.

/ /

// 이전과 동일한 단계입니다. 이 정책에 대한 키가 있는지 확인하고

// 정책에 대한 키가 있는지 확인하고,

// 없으면 생성합니다.

//

BOOL bCreate = FALSE;

if( RegOpenKeyEx( hGPOSectionKey, L"Software\\Policies\\Microsoft\\Windows\\System" , 0, KEY_WRITE, &hSettingKey) != ERROR_SUCCESS )

{

rStatus = RegCreateKeyEx(

hGPOSectionKey,

L"Software\\Policies\\Microsoft\\Windows\\System",

0,

NULL,

REG_OPTION_NON_VOLATILE,

KEY_WRITE,

NULL,

&hSettingKey,

NULL );

bCreate = TRUE;

}

DWORD dwType = 0;

DWORD cbType = sizeof( dwData );

if( !bCreate )

{

//

// 키를 생성하지 않은 경우 , 그러면 값이

// *존재할 수도 있습니다.

// 읽으려고 시도합니다. 성공하면 해당 값을 다시 씁니다.

// **del.DisableCMD

// 그렇지 않은 경우 **del.DisableCMD를 0으로 설정합니다.

//

rStatus = RegGetValue(hGPOSectionKey, p>

L"Software\\Policies\\Microsoft\\Windows\\System", L"DisableCMD", RRF_RT_ANY, &dwType, (BYTE *)(&dwData), &cbType);

if ( rStatus != ERROR_SUCCESS ) dwData = 0;

else RegDeleteValue( hSettingKey, L"DisableCMD");

rStatus = RegSetVal

ueEx(hSettingKey, L"**del.DisableCMD", NULL, REG_DWORD, (BYTE *)(&dwData), sizeof(DWORD));

}

else

{

//

// 키가 생성되었습니다. **del.DisableCMD

// 값을 0으로 설정하세요.

//

dwData = 0;

rStatus = RegSetValueEx(hSettingKey, L"**del.DisableCMD", NULL, REG_DWORD, (BYTE *)(&dwData ), sizeof(DWORD));

}

rStatus = RegCloseKey(hSettingKey);

}

}

GUID RegistryId = REGISTRY_EXTENSION_GUID;

GUID ThisAdminToolGuid =

/*{ CLSID_PolicySnapinUser/* */

{

0x0F6B957E,

0x509E,

0x11D1,

{0xA7, 0xCC, 0x00, 0x00, 0xF8, 0x75, 0x71, 0xE3}

} ;

rStatus = RegCloseKey(hGPOSectionKey);

//

// 디렉터리에 GPO를 다시 씁니다.

//

시간 = p->저장(

FALSE,

TRUE,

&RegistryId,

&ThisAdminToolGuid );

시간 = p->Release();

}

시간 반환;

}