DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

現在のユーザーが管理者か調べる

現在のユーザーが管理者であるかどうか調べる方法を幾つか紹介します。なおこの記事を書くに当たり、以下のページを参考にさせていただきました。

アプリケーションを管理者として実行しているか調べる

アプリケーションを実行しているユーザーに管理者権限があるかを調べるには、以下のようにWindowsPrincipal.IsInRoleメソッドを使う方法があります。

VB.NET
コードを隠すコードを選択
''' <summary>
''' 現在アプリケーションを実行しているユーザーに管理者権限があるか調べる
''' </summary>
''' <returns>管理者権限がある場合はtrue。</returns>
Public Shared Function IsAdministrator() As Boolean
    '現在のユーザーを表すWindowsIdentityオブジェクトを取得する
    Dim wi As System.Security.Principal.WindowsIdentity = _
        System.Security.Principal.WindowsIdentity.GetCurrent()
    'WindowsPrincipalオブジェクトを作成する
    Dim wp As New System.Security.Principal.WindowsPrincipal(wi)
    'Administratorsグループに属しているか調べる
    Return wp.IsInRole( _
        System.Security.Principal.WindowsBuiltInRole.Administrator)
End Function
C#
コードを隠すコードを選択
/// <summary>
/// 現在アプリケーションを実行しているユーザーに管理者権限があるか調べる
/// </summary>
/// <returns>管理者権限がある場合はtrue。</returns>
public static bool IsAdministrator()
{
    //現在のユーザーを表すWindowsIdentityオブジェクトを取得する
    System.Security.Principal.WindowsIdentity wi =
        System.Security.Principal.WindowsIdentity.GetCurrent();
    //WindowsPrincipalオブジェクトを作成する
    System.Security.Principal.WindowsPrincipal wp =
        new System.Security.Principal.WindowsPrincipal(wi);
    //Administratorsグループに属しているか調べる
    return wp.IsInRole(
        System.Security.Principal.WindowsBuiltInRole.Administrator);
}

上のコードではWindowsIdentity.GetCurrentメソッドを使用してWindowsPrincipalオブジェクトを作成していますが、Thread.CurrentPrincipalプロパティを使用する方法もあります。MSDNの「方法 : WindowsPrincipal プロジェクトを作成する」によると、WindowsIdentity.GetCurrentメソッドの方法は1回だけ検証を行なう場合に使用し、Thread.CurrentPrincipalプロパティを使った方法は繰り返して検証を行なう場合にオーバーヘッドが少なくて済むということです。

VB.NET
コードを隠すコードを選択
''' <summary>
''' 現在アプリケーションを実行しているユーザーに管理者権限があるか調べる
''' </summary>
''' <returns>管理者権限がある場合はtrue。</returns>
Public Shared Function IsAdministrator2() As Boolean
    'プリンシパルポリシーを設定する
    System.AppDomain.CurrentDomain.SetPrincipalPolicy( _
        System.Security.Principal.PrincipalPolicy.WindowsPrincipal)
    'WindowsPrincipalオブジェクトを作成する
    Dim wp As System.Security.Principal.WindowsPrincipal = _
        DirectCast(System.Threading.Thread.CurrentPrincipal,  _
            System.Security.Principal.WindowsPrincipal)
    'Administratorsグループに属しているか調べる
    Return wp.IsInRole( _
        System.Security.Principal.WindowsBuiltInRole.Administrator)
