In order to get information about Serial Port devices, with System.Management, we can do as described in Getting Serial Port Information:
using System;
using System.Management;
using System.Collections.Generic;
using System.Linq;
using System.IO.Ports;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
using (var searcher = new ManagementObjectSearcher
("SELECT * FROM WIN32_SerialPort"))
{
string[] portnames = SerialPort.GetPortNames();
var ports = searcher.Get().Cast<ManagementBaseObject>().ToList();
var tList = (from n in portnames
join p in ports on n equals p["DeviceID"].ToString()
select n + " - " + p["Caption"]).ToList();
tList.ForEach(Console.WriteLine);
}
// pause program execution to review results...
Console.WriteLine("Press enter to exit");
Console.ReadLine();
}
}
}
How can this be achieved using Microsoft.Management.Infrastructure, I haven't managed to find examples and the documentation isn't detailed enough.
It's quite similar:
Create a CimSession, where you specify the ComputerName (null for LocalHost) and a CimCredential object (passing the usual UserName and Password for authentication, is necessary). This reflects System.Management's ConnectionOption.
Use the CimSession's QueryInstances method to build the query, passing the namespace and the class. This reflects System.Management's SelectQuery and ManagementObjectSearcher
QueryInstances() returns an IEnumerble<CimInstance> objects (the good news is that no COM objects are returned here).
Get the Value of the CimInstanceProperties you care about.
As a note, you're skipping the ConnectionOption and EnumerationOptions in your WMI Query, which is not really good PERF-wise.
Your query can then be translated to:
using Microsoft.Management.Infrastructure;
using Microsoft.Management.Infrastructure.Options;
using (var session = CimSession.Create(null) {
var ports = session.QueryInstances(#"root\cimv2", "WQL", "SELECT * FROM WIN32_SerialPort");
string[] portnames = SerialPort.GetPortNames();
var tList = (from n in portnames
join p in ports on n equals p.CimInstanceProperties["DeviceID"].Value
select n + " - " + p.CimInstanceProperties["Caption"].Value);
}
I'm not sure why you use string[] portnames = SerialPort.GetPortNames(); here.
You can just use the CimProperties:
using (var session = CimSession.Create(null)) {
var ports = session.QueryInstances(#"root\cimv2", "WQL", "SELECT * FROM WIN32_SerialPort");
var portsDescriptions = ports.Select(p =>
$"{p.CimInstanceProperties["DeviceID"].Value} - {p.CimInstanceProperties["Caption"].Value}");
// If you actually need to materialize a List<T>...
portsDescriptions.ToList().ForEach(Console.WriteLine);
}
Unrelated, but could be useful: I suggest to build some methods to create a CimSession with more options. For example:
public static CimSession CreateSession(string computerName)
=> CreateSession(computerName, string.Empty, string.Empty, null);
public static CimSession CreateSession(string computerName, string domain, string userName, SecureString password)
{
if (string.IsNullOrEmpty(computerName) ||
computerName.Equals("localhost", StringComparison.InvariantCultureIgnoreCase)) {
computerName = null;
}
var option = new CimSessionOptions();
if (password != null && password.Length > 0) {
option.AddDestinationCredentials(
new CimCredential(PasswordAuthenticationMechanism.Default, domain, userName, password));
}
return CimSession.Create(computerName, option);
}
So, instead of:
var session = CimSession.Create(null);
You can call it as:
// LocalHost, default permissions
var session = CreateSession(null);
Or pass domain, Username and Password (as Char*), if needed.
Related
help me please deal with the problem.
I'm trying to get the user group with the following code. I run through the mono. The OS Windows data obtained normally (the account is not included in the domain). But when I start the same code on Linux get the error.
What do I need to do to obtain a normal result?
using System;
using System.Text;
using System.DirectoryServices;
using System.Runtime.InteropServices;
namespace ActiveDirectoryTest
{
class Program
{
private static void Main(string[] args)
{
try
{
DirectoryEntry de = new DirectoryEntry("LDAP://sub.domain.com","username#domain","password",AuthenticationTypes.None);
DirectorySearcher search = new DirectorySearcher(de);
search.ReferralChasing=ReferralChasingOption.All;
search.Filter = "(&(ObjectClass=user)(sAMAccountName=username))";
search.PropertiesToLoad.Add("sAMAccountName");
search.PropertiesToLoad.Add("memberOf");
StringBuilder groupNames = new StringBuilder();
var result = search.FindAll()[0];
int propertyCount = result.Properties["memberOf"].Count;
for (int propertyCounter = 0;
propertyCounter < propertyCount;
propertyCounter++)
{
var dn = (String) result.Properties["memberOf"][propertyCounter];
var equalsIndex = dn.IndexOf("=", 1);
var commaIndex = dn.IndexOf(",", 1);
if (-1 == equalsIndex)
{
Console.WriteLine("error parse");
}
groupNames.Append(dn.Substring((equalsIndex + 1),
(commaIndex - equalsIndex) - 1));
groupNames.Append("|");
}
Console.WriteLine(groupNames.ToString());
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine();
}
}
}
LdapException: (32) No Such Object LdapException: Server Message:
0000208D: NameErr: DSID-03100213, problem 2001 (NO_OBJECT), data 0,
best match of: '' Novell.Directory.Ldap.LdapException
This error is usually generated when the search base is not valid. When you are using clear-text LDAP (my example below uses SSL, but you can comment out the change the authentication type to System.DirectoryServices.AuthenticationTypes.None), you can grab a network capture between your application host and the LDAP server on port 389 and see the actual search that is being performed.
Per MS's documentation, you should be able to use LDAP://dc=company,dc=gTLD without specifying a specific domain controller. Because I needed my code to be functional with both Active Directory and pure LDAP servers, I use something like LDAP://DomainController.company.gTLD/ou=UserOU,dc=company,dc=gTLD where the LDAP hostname and search base is included.
The function I use for LDAP authentication:
protected string ldapAuthentication(string strLDAPServer, string strSuppliedUser, string strSuppliedPwd, string strSystemUID, string strSystemPwd, string strLDAPUserBase, string strUIDAttr){
strSuppliedUser = strSuppliedUser.Trim();
string strResults = "";
string strLDAPUserHost = strLDAPServer + strLDAPUserBase;
// Establish LDAP connection and bind with system ID
System.DirectoryServices.DirectoryEntry dirEntry = new System.DirectoryServices.DirectoryEntry();
dirEntry.Path = strLDAPUserHost;
dirEntry.Username = strSystemUID;
dirEntry.Password = strSystemPwd;
dirEntry.AuthenticationType = System.DirectoryServices.AuthenticationTypes.SecureSocketsLayer;
try
{
dirEntry.RefreshCache();
// Search directory for the user logging on
string strLDAPFilter = "(&(objectClass=user)(" + strUIDAttr + "=" + strSuppliedUser + "))";
System.DirectoryServices.DirectorySearcher ldapSearch = new System.DirectoryServices.DirectorySearcher(dirEntry);
ldapSearch.ServerTimeLimit = new TimeSpan(0, 0, 30);
ldapSearch.Filter = strLDAPFilter;
ldapSearch.SearchScope = System.DirectoryServices.SearchScope.Subtree;
System.DirectoryServices.SearchResultCollection searchResults = ldapSearch.FindAll();
if (searchResults.Count == 1){
...
This function is called like:
strInputResults = ldapAuthentication("LDAP://DomainController.company.gTLD/", strInputSuppliedUser, strInputSuppliedPwd, "SystemAccount#company.gTLD", "Syst3mP#s5w0rd", "ou=UserOU,dc=company,dc=gTLD","sAMAccountName");
I want to remove a Printer from a Windows account. This will be used via Citrix.
First I want to retrieve all printers that are installed for the user and then I want to remove a printer.
I am using the following code to do this.
This works on a normal PC. But when I use this via Citrix then it does not work.
Not all Printers are retrieved via this method. Also I cannot remove the Printer.
Does somebody know why?
What can I do to use this via Citrix?
What is different when using this via Citrix?
using System.Collections.Generic;
using System.Linq;
using System.Management;
namespace RemovePrinter
{
public class PrinterManager
{
public List<string> GetInstalledPrinters()
{
var managementScope = new ManagementScope(ManagementPath.DefaultPath);
managementScope.Connect();
var selectQuery = new SelectQuery {QueryString = #"SELECT * FROM Win32_Printer"};
var objectSearcher = new ManagementObjectSearcher(managementScope, selectQuery);
var ojectCollection = objectSearcher.Get();
return (from ManagementBaseObject item in ojectCollection select item["Name"].ToString()).ToList();
}
public bool DeletePrinter(string printerName)
{
var managementScope = new ManagementScope(ManagementPath.DefaultPath);
managementScope.Connect();
var selectQuery = new SelectQuery
{
QueryString = #"SELECT * FROM Win32_Printer WHERE Name = '" +
printerName.Replace("\\", "\\\\") + "'"
};
var ojectSearcher = new ManagementObjectSearcher(managementScope, selectQuery);
var ojectCollection = ojectSearcher.Get();
if (ojectCollection.Count == 0) return false;
foreach (var item in ojectCollection.Cast<ManagementObject>())
{
item.Delete();
return true;
}
return false;
}
}
}
ManagementObjectSearcher is a part of WMI API classes. By default these services are not enabled on Citrix and that is the reason why it does not work.
You need to have the right services installed as well have license to use those.
Check this out "http://support.citrix.com/article/ctx116423"
I'm pulling data off the Rally server at https://rally1.rallydev.com using C# and the Rally.RestAPI.dll. The server was recently upgraded to webservice v2.0 and I'm having some problems getting tasks for a user story. I know the way child collections are presented were changed in the API with the move to 2.0, but what I'm trying isn't working.
v2.0 removed the ability to return child collections in the same
response for performance reasons. Now fetching a collection will return
an object with the count and the url from which to get the collection
data.A separate request is needed to get to the elements of the
collection.
Here is the code that iterates over user story results, accesses "Tasks" collection on stories and issues a separate request to access individual Task attributes:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using Rally.RestApi;
using Rally.RestApi.Response;
namespace aRestApp_CollectionOfTasks
{
class Program
{
static void Main(string[] args)
{
//Initialize the REST API
RallyRestApi restApi;
restApi = new RallyRestApi("user#co.com", "secret", "https://rally1.rallydev.com", "v2.0");
//Set our Workspace and Project scopings
String workspaceRef = "/workspace/11111"; //please replace this OID with an OID of your workspace
String projectRef = "/project/22222"; //please replace this OID with an OID of your project
bool projectScopingUp = false;
bool projectScopingDown = true;
Request storyRequest = new Request("HierarchicalRequirement");
storyRequest.Workspace = workspaceRef;
storyRequest.Project = projectRef;
storyRequest.ProjectScopeUp = projectScopingUp;
storyRequest.ProjectScopeDown = projectScopingDown;
storyRequest.Fetch = new List<string>()
{
"Name",
"FormattedID",
"Tasks",
"Estimate"
};
storyRequest.Query = new Query("LastUpdateDate", Query.Operator.GreaterThan, "2013-08-01");
QueryResult queryStoryResults = restApi.Query(storyRequest);
foreach (var s in queryStoryResults.Results)
{
Console.WriteLine("----------");
Console.WriteLine("FormattedID: " + s["FormattedID"] + " Name: " + s["Name"]);
//Console.WriteLine("Tasks ref: " + s["Tasks"]._ref);
Request taskRequest = new Request(s["Tasks"]);
QueryResult queryTaskResult = restApi.Query(taskRequest);
if (queryTaskResult.TotalResultCount > 0)
{
foreach (var t in queryTaskResult.Results)
{
var taskEstimate = t["Estimate"];
var taskName = t["Name"];
Console.WriteLine("Task Name: " + taskName + " Estimate: " + taskEstimate);
}
}
else
{
Console.WriteLine("no tasks found");
}
}
}
}
}
I'm trying to get all users of a particular group in AD, then return a list of Employees as mapped to properties in my Employee class. I have:
My Filter is producing no results - what should it be?
Also, I tried the first solution here:
List of users in specific Active Directory Distribution Group, but I need details such as mobile, extension, etc. which I couldn't get with that method.
public static List<Employee> CreateEmployeeList(string department)
{
List<Employee> employees = new List<Employee>();
string filter = string.Format("(&(ObjectClass=person)(memberOf=CN={0},OU=Users & Groups,OU=Blah,DC=Blah,DC=Blah,DC=Blah))", department);
DirectoryEntry adRoot = new DirectoryEntry("LDAP://" + domain, null, null, AuthenticationTypes.Secure);
DirectorySearcher searcher = new DirectorySearcher(adRoot);
searcher.SearchScope = SearchScope.Subtree;
searcher.ReferralChasing = ReferralChasingOption.All;
searcher.Filter = filter;
SearchResultCollection results = searcher.FindAll();
foreach (SearchResult user in results)
{
// do whatever you need to do with the entry
if (user != null)
{
UserDirectoryEntry = user.GetDirectoryEntry();
string displayName = GetUserProperty("displayName");
string firstName = GetUserProperty("givenName");
string lastName = GetUserProperty("sn");
string email = GetUserProperty("mail");
string tel = GetUserProperty("telephonenumber");
string extension = GetUserProperty("ipphone");
string mobile = GetUserProperty("mobile");
string title = GetUserProperty("description");
employees.Add(new Employee{ FullName = displayName, FirstName = firstName, Surname = lastName, Email = email.ToLower(), Telephone = tel, Extension = extension, Mobile = mobile, JobTitle = title });
}
}
return employees;
}
using (var context = new PrincipalContext(ContextType.Domain, "domainName"))
{
using (var group = GroupPrincipal.FindByIdentity(context, "groupName"))
{
if (group == null)
{
MessageBox.Show("Group does not exist");
}
else
{
var users = group.GetMembers(true);
foreach (UserPrincipal user in users)
{
//user variable has the details about the user
}
}
}
}
This should return all Active Directory Users in a group.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
namespace ADQuery
{
class Program
{
static void Main(string[] args)
{
GetListOfAdUsersByGroup("domain", "group");
Console.ReadLine();
}
public static void GetListOfAdUsersByGroup(string domainName, string groupName)
{
DirectoryEntry entry = new DirectoryEntry("LDAP://DC=" + domainName + ",DC=com");
DirectorySearcher search = new DirectorySearcher(entry);
string query = "(&(objectCategory=person)(objectClass=user)(memberOf=*))";
search.Filter = query;
search.PropertiesToLoad.Add("memberOf");
search.PropertiesToLoad.Add("name");
System.DirectoryServices.SearchResultCollection mySearchResultColl = search.FindAll();
Console.WriteLine("Members of the {0} Group in the {1} Domain", groupName, domainName);
foreach (SearchResult result in mySearchResultColl)
{
foreach (string prop in result.Properties["memberOf"])
{
if (prop.Contains(groupName))
{
Console.WriteLine(" " + result.Properties["name"][0].ToString());
}
}
}
}
}
}
Good Luck!
The following code will search through nested domain local groups and/or global groups recursively to find users. You can modify this to look through any order of groups to suit what you need or to return any kind of group that you want.
// Set the list to return and get the group we are looking through.
List<UserPrincipal> list = new List<UserPrincipal>();
GroupPrincipal group = GroupPrincipal.FindByIdentity(new PrincipalContext(/* connection info here */), ((groupName.Length > 0) ? groupName : this.Properties.Name));
// For each member of the group add all Users.
foreach (Principal princ in group.Members)
{
/*
To change what you are looking for or how you are looking for it,
simply change some of the following conditions to match what you want.
*/
// If this member is a User then add them.
if (princ.StructuralObjectClass == "user")
{
list.Add(UserPrincipal.FindByIdentity(new PrincipalContext(/* connection info here */), princ.Name);
}
// If we are looking recursively and this member is a GL_Group then get the Users in it and add them.
if (recursive && (princ.StructuralObjectClass == "group") && (((GroupPrincipal)princ).GroupScope == GroupScope.Global))
{
list.AddRange(this.GetUsers(true, princ.Name));
}
}
return list;
Building on the example by Dalton, here's concise code to get group's usernames:
static SortedSet<string> GetUsernames(string domainName, string groupName) {
using (var pc = new PrincipalContext(ContextType.Domain, domainName))
using (var gp = GroupPrincipal.FindByIdentity(pc, groupName))
return gp == null ? null : new SortedSet<string>(
gp.GetMembers(true).Select(u => u.SamAccountName));
}
In this post I wrote something working in an ActiveDirectory 2003 ans 2008 R2. I use Microsoft LDAP_MATCHING_RULE_IN_CHAIN. This service use DirectoryServices. Be careful in this code as there is a double search.
But you can also do it using Managing Directory Security Principals in the .NET Framework 3.5. You can read this other post. You have to get a GroupPrincipal and you are looking for Members property. It also exists other entries in StackOverflow.
How can I use WMIUserID, WMIPassword, WMIAlternateCredentials using C#?
Also, is it possible to get remote computer's Administrator-password?
Please try to explain with examples.
Thanks.
Her is some example code
using System;
using System.Text;
using System.Threading;
using Microsoft.Management.Infrastructure;
using Microsoft.Management.Infrastructure.Options;
using System.Security;
namespace SMAPIQuery
{
class Program
{
static void Main(string[] args)
{
string computer = "Computer_B";
string domain = "DOMAIN";
string username = "AdminUserName";
string plaintextpassword;
Console.WriteLine("Enter password:");
plaintextpassword = Console.ReadLine();
SecureString securepassword = new SecureString();
foreach (char c in plaintextpassword)
{
securepassword.AppendChar(c);
}
// create Credentials
CimCredential Credentials = new CimCredential(PasswordAuthenticationMechanism.Default,
domain,
username,
securepassword);
// create SessionOptions using Credentials
WSManSessionOptions SessionOptions = new WSManSessionOptions();
SessionOptions.AddDestinationCredentials(Credentials);
// create Session using computer, SessionOptions
CimSession Session = CimSession.Create(computer, SessionOptions);
var allVolumes = Session.QueryInstances(#"root\cimv2", "WQL", "SELECT * FROM Win32_Volume");
var allPDisks = Session.QueryInstances(#"root\cimv2", "WQL", "SELECT * FROM Win32_DiskDrive");
// Loop through all volumes
foreach (CimInstance oneVolume in allVolumes)
{
// Show volume information
if (oneVolume.CimInstanceProperties["DriveLetter"].ToString()[0] > ' ' )
{
Console.WriteLine("Volume ‘{0}’ has {1} bytes total, {2} bytes available",
oneVolume.CimInstanceProperties["DriveLetter"],
oneVolume.CimInstanceProperties["Size"],
oneVolume.CimInstanceProperties["SizeRemaining"]);
}
}
// Loop through all physical disks
foreach (CimInstance onePDisk in allPDisks)
{
// Show physical disk information
Console.WriteLine("Disk {0} is model {1}, serial number {2}",
onePDisk.CimInstanceProperties["DeviceId"],
onePDisk.CimInstanceProperties["Model"].ToString().TrimEnd(),
onePDisk.CimInstanceProperties["SerialNumber"]);
}
Console.ReadLine();
}
}
}