Как применить групповую политику Windows с помощью .NET?

Можно ли применять (и удалять) параметры групповой политики Windows с помощью .NET?

Я работаю над приложением, которому нужно временно перевести машину в ограниченное состояние, похожее на киоск. Одна из вещей, которую мне нужно контролировать, — это доступ к USB-накопителям, который, как мне кажется, я могу сделать с помощью групповой политики. Я хотел бы, чтобы мое приложение устанавливало политику при запуске и отменяло изменение при выходе... могу ли я это сделать с помощью вызовов .NET framework?

Вот мои основные требования:

  • Применять параметры групповой политики при запуске моего консольного приложения.
  • Identify when a user action is denied by the policy and log it.
    • Logging to the system security log is acceptable.
  • Отменить изменения моей политики, когда мое приложение остановится.

person Seth Petry-Johnson    schedule 15.02.2010    source источник
comment
Мне кажется, что запуск вашего приложения в качестве пользователя с ограниченными правами намного безопаснее, чем запуск в качестве пользователя с повышенными правами, который может изменять групповые политики на компьютере.   -  person    schedule 15.02.2010
comment
Согласен, но это не работает для этого конкретного сценария. Это приложение устанавливается в системах, которые я не контролирую, на время, достаточное для того, чтобы пользователь выполнил некоторые действия по времени в изолированной программной среде, которую мы предоставляем, а затем мое приложение удаляется. Я не могу предположить, что уже существует достаточно ограниченная учетная запись пользователя, отсюда и мое желание создать среду на лету.   -  person Seth Petry-Johnson    schedule 15.02.2010
comment
Я не думаю, что вы можете изменить локальную политику с помощью управляемого кода. Это можно сделать только через IGroupPolicyObject в C\C++.   -  person Saher Ahwal    schedule 11.06.2012


Ответы (2)


Попробуйте использовать 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);
person Santhosh    schedule 23.02.2010
comment
Спасибо за ответ. К сожалению, я искал что-то на С#, хотя, вероятно, мне следовало указать это. Несмотря на то, что это мне не помогает, я отмечаю его как правильный ответ, потому что это лучший ответ на вопрос, который я действительно задавал, и, скорее всего, он поможет кому-то найти подобное решение. - person Seth Petry-Johnson; 24.02.2010
comment
Какими будут значения HKEY_CURRENT_USER?? и REG_DWORD??? например? - person Danilo; 18.01.2018
comment
@SethPetry-Johnson Какими будут значения HKEY_CURRENT_USER ?? и REG_DWORD??? например? - person Danilo; 18.01.2018
comment
В этом посте отсутствует важная информация. Какие заголовки? Какие нужны либы? #include ‹GPEdit.h› необходим, но я не могу понять, почему я получаю ошибки связывания при использовании CLSID_GPESnapIn - person zezba9000; 04.12.2019

ПРИМЕЧАНИЕ. Я использую две ссылки на сборки GroupPolicy: C:\Windows\assembly\GAC_MSIL\Microsoft.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.GroupPolicy.Management.Interop.dll Это framework 2.0, поэтому там смешанный код, и вы должны использовать app.config: http://msmvps.com/blogs/rfennell/archive/2010/03/27/mixed-mode-assembly-is-build-против-версии-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 path=@"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;
        }
    }
person Jonik    schedule 19.03.2012