End Function
C#
コードを隠すコードを選択
/// <summary>
/// 現在アプリケーションを実行しているユーザーに管理者権限があるか調べる
/// </summary>
/// <returns>管理者権限がある場合はtrue。</returns>
public static bool IsAdministrator2()
{
    //プリンシパルポリシーを設定する
    System.AppDomain.CurrentDomain.SetPrincipalPolicy(
        System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
    //WindowsPrincipalオブジェクトを作成する
    System.Security.Principal.WindowsPrincipal wp =
        (System.Security.Principal.WindowsPrincipal)
        System.Threading.Thread.CurrentPrincipal;
    //Administratorsグループに属しているか調べる
    return wp.IsInRole(
        System.Security.Principal.WindowsBuiltInRole.Administrator);
}

UACが有効で、管理者に昇格しているか調べる

上記のコードでは、UACが有効の時、ユーザーが管理者としてログオンしていたとしても、昇格していないのであれば、Falseが返されます。

UACが有効になっており、ユーザーが管理者に昇格しているか、いないかを調べるには、GetTokenInformation関数を使う方法があります。GetTokenInformationを使ってTOKEN_ELEVATION_TYPEを取得し、これがTokenElevationTypeFullであれば昇格しており、TokenElevationTypeLimitedであれば昇格していません。TokenElevationTypeDefaultであれば標準ユーザーか、UACが無効になっています。

以下にGetTokenInformationを使ってTOKEN_ELEVATION_TYPEを取得する例を示します。

VB.NET
コードを隠すコードを選択
'Imports System.Runtime.InteropServices

<DllImport("advapi32.dll", SetLastError:=True)> _
Public Shared Function GetTokenInformation(ByVal TokenHandle As IntPtr, _
    ByVal TokenInformationClass As TOKEN_INFORMATION_CLASS, _
    ByVal TokenInformation As IntPtr, _
    ByVal TokenInformationLength As UInteger, _
    ByRef ReturnLength As UInteger) As Boolean
End Function

Public Enum TOKEN_INFORMATION_CLASS
    TokenUser = 1
    TokenGroups
    TokenPrivileges
    TokenOwner
    TokenPrimaryGroup
    TokenDefaultDacl
    TokenSource
    TokenType
    TokenImpersonationLevel
    TokenStatistics
    TokenRestrictedSids
    TokenSessionId
    TokenGroupsAndPrivileges
    TokenSessionReference
    TokenSandBoxInert
    TokenAuditPolicy
    TokenOrigin
    TokenElevationType
    TokenLinkedToken
    TokenElevation
    TokenHasRestrictions
    TokenAccessInformation
    TokenVirtualizationAllowed
    TokenVirtualizationEnabled
    TokenIntegrityLevel
    TokenUIAccess
    TokenMandatoryPolicy
    TokenLogonSid
    MaxTokenInfoClass
End Enum

Public Enum TOKEN_ELEVATION_TYPE
    TokenElevationTypeDefault = 1
    TokenElevationTypeFull
    TokenElevationTypeLimited
End Enum

''' <summary>
''' 昇格トークンの種類を取得する
''' </summary>
''' <returns>昇格トークンの種類を示すTOKEN_ELEVATION_TYPE。
''' 取得に失敗した時でもTokenElevationTypeDefaultを返す。</returns>
Public Shared Function GetTokenElevationType() As TOKEN_ELEVATION_TYPE
    Dim returnValue As TOKEN_ELEVATION_TYPE = _
        TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault

    'Windows Vista以上か確認
    If Environment.OSVersion.Platform <> PlatformID.Win32NT OrElse _
        Environment.OSVersion.Version.Major < 6 Then
        Return returnValue
    End If

    Dim tet As TOKEN_ELEVATION_TYPE = _
        TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault
    Dim returnLength As UInteger = 0
    Dim tetSize As UInteger = CUInt(Marshal.SizeOf(CInt(tet)))
    Dim tetPtr As IntPtr = Marshal.AllocHGlobal(CInt(tetSize))
    Try
        'アクセストークンに関する情報を取得
        If GetTokenInformation( _
            System.Security.Principal.WindowsIdentity.GetCurrent().Token, _
            TOKEN_INFORMATION_CLASS.TokenElevationType, _
            tetPtr, tetSize, returnLength) Then
            '結果を取得
            returnValue = CType(Marshal.ReadInt32(tetPtr), TOKEN_ELEVATION_TYPE)
        End If
    Finally
        '解放する
        Marshal.FreeHGlobal(tetPtr)
    End Try

    Return returnValue
End Function
C#
コードを隠すコードを選択

//using System.Runtime.InteropServices;

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool GetTokenInformation(IntPtr TokenHandle,
    TOKEN_INFORMATION_CLASS TokenInformationClass,
    IntPtr TokenInformation,
    uint TokenInformationLength,
    out uint ReturnLength);

public enum TOKEN_INFORMATION_CLASS
{
    TokenUser = 1,
    TokenGroups,
    TokenPrivileges,
    TokenOwner,
    TokenPrimaryGroup,
    TokenDefaultDacl,
    TokenSource,
    TokenType,
    TokenImpersonationLevel,
    TokenStatistics,
    TokenRestrictedSids,
    TokenSessionId,
    TokenGroupsAndPrivileges,
    TokenSessionReference,
    TokenSandBoxInert,
    TokenAuditPolicy,
    TokenOrigin,
    TokenElevationType,
    TokenLinkedToken,
    TokenElevation,
    TokenHasRestrictions,
    TokenAccessInformation,
    TokenVirtualizationAllowed,
    TokenVirtualizationEnabled,
    TokenIntegrityLevel,
    TokenUIAccess,
    TokenMandatoryPolicy,
    TokenLogonSid,
    MaxTokenInfoClass
}

public enum TOKEN_ELEVATION_TYPE
{
    TokenElevationTypeDefault = 1,
    TokenElevationTypeFull,
    TokenElevationTypeLimited
}

/// <summary>
/// 昇格トークンの種類を取得する
/// </summary>
/// <returns>昇格トークンの種類を示すTOKEN_ELEVATION_TYPE。
/// 取得に失敗した時でもTokenElevationTypeDefaultを返す。</returns>
public static TOKEN_ELEVATION_TYPE GetTokenElevationType()
{
    TOKEN_ELEVATION_TYPE returnValue =
        TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault;

    //Windows Vista以上か確認
    if (Environment.OSVersion.Platform != PlatformID.Win32NT ||
        Environment.OSVersion.Version.Major < 6)
    {
        return returnValue;
    }

    TOKEN_ELEVATION_TYPE tet =
        TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault;
    uint returnLength = 0;
    uint tetSize = (uint)Marshal.SizeOf((int)tet);
    IntPtr tetPtr = Marshal.AllocHGlobal((int)tetSize);
    try
    {
        //アクセストークンに関する情報を取得
        if (GetTokenInformation(
            System.Security.Principal.WindowsIdentity.GetCurrent().Token,
            TOKEN_INFORMATION_CLASS.TokenElevationType,
            tetPtr, tetSize, out returnLength))
        {
            //結果を取得
            returnValue = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(tetPtr);
        }
    }
    finally
    {
        //解放する
        Marshal.FreeHGlobal(tetPtr);
    }

    return returnValue;
}

このメソッドを使って昇格しているか調べる例を以下に示します。

VB.NET
コードを隠すコードを選択
Dim tet As TOKEN_ELEVATION_TYPE = GetTokenElevationType()
If tet = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault Then
    Console.WriteLine("UACが無効になっているか、標準ユーザーです")
ElseIf tet = TOKEN_ELEVATION_TYPE.TokenElevationTypeFull Then
    Console.WriteLine("UACが有効になっており、昇格しています")
ElseIf tet = TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited Then
    Console.WriteLine("UACが有効になっており、昇格していません")
End If
C#
コードを隠すコードを選択
TOKEN_ELEVATION_TYPE tet = GetTokenElevationType();
if (tet == TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault)
{
    Console.WriteLine("UACが無効になっているか、標準ユーザーです");
}
else if (tet == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull)
{
    Console.WriteLine("UACが有効になっており、昇格しています");
}
else if (tet == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited)
{
    Console.WriteLine("UACが有効になっており、昇格していません");
}

現在のユーザーが管理者グループのメンバーか調べる

.NET Framework 3.5からは、Principal.IsMemberOfメソッドによってユーザーが指定されたグループのメンバーであるか調べることができます。これを使って、現在のユーザーがローカル管理者グループのメンバーであるかを調べる例を示します。この方法であれば、昇格していなくても、管理者かどうかの確認ができます。なお、参照設定に「System.DirectoryServices.AccountManagement.dll」を追加することが必要です。

VB.NET
コードを隠すコードを選択
'Imports System.DirectoryServices.AccountManagement

''' <summary>
''' 現在のユーザーがローカルAdministratorsグループのメンバーか調べる
''' </summary>
''' <returns>メンバーであればtrue。</returns>
Public Shared Function IsAdministratorsMember() As Boolean
    'ローカルコンピュータストアのPrincipalContextオブジェクトを作成する
    Using pc As New PrincipalContext(ContextType.Machine)
        '現在のユーザーのプリンシパルを取得する
        Dim up As UserPrincipal = UserPrincipal.Current
        'ローカルAdministratorsグループを探す
        '"S-1-5-32-544"はローカルAdministratorsグループを示すSID
        Dim gp As GroupPrincipal = GroupPrincipal.FindByIdentity(pc, "S-1-5-32-544")
        'グループのメンバーであるか調べる
        Return up.IsMemberOf(gp)
    End Using
End Function
C#
コードを隠すコードを選択
//using System.DirectoryServices.AccountManagement;

/// <summary>
/// 現在のユーザーがローカルAdministratorsグループのメンバーか調べる
/// </summary>
/// <returns>メンバーであればtrue。</returns>
public static bool IsAdministratorsMember()
{
    //ローカルコンピュータストアのPrincipalContextオブジェクトを作成する
    using (PrincipalContext pc = new PrincipalContext(ContextType.Machine))
    {
        //現在のユーザーのプリンシパルを取得する
        UserPrincipal up = UserPrincipal.Current;
        //ローカルAdministratorsグループを探す
        //"S-1-5-32-544"はローカルAdministratorsグループを示すSID
        GroupPrincipal gp = GroupPrincipal.FindByIdentity(pc, "S-1-5-32-544");
        //グループのメンバーであるか調べる
        return up.IsMemberOf(gp);
    }
}

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • 「???を参照に追加します」の意味が分からないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。