Testing application for Administrative Running Rights Testing application for Administrative Running Rights windows windows

Testing application for Administrative Running Rights


C#:

using System.Security.Principal;...var identity = WindowsIdentity.GetCurrent();var principal = new WindowsPrincipal(identity);bool isElevated = principal.IsInRole(WindowsBuiltInRole.Administrator);

VB.Net:

Imports System.Security.Principal...Dim identity = WindowsIdentity.GetCurrent()Dim principal = new WindowsPrincipal(identity)Dim isElevated as Boolean = principal.IsInRole(WindowsBuiltInRole.Administrator)


After a fair bit of poking around, I found that the most common solutions to this question return false negatives if the user's UAC is set to anything but Off.

My solution these days is to do this:

Imports System.Security.PrincipalImports System.DirectoryServices.AccountManagementImports System.DirectoryServices.ActiveDirectoryImports Microsoft.VisualBasic.ApplicationServices''' <summary>Checks whether the current user is belongs to any Administrators groups.</summary>''' <param name="AuthGroups">Optional. A flag indicating whether to use GetAuthorizationGroups instead of the - faster - GetGroups. Default=true.</param>''' <returns>True if the user belongs to an Administrators group, false otherwise.</returns>Public Function IsAdministrator(    Optional ByVal AuthGroups As Boolean = True) As Boolean    Static bResult As Boolean? = Nothing    Try        If bResult Is Nothing Then            bResult = New WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator)            If Not bResult Then                Dim oContext As PrincipalContext = Nothing                Try 'Domain check first                    Domain.GetComputerDomain()                    oContext = New PrincipalContext(ContextType.Domain)                Catch                    'Fall through to machine check                End Try                If oContext Is Nothing Then oContext = New PrincipalContext(ContextType.Machine)                'Dim oPrincipal As UserPrincipal = UserPrincipal.FindByIdentity(oContext, WindowsIdentity.GetCurrent().Name) ' Don't use - slow                Using oSearchUser As Principal = New UserPrincipal(oContext)                    oSearchUser.SamAccountName = WindowsIdentity.GetCurrent().Name                    Using oSearcher As PrincipalSearcher = New PrincipalSearcher(oSearchUser)                        Using oUser As Principal = oSearcher.FindOne()                            If oUser IsNot Nothing Then                                If AuthGroups Then                                    bResult = CType(oUser, UserPrincipal).GetAuthorizationGroups().Any(Function(p) _                                        p.Sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid) OrElse                                        p.Sid.IsWellKnown(WellKnownSidType.AccountDomainAdminsSid) OrElse                                        p.Sid.IsWellKnown(WellKnownSidType.AccountAdministratorSid) OrElse                                        p.Sid.IsWellKnown(WellKnownSidType.AccountEnterpriseAdminsSid))                                Else                                    bResult = oUser.GetGroups().Any(Function(p) _                                        p.Sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid) OrElse                                        p.Sid.IsWellKnown(WellKnownSidType.AccountDomainAdminsSid) OrElse                                        p.Sid.IsWellKnown(WellKnownSidType.AccountAdministratorSid) OrElse                                        p.Sid.IsWellKnown(WellKnownSidType.AccountEnterpriseAdminsSid))                                End If                            End If                        End Using                    End Using                End Using            End If        End If    Catch        bResult = False    End Try    Return bResult.GetValueOrDefault(False)End Function

This method is a composite of a few other answers, so I only take credit for packaging it up into a function that will only ever run once and therefore if there is a bit of a delay due to the fall-through, you can probably hide it in start-up.

The AuthGroups argument gives you a choice of the more thorough, recursive AuthorizationGroups check (default) or the faster Groups check.