Getting a list of users on a windows machine? - c#

I'm trying to return, or in this example print out each user that has been created on a windows machine, I don't really care about the windows users like "defaultuser0", but if anyone can tell me how I can exclude them aswell, that would be great, but back to the main question.
I have this code below, and it works to a certain degree. Output I received was this.
\PC_NAME\root\cimv2:Win32_UserAccount.Domain="PC_NAME",Name="admin"
\PC_NAME\root\cimv2:Win32_UserAccount.Domain="PC_NAME",Name="Administrator"
\PC_NAME\root\cimv2:Win32_UserAccount.Domain="PC_NAME",Name="DefaultAccount"
\PC_NAME\root\cimv2:Win32_UserAccount.Domain="PC_NAME",Name="defaultuser0"
\PC_NAME\root\cimv2:Win32_UserAccount.Domain="PC_NAME",Name="Guest"
\PC_NAME\root\cimv2:Win32_UserAccount.Domain="HEAVEN",Name="WDAGUtilityAccount"
Now I understand that this is natural behaviour of my code. Is there a way I can get the actual usernames, without including the domain and all the other directory code?
Here is the code I'm using.
var searcher = new ManagementObjectSearcher(new SelectQuery("Win32_UserAccount"));
foreach (var managementBaseObject in searcher.Get())
{
Console.WriteLine(((ManagementObject) managementBaseObject).ToString());
}

Instead of letting the compiler choose the base type ManagementBaseObject, you can specify that you only want all ManagementObjectinstances in the collection.
foreach (ManagementObject instance in searcher.Get())
This way you do not need to cast explicitely again.
To access any property of such a ManagementObject use the [string] access notation. The string has to be the property name, in your case it would be Name.
Console.WriteLine("Username: {0}", instance["Name"]);
The full code would be:
var searcher = new ManagementObjectSearcher(new SelectQuery("Win32_UserAccount"));
foreach (ManagementObject instance in searcher.Get())
{
var strUsername = instance["Name"];
Console.WriteLine("Username: {0}", strUsername);
}

Related

C# Application: Get Network Shares On Another Computer

First of all, apologies if this doesn't make sense, and/or it has already been asked (although searching didn't find anything).
I have an application which sets default printers for our end users but I would like to expand it by also making it able to install printers from a remote machine as well.
What I need to do is on Form_Load populate a Combo Box with all network shares from the print server.
I am shooting in the dark and am wondering if anyone can shed some light.
I believe this works.
This isnt my code originally but I cant remember where it came from.
using System.Management;
private void btnGetPrinters_Click(object sender, EventArgs e) {
// Use the ObjectQuery to get the list of configured printers.
ObjectQuery oquery = new ObjectQuery("SELECT * FROM Win32_Printer");
ManagementObjectSearcher mosearcher = new ManagementObjectSearcher(oquery);
ManagementObjectCollection moc = mosearcher.Get();
foreach (ManagementObject mo in moc)
{
PropertyDataCollection pdc = mo.Properties;
foreach (System.Management.PropertyData pd in pdc)
{
if ((bool)mo["Network"])
{
cmbPrinters.Items.Add(mo[pd.Name]);
}
}
}
}

How to list all local computer user profiles in a combo box?

I need to enumerate all user profiles on a local computer and list them in a combo box. Any special accounts need to be filtered out. I'm only concerned about actual user profiles on the computer where the app is running. I have done some searching but I haven't found a clear answer posted anywhere. I did find some code that might work but SelectQuery and ManagementObjectSearcher are displaying errors in VS and I'm not sure what I need to do to make this work.
using System.Management;
SelectQuery query = new SelectQuery("Win32_UserAccount");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
foreach (ManagementObject envVar in searcher.Get())
{
Console.WriteLine("Username : {0}", envVar["Name"]);
}
By saying "SelectQuery and ManagementObjectSearcher are displaying errors" I guess you didn't reference the System.Management dll.
You should right click References in your solution and add System.Management.
Then, with your using statement, the errors should disappear.
Anyway, including the error next time will assist everyone to help you :)
The mentioned code is great but when I tried on a machine connected to a Active Directory Domain all the usernames where returned for the domain. I was able to tweak the code a bit to only return the users that actually have a local directory on the current machine. If a better C# developer can refactor the code to make it cleaner - please help!
var localDrives = Environment.GetLogicalDrives();
var localUsers = new List<string>();
var query = new SelectQuery("Win32_UserAccount") { Condition = "SIDType = 1 AND AccountType = 512" };
var searcher = new ManagementObjectSearcher(query);
foreach (ManagementObject envVar in searcher.Get())
{
foreach (string drive in localDrives)
{
var dir = Path.Combine(String.Format("{0}Users", drive), envVar["name"].ToString());
if (Directory.Exists(dir))
{
localUsers.Add(envVar["name"].ToString());
}
}
}
Once you have the localUsers variable you can set this as the data source to your ComboBox control of our choice.

Getting the Driver Details the same as Driver File Details Window

