2010-02-15 11 views
6

È possibile applicare (e rimuovere) le impostazioni dei criteri di gruppo di Windows utilizzando .NET?Come applicare i criteri di gruppo di Windows utilizzando .NET?

Sto lavorando su un'applicazione che necessita di temporaneamente mettere una macchina in uno stato limitato, simile a un chiosco. Una delle cose che devo controllare è l'accesso alle unità USB che credo di poter fare attraverso i criteri di gruppo. Mi piacerebbe che la mia app impostasse la politica all'avvio e ripristinasse la modifica quando esce ... è qualcosa che posso fare tramite le chiamate di framework .NET?

Queste sono le mie esigenze principali:

  • applicati i criteri di gruppo quando viene avviata la console app.
  • Identifica quando un'azione viene negata dal criterio e la registra.
    • La registrazione nel registro di sicurezza del sistema è accettabile.
  • Ripristina le modifiche alle norme quando la mia app si arresta.
+0

Mi sembra che l'esecuzione dell'app come utente limitato sia molto più sicura rispetto all'esecuzione come utente con privilegi elevati che può modificare i criteri di gruppo sul computer. – Will

+0

D'accordo, ma non funziona per questo particolare scenario. Questa app viene installata su sistemi che non controllo abbastanza a lungo perché un utente possa eseguire alcune azioni temporizzate all'interno della sandbox limitata che forniamo, e quindi la mia app viene rimossa. Non posso presumere che esista già un account utente sufficientemente limitato, quindi il mio desiderio di creare l'ambiente al volo. –

+0

Non penso che sia possibile modificare la politica locale tramite il codice gestito. Questo può essere fatto solo tramite IGroupPolicyObject in C \ C++ –

risposta

3

Prova utilizzando 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; 
} 

È possibile chiamare questa funzione come questa ..

// 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

Grazie per la risposta. Purtroppo stavo cercando qualcosa in C#, anche se probabilmente avrei dovuto specificarlo. Anche se questo non mi aiuta, lo considero la risposta corretta perché è la migliore risposta alla domanda che ho effettivamente posto e che è più probabile che aiuti qualcuno a cercare una soluzione simile. –

+0

Quali sarebbero i valori HKEY_CURRENT_USER ?? e REG_DWORD ??? per esempio? – Danilo

+0

@ SethPetry-Johnson Quali sarebbero i valori HKEY_CURRENT_USER ?? e REG_DWORD ??? per esempio? – Danilo

0

Non ho mai giocato con esso, ma System.Security.Policy sembra che potrebbe essere un punto di partenza interessante.

collegamento Re-scritto come richiesto: Group Policy access via Registry

+1

System.Security.Policy sembra essere correlato alla sicurezza dell'accesso al codice CLR, che non è quello che sto cercando. Grazie comunque! –

+0

Hmm, hai ragione. Che ne dici di questo: sembra che non ci sia un utile oggetto .NET per gestire le entità GP, ma questo link [http: //www.devx.it/dotnet/Article/34784/1763/page/5] parla di come farlo tramite il Registro di sistema (che è, dopotutto, dove la roba del GP vive effettivamente). È ASP.NET, ma potrebbe essere un modo in ... –

+0

Questo sembra un po 'promettente, anche se spero che la taglia che ho appena aggiunto mi aiuterà a trovare una risposta più diretta. Ti dispiacerebbe ripubblicare quel collegamento come una nuova risposta? In questo modo, se non viene fornita una risposta migliore, otterrai la taglia quando scade. –

2

Partenza www.sdmsoftware.com/group_policy_scripting. Non è gratuito, ma farà esattamente quello che stai cercando.

+0

Grazie per il link. Sfortunatamente è costoso (di solito è quando devi contattare le vendite per un preventivo) ed è probabilmente eccessivo per le mie esigenze in questo progetto. Ma hai ragione, sembra che faccia quello che ho chiesto :) –

3

NOTA: Io uso due riferimenti di assemblaggio GroupPolicy: C: \ Windows \ Assembly \ GAC_MSIL \ Microsoft .GroupPolicy.Management \ 2.0.0.0__31bf3856ad364e35 \ Microsoft.GroupPolicy.Management.dll e C: \ Windows \ assembly \ GAC_32 \ Microsoft.GroupPolicy.Management.Interop \ 2.0.0.0__31bf3856ad364e35 \ Microsoft.Grou pPolicy.Management.Interop.dll Questo framework 2.0, quindi ci sono codice misto, ed è necessario utilizzare 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

Ho fatto così.

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; 
     } 
    } 
Problemi correlati