In my C# application, I need to check if the current user is a member of the Administrators group. It needs to be compatible with both Windows XP and Windows 7.
Currently, I am using the following code:
bool IsAdministrator
{
get
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
The problem is that this method returns false if the application is run on Windows 7 with UAC turned on as a non-elevated Administrator. How can I determine if the user is an Administrator even if the application is run as a non-elevated Administrator?
There is a Win32 API GetTokenInformation
that can be used to check the current token. If the returned token is a split token, it probably is an administrator user that is running i non elevated mode.
GetTokenInformation
has an output parameter tokenInformation
which takes one of three values:
A value of TokenElevantionTypeLimited indicates that the user is running with a split token with limited privileges. When elevated the TokenElevationTypeFull value is returned. Non-admin user has a value of TokenElevationTypeDefault.
There is a complete code example for C# at http://www.davidmoore.info/2011/06/20/how-to-check-if-the-current-user-is-an-administrator-even-if-uac-is-on/
For any VB.NET people (I know you're out there ...), here's a version that I concocted from various sources and is, I think, optimized to determine whether the current user (including elevated) is in a defined Administrators group, machine or domain, with or without UAC enabled. (Lots of credit to other posts here and elsewhere for this one!)
Firstly, it uses a static null-able Boolean to retain the Administrator status because, although the basic check is quick, the full test can take tens of seconds, so you only want to do it once - if at all if you can help it.
Secondly, it errs on the side of the basic test being incorrect/false, which is usually the case if the user is AD-administered or if the local machine has UAC enabled. So if it can decide a user is an Administrator, it will.
Thirdly, you can add or remove criteria from the AuthorizationGroups as you see fit but the ones included cover most situations.
Lastly, if anything goes wrong, you'll get False; if you want an error, you can have one, but personally I don't see the point.
Function IsAdministrator() 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 'to get a domain context first ...
Domain.GetComputerDomain()
oContext = New PrincipalContext(ContextType.Domain)
Catch
'... if it fails, fall through to a machine context
End Try
If oContext Is Nothing Then oContext = New PrincipalContext(ContextType.Machine)
Dim oPrincipal As UserPrincipal = UserPrincipal.FindByIdentity(oContext, WindowsIdentity.GetCurrent().Name)
If oPrincipal IsNot Nothing Then
bResult = oPrincipal.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))
End If
End If
End If
Catch
bResult = False
End Try
Return bResult.GetValueOrDefault(False)
End Function
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With