I've tagged this question with C#
because is part of .NET
and is known that some people can programming and understand without problems both VB.NET
and C#
as one, and I should not have problems to translate the C#
instructions to VB.NET
then I would be happy with a solution written in one of those languages.
I would like to specify an username in this function to retrieve if it's an Admin or not, what changes I should do?
MsgBox(UserIsAdmin("Elektro"))
' ByVal UserName as String or other needed object.
Public Function UserIsAdmin(ByVal UserName As XXXX) As Boolean
Dim Identity As Security.Principal.WindowsIdentity =
Security.Principal.WindowsIdentity.FromUserName(UserName)
Return New Security.Principal.WindowsPrincipal(Identity).
IsInRole(Security.Principal.WindowsBuiltInRole.Administrator)
End Function
PS: Ofcourse the FromUserName
method does not exist.
UPDATE
I'm just trying @meziantou approach but I always get an exception about the username structure or about the network entry is not found, but, anyways, this is not exactlly what I'm looking for (I mean specify a domain or computername or whatever else that is not done automated by the function).
Public Class Form
Private Sub Test() Handles MyBase.Shown
' Things that I've tried:
MsgBox(UserIsAdmin("Administrador")) ' Username
MsgBox(UserIsAdmin("Administrador@127.0.0.1")) ' Username@LocalHost
MsgBox(UserIsAdmin(Security.Principal.WindowsIdentity.GetCurrent().Name)) ' DomainName\Username
MsgBox(UserIsAdmin("Administrador@ELEKTRO")) ' Username@DomainName
MsgBox(UserIsAdmin(Security.Principal.WindowsIdentity.GetCurrent.User.Value)) ' The SID
End Sub
''' <summary>
''' Determines whether an user is an Administrator.
''' </summary>
''' <returns><c>true</c> if the user is an Administrator, <c>false</c> otherwise.</returns>
Public Function UserIsAdmin(Optional ByVal UserName As String = String.Empty) As Boolean
Dim Identity As Security.Principal.WindowsIdentity =
If(Not String.IsNullOrEmpty(UserName),
New Security.Principal.WindowsIdentity(UserName),
Security.Principal.WindowsIdentity.GetCurrent())
Return New Security.Principal.WindowsPrincipal(Identity).
IsInRole(Security.Principal.WindowsBuiltInRole.Administrator)
End Function
End Class
UPDATE 2
I'm trying the @Frinavale approach but I'm not able to adapt this code to retrieve the information that I'm interested to.
Imports System.DirectoryServices.AccountManagement
Imports System.Security.Principal
Public Class Form1
Private Sub Test() Handles MyBase.Shown
Dim pContext As PrincipalContext = New PrincipalContext(ContextType.Machine)
Dim pUsers As Principal = New UserPrincipal(pContext)
Dim pSearcher As PrincipalSearcher = New PrincipalSearcher(pUsers)
For Each User As Principal In pSearcher.FindAll()
For Each Group As Principal In User.GetGroups
' Result of 'Administrators' (in Spanish): 'Administradores',
' so this is not efficient to compare.
MsgBox(Group.Name)
Next
' Any of these works:
' It throws an exception because
' i'm not passing the expected parameter for a WindowsIdentity.
MsgBox(UserIsAdmin(User.Name))
' MsgBox(UserIsAdmin(User.UserPrincipalName))
' MsgBox(UserIsAdmin(User.DistinguishedName))
' MsgBox(UserIsAdmin(User.SamAccountName))
Next User
End Sub
Public Function UserIsAdmin(ByVal User As String) As Boolean
Using Identity As New WindowsIdentity(User)
Return New WindowsPrincipal(Identity).IsInRole(WindowsBuiltInRole.Administrator)
End Using
End Function
End Class
You can use the GroupPrincipal Class to retrieve all users that are part of the administrator group. Once you have all the members, you can determine if the user is in the group by comparing the member's name to the user name provided.
For example:
Public Function UserIsAdmin(ByVal userName As String) As Boolean
Dim groupName As String = "administrators" '<--You can localize this'
Dim isAdmin As Boolean
Using context As PrincipalContext = New PrincipalContext(ContextType.Machine)
Dim gfilter As GroupPrincipal = GroupPrincipal.FindByIdentity(context, groupName)
If gfilter IsNot Nothing Then
Dim members = gfilter.GetMembers
For Each member In members
If String.Compare(member.Name, userName, True) = 0 Then
isAdmin = True
End If
Next
End If
End Using
Return isAdmin
End Function
I know that you mentioned that the group's name is localized (which hasn't occurred for me because I'm using an US English operating system/environment). In that case I recommend that you look into the topic of Globalization (store store a localized version of "administrators" into resource files with the key being "administrators" and then retrieve the appropriate text for "administrator" based on the culture that you are working in)