views:

323

answers:

3

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.
A: 

I haven't played with it myself, but System.Security.Policy looks like it might be an interesting starting-point.

Re-posted link as requested: Group Policy access via Registry

Jonners
System.Security.Policy seems to be related to CLR code access security, which isn't what I'm after. Thanks though!
Seth Petry-Johnson
Hmm, you're right. How about this - it looks like there's no handy .NET object to manupulate GP entities, but this link [http://www.devx.com/dotnet/Article/34784/1763/page/5] talks about doing it via the Registry (which is, after all, where the GP stuff actually lives). It's ASP.NET, but it might be a way in...
Jonners
That looks somewhat promising, although I'm hoping the bounty I just added will help me find a more direct answer. Would you mind re-posting that link as a new answer? That way, if no better answer is provided, you'll get the bounty when it expires.
Seth Petry-Johnson
+1  A: 

Check out www.sdmsoftware.com/group_policy_scripting. Its not free but will do exactly what you're after.

Darren
Thanks for the link. Unfortunately it _looks_ expensive (it usually is when you have to contact sales for a quote) and is probably overkill for my needs on this project. But you are correct, it does seem to do what I asked for :)
Seth Petry-Johnson
A: 

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;
}//OpenLocalMachine

if(pGPO->GetRegistryKey(GPO_SECTION_USER,&ghKey) != S_OK)
{
    MessageBox(NULL,L"Failed to get the root key",L"",S_OK);
    CoUninitialize();
    return false;
}//GetRegistryKey

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;
}//RegCreateKeyEx

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;
    }//RegSetValueEx
}

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;
    }//RegSetValueEx
}

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);
Santhosh
Thanks for the answer. Unfortunately I was looking for something in C#, although I probably should have specified that. Even though this doesn't help me I'm flagging it as the correct answer because its the best answer to the question that I actually asked and most likely to help someone searching for a similar solution.
Seth Petry-Johnson