2010-02-15 46 views
6

是否可以使用.NET应用(并删除)Windows组策略设置?如何使用.NET应用Windows组策略?

我正在研究一个需要暂时需要的应用程序将一台机器设置为受限制的亭子状态。我需要控制的一件事是访问USB驱动器,我相信我可以通过组策略来实现。我希望我的应用程序在启动时设置策略,并在退出时恢复更改......这是我可以通过.NET框架调用完成的事情吗?

这是我的基本要求:

  • ,当我的控制台应用程序启动应用组策略设置。
  • 确定用户操作何时被策略拒绝并记录下来。
    • 记录到系统安全日志是可以接受的。
  • 当我的应用停止时恢复我的策略更改。
+0

在我看来,以有限的用户身份运行您的应用程序比作为可以更改计算机上的组策略的提升用户运行要安全得多。 – Will

+0

同意,但这不适用于此特定情况。此应用安装在我无法控制的系统上的时间足够长,以便用户在我们提供的受限制沙箱内执行一些定时操作,然后删除我的应用。我不能认为已经存在足够有限的用户帐户,因此我希望能够即时创建环境。 –

+0

我不认为你可以通过托管代码来改变本地策略。这只能通过C \ C++中的IGroupPolicyObject来完成 –

回答

3

尝试使用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; 
} 

你可以这样调用这个函数..

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

感谢您的答案。不幸的是,我正在寻找C#中的东西,虽然我可能应该指定。尽管这并不能帮助我,但我将其标记为正确的答案,因为它是我实际询问的问题的最佳答案,并且最有可能帮助某人搜索类似的解决方案。 –

+0

什么是HKEY_CURRENT_USER的值?和REG_DWORD ???例如? – Danilo

+0

@ SethPetry-Johnson 什么是HKEY_CURRENT_USER的值?和REG_DWORD ???例如? – Danilo

0

我还没有玩过它,但System.Security.Policy看起来像它可能是一个有趣的起点。根据要求

重贴链接:Group Policy access via Registry

+1

System.Security.Policy似乎与CLR代码访问安全性有关,这不是我所追求的。虽然谢谢! –

+0

嗯,你说得对。这个怎么样 - 看起来没有方便的.NET对象来管理GP实体,但是这个链接[http://www.devx。com/dotnet/Article/34784/1763/page/5]讨论了如何通过注册管理机构(毕竟这是GP的实际生活地点)进行的。这是ASP.NET,但它可能是... –

+0

这看起来有些有前途,虽然我希望我刚添加的赏金将帮助我找到更直接的答案。您介意将该链接重新张贴为新答案吗?这样,如果没有提供更好的答案,您会在到期时获得赏金。 –

2

退房www.sdmsoftware.com/group_policy_scripting。它不是免费的,但会完全符合你的要求。

+0

感谢您的链接。不幸的是,它看起来非常昂贵(通常是因为你必须联系销售人员才能得到报价),而且这可能是对我在这个项目上的需求的矫枉过正。但你是对的,它似乎做我所要求的:) –

3

注:我用两个GroupPolicy中集的引用: C:\ WINDOWS \装配\ GAC_MSIL \微软.GroupPolicy.Management \ 2.0.0.0__31bf3856ad364e35 \ Microsoft.GroupPolicy.Management.dll 和 C:\ Windows \ assembly \ GAC_32 \ Microsoft.GroupPolicy.Management.Interop \ 2.0.0.0__31bf3856ad364e35 \ Microsoft.Grou pPolicy.Management.Interop.dll 这个框架2.0,所以有混合代码,你必须使用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

我这样做。

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