How to apply Windows Group Policy using .NET?

Can I apply (and remove) Windows Group policy settings using .NET?

I am working on an application that should temporarily put the machine in a limited state, like a kiosk. One of the things I need to control is access to USB drives, which I believe can be accomplished using Group Policy. I want my application to set the policy on startup and return the change on exit ... is this something I can do through .NET framework calls?

These are my basic requirements:

  • Apply Group Policy settings when starting the console application.
  • Determine when a user policy is rejected and logs it.
    • Access to the system security log is valid.
  • Revert my policy changes when my application stops.
+6
c #
source share
4 answers

Try using IGroupPolicyObject

bool SetGroupPolicy(HKEY hKey, LPCTSTR subKey, LPCTSTR valueName, DWORD dwType, const BYTE* szkeyValue, DWORD dwkeyValue) { CoInitialize(NULL); HKEY ghKey, ghSubKey, hSubKey; LPDWORD flag = NULL; IGroupPolicyObject *pGPO = NULL; HRESULT hr = CoCreateInstance(CLSID_GroupPolicyObject, NULL, CLSCTX_ALL, IID_IGroupPolicyObject, (LPVOID*)&pGPO); if(!SUCCEEDED(hr)) { MessageBox(NULL, L"Failed to initialize GPO", L"", S_OK); } if (RegCreateKeyEx(hKey, subKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hSubKey, flag) != ERROR_SUCCESS) { return false; CoUninitialize(); } if(dwType == REG_SZ) { if(RegSetValueEx(hSubKey, valueName, 0, dwType, szkeyValue, strlen((char*)szkeyValue) + 1) != ERROR_SUCCESS) { RegCloseKey(hSubKey); CoUninitialize(); return false; } } else if(dwType == REG_DWORD) { if(RegSetValueEx(hSubKey, valueName, 0, dwType, (BYTE*)&dwkeyValue, sizeof(dwkeyValue)) != ERROR_SUCCESS) { RegCloseKey(hSubKey); CoUninitialize(); return false; } } if(!SUCCEEDED(hr)) { MessageBox(NULL, L"Failed to initialize GPO", L"", S_OK); CoUninitialize(); return false; } if(pGPO->OpenLocalMachineGPO(GPO_OPEN_LOAD_REGISTRY) != S_OK) { MessageBox(NULL, L"Failed to get the GPO mapping", L"", S_OK); CoUninitialize(); return false; } if(pGPO->GetRegistryKey(GPO_SECTION_USER,&ghKey) != S_OK) { MessageBox(NULL, L"Failed to get the root key", L"", S_OK); CoUninitialize(); return false; } if(RegCreateKeyEx(ghKey, subKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &ghSubKey, flag) != ERROR_SUCCESS) { RegCloseKey(ghKey); MessageBox(NULL, L"Cannot create key", L"", S_OK); CoUninitialize(); return false; } if(dwType == REG_SZ) { if(RegSetValueEx(ghSubKey, valueName, 0, dwType, szkeyValue, strlen((char*)szkeyValue) + 1) != ERROR_SUCCESS) { RegCloseKey(ghKey); RegCloseKey(ghSubKey); MessageBox(NULL, L"Cannot create sub key", L"", S_OK); CoUninitialize(); return false; } } else if(dwType == REG_DWORD) { if(RegSetValueEx(ghSubKey, valueName, 0, dwType, (BYTE*)&dwkeyValue, sizeof(dwkeyValue)) != ERROR_SUCCESS) { RegCloseKey(ghKey); RegCloseKey(ghSubKey); MessageBox(NULL, L"Cannot set value", L"", S_OK); CoUninitialize(); return false; } } if(pGPO->Save(false, true, const_cast<GUID*>(&EXTENSION_GUID), const_cast<GUID*>(&CLSID_GPESnapIn)) != S_OK) { RegCloseKey(ghKey); RegCloseKey(ghSubKey); MessageBox(NULL, L"Save failed", L"", S_OK); CoUninitialize(); return false; } pGPO->Release(); RegCloseKey(ghKey); RegCloseKey(ghSubKey); CoUninitialize(); return true; } 

You can call this function as follows.

 // Remove the Log Off in start menu SetGroupPolicy(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", L"StartMenuLogOff", REG_DWORD, NULL, 1); 
+3
source share

NOTE. I use two GroupPolicy assembly links: C: \ Windows \ assembly \ GAC_MSIL \ Microsoft.GroupPolicy.Management \ 2.0.0.0__31bf3856ad364e35 \ Microsoft.GroupPolicy.Management.dll and C: \ Windows \ assembly \ GAC_32 \ Microsoft.GroupPolicy.Management .Interop \ 2.0.0.0__31bf3856ad364e35 \ Microsoft.GroupPolicy.Management.Interop.dll This environment is 2.0, so there is mixed code and you should use app.config: http://msmvps.com/blogs/rfennell/archive/2010/ 03/27 / mixed-mode-assembly-is-built-against-version-v2-0-50727-error-using-net-4-development-web-server.aspx

I did it like that.

 using System.Collections.ObjectModel; using Microsoft.GroupPolicy; using Microsoft.Win32; /// <summary> /// Change user registry policy /// </summary> /// <param name="gpoName">The name of Group Policy Object(DisplayName)</param> /// <param name="keyPath">Is KeyPath(like string path=@ "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer")</param> /// <param name="typeOfKey">DWord, ExpandString,... etc </param> /// <param name="parameterName">Name of parameter</param> /// <param name="value">Value</param> /// <returns>result: true\false</returns> public bool ChangePolicyUser(string gpoName, string keyPath, RegistryValueKind typeOfKey, string parameterName, object value) { try { RegistrySetting newSetting = new PolicyRegistrySetting(); newSetting.Hive = RegistryHive.CurrentUser; newSetting.KeyPath = keyPath; bool contains = false; //newSetting.SetValue(parameterName, value, typeOfKey); switch (typeOfKey) { case RegistryValueKind.String: newSetting.SetValue(parameterName, (string)value, typeOfKey); break; case RegistryValueKind.ExpandString: newSetting.SetValue(parameterName, (string)value, typeOfKey); break; case RegistryValueKind.DWord: newSetting.SetValue(parameterName, (Int32)value); break; case RegistryValueKind.QWord: newSetting.SetValue(parameterName, (Int64)value); break; case RegistryValueKind.Binary: newSetting.SetValue(parameterName, (byte[])value); break; case RegistryValueKind.MultiString: newSetting.SetValue(parameterName, (string[])value, typeOfKey); break; } Gpo gpoTarget = _gpDomain.GetGpo(gpoName); RegistryPolicy registry = gpoTarget.User.Policy.GetRegistry(false); try { ReadOnlyCollection<RegistryItem> items = gpoTarget.User.Policy.GetRegistry(false).Read(newSetting.Hive, keyPath); foreach (RegistryItem item in items) { if (((RegistrySetting) item).ValueName == parameterName) { contains = true; } } registry.Write((PolicyRegistrySetting) newSetting, !contains); registry.Save(false); return true; } catch (ArgumentException) { registry.Write((PolicyRegistrySetting)newSetting, contains); registry.Save(true); return true; } } catch (Exception) { return false; } } 
+3
source share

Check out www.sdmsoftware.com/group_policy_scripting. It is not free, but will do what you need.

+2
source share

I did not play with it myself, but System.Security.Policy looks like this can be an interesting starting point.

Request sent link: Access to Group Policy through the registry

0
source share

All Articles