2012-09-07 7 views
5

Come posso verificare da C# se un account utente locale (ovvero l'account amministratore locale) è attivo?Come effettuare il check in C# se l'account utente è attivo

Quello che in realtà desidero è una sostituzione C# per l'output "Account Active" = "Sì" (o "No") dal comando "net user Administrator".

Ho paura che questa domanda assomigli a un duplicato su this, ma non so cosa passare per il parametro per l'oggetto DirectoryDirectory root. Ho provato cose diverse come "ldap: //" + Environment.MachineName, "ldap: //127.0.0.1", "WinNT: //" + Environment.MachineName, ma nessuno di loro ha funzionato. Ricevo un'eccezione generata dalla chiamata searcher.FindAll() in tutti e tre i casi.

+0

quello eccezione vuoi arrivare? – BlackICE

+0

Con "ldap: //" + Environment.MachineName Ricevo una COMException con messaggio "Il server non è operativo." e ErrorCode = -2147016646. Lo stesso con "ldap: //127.0.0.1". – candritzky

+0

Con "WinNT: //" + Environment.MachineName Ricevo un NotSupportedException con messaggio "Il provider non supporta la ricerca e non può cercare WinNT: // ." – candritzky

risposta

5
class Program 
{ 
    static void Main(string[] args) 
    { 

     // Create the context for the principal object. 
     PrincipalContext ctx = new PrincipalContext(ContextType.Machine); 

     UserPrincipal u = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "Administrator"); 
     Console.WriteLine(String.Format("Administrator is enable: {0}", u.Enabled)); 

    } 
} 
+0

Grazie, anche questo funziona. Ma la chiamata FindByIdentity a volte richiede alcuni secondi prima che restituisca un risultato. Quindi, sebbene sia un buon codice, non è la soluzione migliore dal punto di vista delle prestazioni. – candritzky

+0

Ho notato anche questo, ma penso che ci sia un sovraccarico che apre la connessione o qualcosa del genere, perché quando ho fatto query successive erano molto veloci. – BlackICE

1

È possibile eseguire una query di Win32_UserAccount

Questo è boilerplate quale codice WMI creatore di MS sputa fuori come riferimento WMI;

using System; 
using System.Management; 
using System.Windows.Forms; 

namespace WMISample 
{ 
    public class MyWMIQuery 
    { 
     public static void Main() 
     { 
      try 
      { 
       ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT Disabled FROM Win32_UserAccount WHERE name = 'alexk'"); 

       foreach (ManagementObject queryObj in searcher.Get()) 
       { 
        Console.WriteLine("-----------------------------------"); 
        Console.WriteLine("Win32_UserAccount instance"); 
        Console.WriteLine("-----------------------------------"); 
        Console.WriteLine("Disabled: {0}", queryObj["Disabled"]); 
        Console.ReadKey(); 
       } 
      } 
      catch (ManagementException e) 
      { 
       MessageBox.Show("An error occurred while querying for WMI data: " + e.Message); 
      } 
     } 
    } 
} 

(mi piacerebbe collego lo strumento ma come al solito i link MSDN sono morti)

+0

L'ha fatto! Ho dovuto aggiungere "dominio = '" + Environment.MachineName + "" "alla query WMI per limitare i risultati agli account utente locali, ma poi funziona. Molte grazie! – candritzky

0

This non è proprio la stessa cosa ma usano DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("WinNT://{0}/{1}", computerName, username)); Vorrei che aiuto?

+0

No, non funziona. Restituisce un set di risultati vuoto. – candritzky

1

Prova questo.

var server = "YOURMACHINENAME"; 
var username = "Guest"; 
var de = new DirectoryEntry {Path = "WinNT://" + server + ",computer"}; 
var result = de.Children 
    .Cast<DirectoryEntry>() 
    .First<DirectoryEntry>(d => d.SchemaClassName == "User" && d.Properties["Name"].Value.ToString() == username); 

var flags = (int)result.Properties["UserFlags"].Value; 
var disabled = (flags & 2) == 2; 
+0

Funziona perfettamente. Grazie! – candritzky

0

Considerando che è un utente locale, è necessario chiamare l'API Win32 funcion NetGetUserInfo per ottenere quello che ti serve.

L'esempio in pinvoke.net è quasi quello che ti serve, tuttavia è necessario modificare il parametro del livello per 2 per ottenere la neccesary info

+0

Grazie. Questo potrebbe anche funzionare. Non l'ho ancora provato. Immagino tu ti stia riferendo al campo USER_INFO_2.usri2_flags (UF_ACCOUNTDISABLE). Anche se è meglio evitare P/Invoke e attaccare con una pura soluzione C# WMI o LDAP. – candritzky

Problemi correlati