2013-02-26 3 views
1

Я пишу приложение, которое объединяет все записи журнала событий на каждом из нескольких разных серверов. Я могу получить журналы событий, перейдя в MachineName в EventLog.GetEventLogs. Это, как правило, терпят неудачу на каком-то этапе это пользователь не является локальным администратором на этой машине, поэтому я хотел бы, чтобы проверить на него загодя и перейти к следующему набору серверов, если это такПроверьте, является ли пользователь локальным администратором на внешнем компьютере

For Each svr As String In Servers 

    'TODO: check to see if they are a local administrator, else continue for 

    Dim logs As List(Of EventLog) = EventLog.GetEventLogs(svr).ToList 
    For Each log As EventLog In logs 
     LoadEachOSLogEntry(log) 
    Next 
Next 

Большинство решений, таких как here, проверяют только, является ли пользователь администратором на текущей исполняющей машине.

Dim user As WindowsIdentity = WindowsIdentity.GetCurrent() 
Dim principal As New WindowsPrincipal(user) 
Dim isAdmin As Boolean = principal.IsInRole(WindowsBuiltInRole.Administrator) 
+1

в сторону: не было бы проще просто справиться с случайным провалом? Вместо того, чтобы выполнять некоторые вызовы WMI на целевой машине и анализировать права этого пользователя. Это просто поражает меня как вопрос такого типа, как «как я могу узнать, могу ли я писать в файл?» ответ: «сделайте это и обработайте ошибки». – hometoast

+0

Я считаю, что обычно лучше всего справляться с легко устраняемыми ошибками до их возникновения. Я бы предпочел не брать на себя затраты на обработку исключения для почти каждого сервера в длинном списке серверов, если я могу проверить привилегии раньше времени. Кроме того, способ, которым я в настоящее время структурирован, я могу временно сохранить информацию о разрешении в моем списке серверов, поэтому вам не нужно дважды проверять вызов. Это сложнее сделать в блоке catch, где может возникнуть любое количество проблем, связанных с разрешениями. – KyleMit

+0

@Kyle: стоимость исключения на несколько порядков дешевле одного сетевого вызова. –

ответ

0

Я поделюсь частичным решением, но я не совсем доволен этим, так что если у кого есть что-нибудь лучше, я бы с радостью принять их ответ.

Следующая функция возвращает пользователя или не принадлежит к определенной группе пользователей (в моем случае "Administrators") на любом компьютере.

Imports System.DirectoryServices.AccountManagement 

Public Shared Function IsMemberOfGroup(userName As String, machineName As String, memberGroup as String) As Boolean 
    Dim isMember As Boolean = False 
    Using rootContext As New PrincipalContext(ContextType.Machine, machineName), _ 
      grp As GroupPrincipal = GroupPrincipal.FindByIdentity(rootContext, memberGroup), _ 
      usr As UserPrincipal = UserPrincipal.FindByIdentity(rootContext, IdentityType.SamAccountName, userName) 
     If grp IsNot Nothing AndAlso usr IsNot Nothing Then 
      ' Check if the user is a member of the group. 
      isMember = grp.GetMembers(True).Contains(usr) 
     Else 
      isMember = False 
     End If 
    End Using 
    Return isMember 
End Function 

caviat является то, что пользователь работает метод должен быть администратором, чтобы иметь право на эту информацию, установленной в PrincipalContext. Я надеялся, что приложение сможет определить, является ли пользователь, запускающий приложение, администратором.

Единственный способ сделать это супер полезно, чтобы назвать его и посмотреть, если он пришел с «Access Denied», подобно hometoast уже предложил, но это еще не чувствует себя супер «чистый»