2010-02-15 25 views
6

¿Es posible aplicar (y eliminar) la configuración de directiva de grupo de Windows con .NET?¿Cómo aplicar la política de grupo de Windows con .NET?

Estoy trabajando en una aplicación que necesita temporalmente poner una máquina en un estado restringido tipo kiosco. Una de las cosas que necesito controlar es el acceso a unidades USB, que creo que puedo hacer a través de la política de grupo. Me gustaría que mi aplicación establezca la política cuando se inicia y revierte el cambio cuando sale ... ¿Esto es algo que puedo hacer a través de las llamadas de .NET Framework?

Estos son mis requisitos principales:

  • aplicar la configuración de directiva de grupo cuando se inicia mi aplicación de consola.
  • Identifique cuando la política niega una acción del usuario y conéctela.
    • El registro en el registro de seguridad del sistema es aceptable.
  • Revertir mis cambios de política cuando se detiene mi aplicación.
+0

Me parece que ejecutar su aplicación como usuario limitado es mucho más seguro que ejecutar como un usuario elevado que puede cambiar las políticas de grupo en la computadora. – Will

+0

De acuerdo, pero eso no funciona para este escenario en particular. Esta aplicación se instala en sistemas que no controlo el tiempo suficiente para que un usuario realice algunas acciones cronometradas dentro de la zona restringida que proporcionamos, y luego se elimina mi aplicación. No puedo suponer que ya existe una cuenta de usuario suficientemente restringida, de ahí mi deseo de crear el entorno sobre la marcha. –

+0

No creo que pueda cambiar la política local a través del código administrado. Esto solo se puede hacer a través de IGroupPolicyObject en C \ C++ –

Respuesta

3

Trate de usar 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; 
} 

Usted puede llamar a esta función como esta ..

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

Gracias por la respuesta. Desafortunadamente estaba buscando algo en C#, aunque probablemente debería haberlo especificado. Aunque esto no me ayuda, lo estoy marcando como la respuesta correcta porque es la mejor respuesta a la pregunta que realmente hice y más probable que ayude a alguien que busca una solución similar. –

+0

¿Cuáles serían los valores HKEY_CURRENT_USER? y REG_DWORD ??? por ejemplo? – Danilo

+0

@ SethPetry-Johnson ¿Cuáles serían los valores HKEY_CURRENT_USER? y REG_DWORD ??? por ejemplo? – Danilo

0

No he jugado con él, pero System.Security.Policy parece que podría ser un interesante punto de partida.

enlace Re-publicado como solicitada: Group Policy access via Registry

+1

System.Security.Policy parece estar relacionado con la seguridad de acceso al código CLR, que no es lo que busco. ¡Gracias! –

+0

Hmm, tienes razón. ¿Qué tal esto? Parece que no hay ningún objeto .NET útil para manupular entidades GP, pero este enlace [http: //www.devx.com/dotnet/Article/34784/1763/page/5] habla de hacerlo a través del Registro (que es, después de todo, donde en realidad vive GP). Es ASP.NET, pero podría ser una forma en ... –

+0

Parece algo prometedor, aunque espero que la recompensa que acabo de agregar me ayude a encontrar una respuesta más directa. ¿Le importaría volver a publicar ese enlace como una nueva respuesta? De esta forma, si no se proporciona una respuesta mejor, obtendrás la recompensa cuando caduque. –

2

Salida www.sdmsoftware.com/group_policy_scripting. No es gratis, pero hará exactamente lo que estás buscando.

+0

Gracias por el enlace. Desafortunadamente, parece caro (generalmente es cuando debe ponerse en contacto con ventas para obtener una cotización) y probablemente sea excesivo para mis necesidades en este proyecto. Pero estás en lo cierto, parece hacer lo que te pedí :) –

3

NOTA: Yo uso dos referencias de ensamblado GroupPolicy: C: \ Windows \ assembly \ GAC_MSIL \ Microsoft .GroupPolicy.Management \ 2.0.0.0__31bf3856ad364e35 \ Microsoft.GroupPolicy.Management.dll y C: \ Windows \ assembly \ GAC_32 \ Microsoft.GroupPolicy.Management.Interop \ 2.0.0.0__31bf3856ad364e35 \ Microsoft.Grou pPolicy.Management.Interop.dll Este marco 2.0, por lo que hay código mixto, y debe utilizar 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

Lo hice así.

using System.Collections.ObjectModel; 
using Microsoft.GroupPolicy; 
using Microsoft.Win32; 

/// <summary> 
/// Change user's registry policy 
/// </summary> 
/// <param name="gpoName">The name of Group Policy Object(DisplayName)</param> 
/// <param name="keyPath">Is KeyPath(like string [email protected]"Software\Microsoft\Windows\CurrentVersion\Policies\Explorer")</param> 
/// <param name="typeOfKey">DWord, ExpandString,... e.t.c </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; 
     } 
    } 
Cuestiones relacionadas