Check if current user is a domain administrator
In business apps, you often need to detect whether the current user is a member of the Domain Admins group—say, to show advanced options only to users with elevated rights. Here’s how to do it elegantly in C#.
Step 1: Use IsInRole
The WindowsPrincipal.IsInRole(...)
method lets you check if the current user belongs to a given Windows role. It accepts either a built-in enum value or a SecurityIdentifier
(SID) and returns a bool
.
Tip: For best performance, use the
SecurityIdentifier
overload.
var wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
return wp.IsInRole(WindowsBuiltInRole.Administrator);
That works well—for local admin roles, that is. But if you want to detect domain-level admin groups, you need something more domain-aware.
Step 2: Use a Well-Known SID for Domain Admins
Enter WellKnownSidType.AccountDomainAdminsSid
—a ready-to-use SID type representing the Domain Admins group. But you still need to add your domain’s SID as the second parameter:
var wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
var sid = new SecurityIdentifier(WellKnownSidType.AccountDomainAdminsSid, null);
return wp.IsInRole(sid);
Looks easy… until you realize: using null
doesn’t always cut it—your domain’s actual SID is needed to fully resolve the group membership.
Step 3: Retrieve Your Domain SID Realistically
To build a proper SecurityIdentifier
for domain-level roles, you need to fetch your domain’s SID at runtime:
var domain = Domain.GetDomain(
new DirectoryContext(
DirectoryContextType.Domain,
IPGlobalProperties.GetIPGlobalProperties().DomainName
)
);
using (DirectoryEntry de = domain.GetDirectoryEntry())
{
var domainSidBytes = (byte[])de.Properties["objectSid"].Value;
var domainSid = new SecurityIdentifier(domainSidBytes, 0);
// Build the full Domain Admins SID
var domainAdminsSid = new SecurityIdentifier(
WellKnownSidType.AccountDomainAdminsSid,
domainSid);
var wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
return wp.IsInRole(domainAdminsSid);
}
That wraps it up—now you’re checking for actual membership in the Domain Admins group, not just a generic role that might miss your domain context.
Step 4: Wrap It Up in an Extension Method
To make this easier to use across your project, you can wrap the logic in a handy extension method:
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Net.NetworkInformation;
using System.Security.Principal;
public static class SecurityExtensions
{
public static bool IsDomainAdmin(this WindowsIdentity identity)
{
var wp = new WindowsPrincipal(identity);
// First, check local admin
if (wp.IsInRole(WindowsBuiltInRole.Administrator))
return true;
// Otherwise, check Domain Admins
var domain = Domain.GetDomain(
new DirectoryContext(
DirectoryContextType.Domain,
IPGlobalProperties.GetIPGlobalProperties().DomainName
)
);
using (DirectoryEntry de = domain.GetDirectoryEntry())
{
var domainSidBytes = (byte[])de.Properties["objectSid"].Value;
var domainSid = new SecurityIdentifier(domainSidBytes, 0);
var domainAdminsSid = new SecurityIdentifier(
WellKnownSidType.AccountDomainAdminsSid,
domainSid);
return wp.IsInRole(domainAdminsSid);
}
}
}
Usage
if (WindowsIdentity.GetCurrent().IsDomainAdmin())
{
Console.WriteLine("You are a domain admin!");
}
else
{
Console.WriteLine("Standard user detected.");
}
Summary & When to Use It
Scenario | Recommended Method |
---|---|
Check for local admin permissions | IsInRole(WindowsBuiltInRole.Administrator) — simple and performant |
Check for domain admin permissions | Build domain-aware SecurityIdentifier using well-known SID and domain SID fetch |
Need top-level admin functionality gating | Use the full domain SID-based check for accuracy and security |
Heads-up: On Vista and above, Windows uses two security tokens for users—one elevated and one restricted. Be sure you’re running elevated if your logic depends on admin rights—otherwise, IsInRole
checks could return false
even for actual Admin users (unless explicitly elevated).
Happy coding—and may your admin-only features stay private! ::contentReference[oaicite:0]{index=0}

Resistance is futile.