Search code examples
c#.netwindows-security

How to apply Windows group policy using .NET?


Is it possible to apply (and remove) Windows group policy settings using .NET?

I am working on an application that needs to temporarily put a machine into a restricted, kiosk-like state. One of the things I need to control is access to USB drives which I believe I can do through group policy. I'd like my app to set the policy when it starts and revert the change when it exits... is this something I can do through .NET framework calls?

These are my primary requirements:

  • Apply group policy settings when my console app is started.
  • Identify when a user action is denied by the policy and log it.
    • Logging to the system security log is acceptable.
  • Revert my policy changes when my app stops.

Solution

  • 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 like this..

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