0

Я разрабатываю приложение типа киоска Windows 8.1, и мне нужно установить настраиваемый пользовательский интерфейс групповой политики в .exe приложения. Это, конечно, можно выполнить вручную, но я хотел бы иметь возможность изменить его с помощью C# или, альтернативно, установщика (сейчас я использую установку Visual Studio).Как изменить групповую политику Windows 8.1 программно в C#?

Спасибо за помощь!

+0

Google «gpedit automation», сделайте первый удар. –

+0

Автоматическая групповая политика с PowerShell? Я взгляну. Спасибо, Ханс! – Giallo

ответ

1

путь является:

  1. Создать Custom Action и добавить его в раздел установщиком Установить.
  2. Использование неуправляемого LsaAddAccountRights метод, чтобы установить какую-либо политику в любой учетной записи пользователя или группы (например, Администраторы, пользователи, все). Все, что вам нужно знать, это право Политическая ручка и Право пользователя, которое вы хотите назначить.

Теперь, вплоть до реализации :-)

Пожалуйста, проверьте код, приведенный ниже. Это реализация я закончил с помощью анализа и заимствования разных фрагментов кода из различных ресурсов:

public class LSAManager 
{ 
    [DllImport("advapi32.dll", PreserveSig = true)] 
    private static extern uint LsaOpenPolicy(ref LSA_UNICODE_STRING SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, Int32 DesiredAccess, out IntPtr PolicyHandle); 
    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true), SuppressUnmanagedCodeSecurityAttribute] 
    private static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr pSID, LSA_UNICODE_STRING[] UserRights, int CountOfRights); 
    [DllImport("advapi32.dll")] 
    public static extern void FreeSid(IntPtr pSid); 
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, PreserveSig = true)] 
    private static extern bool LookupAccountName(string lpSystemName, string lpAccountName, IntPtr psid, ref int cbsid, StringBuilder domainName, ref int cbdomainLength, ref int use); 
    [DllImport("advapi32.dll")] 
    private static extern bool IsValidSid(IntPtr pSid); 
    [DllImport("advapi32.dll")] 
    private static extern int LsaClose(IntPtr ObjectHandle); 
    [DllImport("advapi32.dll")] 
    private static extern int LsaNtStatusToWinError(int status); 

    [DllImport("kernel32.dll")] 
    private static extern int GetLastError(); 

    [StructLayout(LayoutKind.Sequential)] 
    private struct LSA_UNICODE_STRING 
    { 
     public UInt16 Length; 
     public UInt16 MaximumLength; 
     public IntPtr Buffer; 
    } 
    [StructLayout(LayoutKind.Sequential)] 
    private struct LSA_OBJECT_ATTRIBUTES 
    { 
     public int Length; 
     public IntPtr RootDirectory; 
     public LSA_UNICODE_STRING ObjectName; 
     public UInt32 Attributes; 
     public IntPtr SecurityDescriptor; 
     public IntPtr SecurityQualityOfService; 
    } 

    private enum LSA_AccessPolicy : long 
    { 
     POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L, 
     POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L, 
     POLICY_GET_PRIVATE_INFORMATION = 0x00000004L, 
     POLICY_TRUST_ADMIN = 0x00000008L, 
     POLICY_CREATE_ACCOUNT = 0x00000010L, 
     POLICY_CREATE_SECRET = 0x00000020L, 
     POLICY_CREATE_PRIVILEGE = 0x00000040L, 
     POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L, 
     POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L, 
     POLICY_AUDIT_LOG_ADMIN = 0x00000200L, 
     POLICY_SERVER_ADMIN = 0x00000400L, 
     POLICY_LOOKUP_NAMES = 0x00000800L, 
     POLICY_NOTIFICATION = 0x00001000L 
    } 

    /// <summary>Adds a privilege to an account</summary> 
    /// <param name="accountName">Name of an account - "domain\account" or only "account"</param> 
    /// <param name="privilegeName">Name of the privilege</param> 
    /// <returns>The windows error code returned by LsaAddAccountRights (0 = success)</returns> 
    public static long SetRight(String accountName, String privilegeName) 
    { 
     long winErrorCode = 0; //contains the last error 

     //pointer an size for the SID 
     IntPtr sid = IntPtr.Zero; 
     int sidSize = 0; 
     //StringBuilder and size for the domain name 
     StringBuilder domainName = new StringBuilder(); 
     int nameSize = 0; 
     //account-type variable for lookup 
     int accountType = 0; 

     //get required buffer size 
     LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); 

     //allocate buffers 
     domainName = new StringBuilder(nameSize); 
     sid = Marshal.AllocHGlobal(sidSize); 

     //lookup the SID for the account 
     bool result = LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); 

     // check SID if required: IsValidSid(sid)); 

     if (!result) 
     { 
      winErrorCode = GetLastError(); 
     } 
     else 
     { 
      //initialize an empty unicode-string 
      LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING(); 
      //combine all policies 
      int access = (int)(
       LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN | 
       LSA_AccessPolicy.POLICY_CREATE_ACCOUNT | 
       LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE | 
       LSA_AccessPolicy.POLICY_CREATE_SECRET | 
       LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION | 
       LSA_AccessPolicy.POLICY_LOOKUP_NAMES | 
       LSA_AccessPolicy.POLICY_NOTIFICATION | 
       LSA_AccessPolicy.POLICY_SERVER_ADMIN | 
       LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS | 
       LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS | 
       LSA_AccessPolicy.POLICY_TRUST_ADMIN | 
       LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION | 
       LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION 
       ); 
      //initialize a pointer for the policy handle 
      IntPtr policyHandle = IntPtr.Zero; 

      //these attributes are not used, but LsaOpenPolicy wants them to exists 
      LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES(); 
      ObjectAttributes.Length = 0; 
      ObjectAttributes.RootDirectory = IntPtr.Zero; 
      ObjectAttributes.Attributes = 0; 
      ObjectAttributes.SecurityDescriptor = IntPtr.Zero; 
      ObjectAttributes.SecurityQualityOfService = IntPtr.Zero; 

      //get a policy handle 
      uint resultPolicy = LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle); 
      winErrorCode = LsaNtStatusToWinError((int)resultPolicy); 

      if (winErrorCode == 0) 
      { 
       //Now that we have the SID and the policy, 
       //we can add rights to the account. 

       //initialize an unicode-string for the privilege name 
       LSA_UNICODE_STRING[] userRights = new LSA_UNICODE_STRING[1]; 
       userRights[0] = new LSA_UNICODE_STRING(); 
       userRights[0].Buffer = Marshal.StringToHGlobalUni(privilegeName); 
       userRights[0].Length = (UInt16)(privilegeName.Length * UnicodeEncoding.CharSize); 
       userRights[0].MaximumLength = (UInt16)((privilegeName.Length + 1) * UnicodeEncoding.CharSize); 

       //add the right to the account 
       uint res = LsaAddAccountRights(policyHandle, sid, userRights, 1); 

       winErrorCode = LsaNtStatusToWinError((int)res); 

       LsaClose(policyHandle); 
      } 
      FreeSid(sid); 
     } 

     return winErrorCode; 
    } 
} 

Я поместил этот код в отдельном классе под названием LSAManager для удобства. Чтобы использовать этот код, просто позвоните:

string userName = "alex"; 
// Set "Logon As a Service" privilege (for example): 
if (LSAManager.SetRight(userName, "SeServiceLogonRight") != 0) 
{ 
    // handle error here 
} 
+0

Ух, потрясающе! Спасибо за ответ. – Giallo

+0

Добро пожаловать. Кстати, чтобы получить полный список ** Константы авторизации ** (например, _SeServiceLogonRight_), проверьте следующую [статью MSDN] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa375728 % 28v = vs.85% 29.aspx). –

Смежные вопросы