I'm trying to duplicate the exact file listing below which is found under "Driver Details" in Device Manager, i've come up with the below code but i'm unable to display this list. Any help is awesome.
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPSignedDriver");
foreach (ManagementObject obj in searcher.Get())
{
if(obj["DriverProviderName"] != null)
foreach (PropertyData prop in obj.Properties)
{
File.AppendAllText(#"C:\driverusers.txt", prop.Name +"\t" +prop.Value+"\n");
Console.WriteLine("{0}: {1}", prop.Name, prop.Value);
}
}
Take a look at this, someone was doing something very similar.
http://www.dreamincode.net/forums/topic/63149-devices-in-c%23/
The first thing I can think of is to go hunt for it in the registry. (I think they even state this in the article above).
Also, check this out:
http://www.codeproject.com/Articles/17973/How-To-Get-Hardware-Information-CPU-ID-MainBoard-I

How to get network adapter index?

From code I want to force a Windows machine to use a specific network adapter for all connections to a specific IP address.
I plan to do so by using the ROUTE ADD command line tool, but this requires that I know in advance the network adapters' index number (as it must be given to the ROUTE ADD command).
QUESTION: How can I programmatically retrieve a network adapter's index, given I know its name?
I'm aware that ROUTE PRINT shows me the information I need (the index numbers of all network adapters present), but there must be a way to get that information programmatically too (C#)?
Note, that I don't like parsing the text output from ROUTE PRINT, as the text format may change with different Windows versions.
You can obtain the interface index of your network adapter
by using the .Net NetworkInterface (and related) classes.
Here is a code example:
static void PrintInterfaceIndex(string adapterName)
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
Console.WriteLine("IPv4 interface information for {0}.{1}",
properties.HostName, properties.DomainName);
foreach (NetworkInterface adapter in nics)
{
if (adapter.Supports(NetworkInterfaceComponent.IPv4) == false)
{
continue;
}
if (!adapter.Description.Equals(adapterName, StringComparison.OrdinalIgnoreCase))
{
continue;
}
Console.WriteLine(adapter.Description);
IPInterfaceProperties adapterProperties = adapter.GetIPProperties();
IPv4InterfaceProperties p = adapterProperties.GetIPv4Properties();
if (p == null)
{
Console.WriteLine("No information is available for this interface.");
continue;
}
Console.WriteLine(" Index : {0}", p.Index);
}
}
Then just call this function with the name of your network adapter:
PrintInterfaceIndex("your network adapter name");
You can also obtain the InterfaceIndex of your network adapter
by using the Win32_NetworkAdapter WMI class. The Win32_NetworkAdapter class
contains a property called InterfaceIndex.
So, to retrieve the InterfaceIndex for a network adapter with a given
name, use the following code:
ManagementScope scope = new ManagementScope("\\\\.\\ROOT\\cimv2");
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_NetworkAdapter WHERE Description='<Your Network Adapter name goes here>'");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
using (ManagementObjectCollection queryCollection = searcher.Get())
{
foreach (ManagementObject mo in queryCollection)
{
Console.WriteLine("InterfaceIndex : {0}, name {1}", mo["InterfaceIndex"], mo["Description"]);
}
}
}
If you do not want to use WMI you could also use the Win32 API function
GetAdaptersInfo in combination with the IP_ADAPTER_INFO struct.
You will find an example here pinvoke.net.
have you looked into using C#'s system.net.networkinformation interface?
http://msdn.microsoft.com/en-us/library/system.net.networkinformation.networkinterface.getallnetworkinterfaces.aspx
I'm not familiar with ROUTE ADD, but you can theoretically marry up information from one with the other.

finding the actual executable and path associated to a windows service using c#

I am working on an installation program for one of my company's product. The product can be installed multiple times and each installation represents a separate windows service. When users upgrade or reinstall the program, I would like to look up the services running, find the services that belong to the product, and then find the executable file and its path for that service. Then use that information to find which one of the services the user wishes to upgrade/replace/install/etc. In my code example below, I see the service name, description, etc, but don't see the actual filename or path. Could someone please tell me what I'm missing? Thank you in advance!
The code I have is as follows:
ServiceController[] scServices;
scServices = ServiceController.GetServices();
foreach (ServiceController scTemp in scServices)
{
if (scTemp.ServiceName == "ExampleServiceName")
{
Console.WriteLine();
Console.WriteLine(" Service : {0}", scTemp.ServiceName);
Console.WriteLine(" Display name: {0}", scTemp.DisplayName);
ManagementObject wmiService;
wmiService = new ManagementObject("Win32_Service.Name='" + scTemp.ServiceName + "'");
wmiService.Get();
Console.WriteLine(" Start name: {0}", wmiService["StartName"]);
Console.WriteLine(" Description: {0}", wmiService["Description"]);
}
}
I might be wrong but the ServiceController class doesn't provide that information directly.
So as suggested by Gene - you will have to use the registry or WMI.
For an example of how to use the registry, refer to http://www.codeproject.com/Articles/26533/A-ServiceController-Class-that-Contains-the-Path-t
If you decide to use WMI (which I would prefer),
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Service");
ManagementObjectCollection collection = searcher.Get();
foreach (ManagementObject obj in collection)
{
string name = obj["Name"] as string;
string pathName = obj["PathName"] as string;
...
}
You can decide to wrap the properties you need in a class.
the interface has changed since #sidprasher answered, try:
var collection = searcher.Get().Cast<ManagementBaseObject>()
.Where(mbo => mbo.GetPropertyValue("StartMode")!=null)
.Select(mbo => Tuple.Create((string)mbo.GetPropertyValue("Name"), (string)mbo.GetPropertyValue("PathName")));

Categories