/// <summary> /// Checks whether the primary access token of the process belongs to a user account that is a member of the local Administrator group, even if it currently is not elevated. /// </summary> /// <returns> /// True if the primary access token of the process belongs to a user account that is a member of the Administrators group; false otherwise. /// </returns> public static bool IsUserInAdminGroup() { // Default token's received aren't impersonation tokens, we are looking for an impersonation token. bool isImpersonationToken = false; // Open the access token of the current process. SafeTokenHandle processToken; if (!AdvApi32.OpenProcessToken(Process.GetCurrentProcess().Handle, (uint)(TokenAccessLevels.Query | TokenAccessLevels.Duplicate), out processToken)) { MarshalHelper.ThrowLastWin32ErrorException(); } // Starting from Vista linked tokens are supported which need to be checked. if (EnvironmentHelper.VistaOrHigher) { // Determine token type: limited, elevated, or default. int marshalSize = sizeof(AdvApi32.TokenElevationType); var elevationTypeHandle = SafeUnmanagedMemoryHandle.FromNewlyAllocatedMemory(marshalSize); if (!AdvApi32.GetTokenInformation(processToken, AdvApi32.TokenInformationClass.TokenElevationType, elevationTypeHandle.DangerousGetHandle(), marshalSize, out marshalSize)) { MarshalHelper.ThrowLastWin32ErrorException(); } var tokenType = (AdvApi32.TokenElevationType)Marshal.ReadInt32(elevationTypeHandle.DangerousGetHandle()); // If limited, get the linked elevated token for further check. if (tokenType == AdvApi32.TokenElevationType.TokenElevationTypeLimited) { // Get the linked token. marshalSize = IntPtr.Size; var linkedTokenHandle = SafeUnmanagedMemoryHandle.FromNewlyAllocatedMemory(marshalSize); if (!AdvApi32.GetTokenInformation(processToken, AdvApi32.TokenInformationClass.TokenLinkedToken, linkedTokenHandle.DangerousGetHandle(), marshalSize, out marshalSize)) { MarshalHelper.ThrowLastWin32ErrorException(); } processToken = new SafeTokenHandle(Marshal.ReadIntPtr(linkedTokenHandle.DangerousGetHandle())); isImpersonationToken = true; // Linked tokens are already impersonation tokens. } } // We need an impersonation token in order to check whether it contains admin SID. if (!isImpersonationToken) { SafeTokenHandle impersonatedToken; if (!AdvApi32.DuplicateToken(processToken, AdvApi32.SecurityImpersonationLevel.SecurityIdentification, out impersonatedToken)) { MarshalHelper.ThrowLastWin32ErrorException(); } processToken = impersonatedToken; } // Check if the token to be checked contains admin SID. var identity = new WindowsIdentity(processToken.DangerousGetHandle()); var principal = new WindowsPrincipal(identity); return(principal.IsInRole(WindowsBuiltInRole.Administrator)); }