I need to get the Parent property of network adapter device from c# program
Please find the image here
Tried below code but the property "Parent" is not available
List mappingIpDeviceIds = new List();
Console.WriteLine("Reading Id and IP address...");
ManagementObjectSearcher adapters = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionStatus = 2");
foreach (ManagementObject item in adapters.Get())
{
foreach (ManagementObject setting in item.GetRelated("Win32_NetworkAdapterConfiguration"))
{
var relationships = setting.GetRelationships();
var name = setting["Caption"].ToString();
string[] defaultIPGateway = (string[])setting.GetPropertyValue("DefaultIPGateway");
string[] compterips = (string[])setting.GetPropertyValue("IPAddress");
string dhcpserver = (string)setting.GetPropertyValue("DHCPServer");
foreach (ManagementObject win32PnPEntity in item.GetRelated("Win32_PnPEntity"))
{
var x = win32PnPEntity.Properties;
foreach (var prop in x)
{
Console.WriteLine("::: PROPERTY NAME ::: " + prop.Name);
Console.WriteLine("::: PROPERTY VALUE ::: " + prop.Value);
}
}
MappingIpDeviceId mappingIpDeviceId = new MappingIpDeviceId();
string deviceid = (string)item.GetPropertyValue("PNPDeviceID");
string deviceid1 = (string)item.GetPropertyValue("ProductName");
string[] devicenames = deviceid.Split(new Char[] { '\\' });
foreach (string dn in devicenames)
{
mappingIpDeviceId.OWLIP = dhcpserver;
mappingIpDeviceId.ComputerIP = compterips[0];
mappingIpDeviceId.DeviceId = dn;
mappingIpDeviceIds.Add(mappingIpDeviceId);
}
}
}
There are two ways you can refer to:
Using PowerShell command Get-PnpDeviceProperty: Get-PnpDeviceProperty -KeyName 'DEVPKEY_Device_Parent' -InstanceId 'xxxxxxxxxxxxxxxx'
Use CM_Get_Parent. "Determining the Parent of a Device".
Related
I have a utility that reads the status of MicrosoftBizTalk Server resources .. specifically the ReceiveLocation component. My problem is that the program is submitting multiple entries of each item i.e each item in the data returned is being multiplied by 25 such that instead of persisting only 5 rows the data being persisted is 125. So for example instead of having just 1 row for my first row returned i have 25.
This is my program :
public List<BizTalk> GetBizTalkServicesStatistics()
{
List<BizTalk> model = new List<BizTalk>();
try
{
//Create the WMI search object.
ManagementObjectSearcher Searcher = new ManagementObjectSearcher();
ConnectionOptions options = new ConnectionOptions
{
Username = "+username+",
Password = "+password+",
Authority = "+domain+"
};
var server = "+server+";
// create the scope node so we can set the WMI root node correctly.
ManagementScope Scope = new ManagementScope("\\\\" + server + "\\root\\MicrosoftBizTalkServer", options);
Searcher.Scope = Scope;
// Build a Query to enumerate the MSBTS_ReceiveLocation instances if an argument
// is supplied use it to select only the matching RL.
//if (args.Length == 0)
SelectQuery Query = new SelectQuery();
Query.QueryString = "SELECT * FROM MSBTS_ReceiveLocation";
// else
//Query.QueryString = "SELECT * FROM MSBTS_ReceiveLocation WHERE Name = '" + args[0] + "'";
// Set the query for the searcher.
Searcher.Query = Query;
// Execute the query and determine if any results were obtained.
ManagementObjectCollection QueryCol = Searcher.Get();
// Use a bool to tell if we enter the for loop
// below because Count property is not supported
bool ReceiveLocationFound = false;
// Enumerate all properties.
foreach (ManagementBaseObject envVar in QueryCol)
{
// There is at least one Receive Location
ReceiveLocationFound = true;
PropertyDataCollection envVarProperties = envVar.Properties;
foreach (PropertyData envVarProperty in envVarProperties)
{
BizTalk bizTalk = new BizTalk();
bizTalk.Name = Convert.ToString(envVar["Name"]);
bizTalk.TransportType = Convert.ToString(envVar["AdapterName"]);
bizTalk.Uri = Convert.ToString(envVar["InboundTransportURL"]);
bizTalk.Status = Convert.ToString(envVar["Name"]);
bizTalk.ReceiveHandler = Convert.ToString(envVar["HostName"]);
bizTalk.ReceivePort = Convert.ToString(envVar["ReceivePortName"]);
bizTalk.RunDate = DateTime.Now;
bizTalk.ApplicationId = 24;
bizTalk.ServerId = 8;
bizTalk.InstanceName = "FBCZOP";
model.Add(bizTalk);
}
}
if (!ReceiveLocationFound)
{
Console.WriteLine("No receive locations found matching the specified name.");
}
}
catch (Exception excep)
{
ExceptionLogger.SendErrorToText(excep);
}
return model;
}
Save Function
public void SaveStatistics(BizTalk entity)
{
List<BizTalk> ServerInfo = new List<BizTalk>();
ServerInfo = GetBizTalkServicesStatistics();
foreach (var di in ServerInfo)
{
entity.RunDate = di.RunDate;
entity.Name = di.Name;
entity.Status = di.Status;
entity.Uri = di.Uri;
entity.InstanceName = di.InstanceName;
entity.ReceivePort = di.ReceivePort;
entity.TransportType= di.TransportType;
entity.RunDate = DateTime.Now;
entity.ReceiveHandler = di.ReceiveHandler;
entity.ServerId = entity.ServerId;
entity.ApplicationId = entity.ApplicationId;
appEntities.BizTalk.Add(entity);
appEntities.SaveChanges();
}
}
When i step through the code variable envVarProperties shows record count as 125 under envVarProperties << ResultsView :
Link 1
whilst QueryCol variable shows count of 5 :
Link 2
It looks like you're iterating an extra time in your GetBizTalkServicesStatistics() method.
Remove the foreach loop that starts with foreach (PropertyData envVarProperty in envVarProperties). This is looping through each property the object has (All 25 properties) for each instance (5 instances)... 25 * 5 = 125 values you are retrieving. You only want to iterate through your instances and pull the properties you want. That way you end up with 5 objects in your model object.
I'd suggest maybe something like this (untested because I don't have BizTalk)
public List<BizTalk> GetBizTalkServicesStatistics()
{
List<BizTalk> model = new List<BizTalk>();
try
{
//Create the WMI search object.
ConnectionOptions options = new ConnectionOptions
{
Username = "+username+",
Password = "+password+",
Authority = "+domain+"
};
var server = "+server+";
// create the scope node so we can set the WMI root node correctly.
ManagementScope Scope = new ManagementScope("\\\\" + server + "\\root\\MicrosoftBizTalkServer", options);
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, new ObjectQuery("SELECT * FROM MSBTS_ReceiveLocation"));
// Enumerate all properties.
foreach (ManagementObject instance in Searcher.Get())
{
{
BizTalk bizTalk = new BizTalk();
bizTalk.Name = instance.Properties["Name"]?.Value?.ToString();
bizTalk.TransportType = instance.Properties["AdapterName"]?.Value?.ToString();
bizTalk.Uri = instance.Properties["InboundTransportURL"]?.Value?.ToString();
bizTalk.Status = instance.Properties["Name"]?.Value?.ToString();
bizTalk.ReceiveHandler = instance.Properties["HostName"]?.Value?.ToString();
bizTalk.ReceivePort = instance.Properties["ReceivePortName"]?.Value?.ToString();
bizTalk.RunDate = DateTime.Now;
bizTalk.ApplicationId = 24;
bizTalk.ServerId = 8;
bizTalk.InstanceName = "FBCZOP";
model.Add(bizTalk);
}
}
// Determine
if (model.Count == 0)
{
Console.WriteLine("No receive locations found matching the specified name.");
}
}
catch (Exception excep)
{
ExceptionLogger.SendErrorToText(excep);
}
return model;
}
Also, this can be simplified more if you remove the connectionoptions (unless you are hard coding credentials which is highly advised against). If you are just using the identity of the executing user, that data is not needed.
-Paul
You are adding the same entity 25 times and overwrite its properties by reference. You need to initialize a new entity inside your loop:
foreach (var di in ServerInfo)
{
var entity = new BizTalk();
entity.RunDate = di.RunDate;
entity.Name = di.Name;
entity.Status = di.Status;
entity.Uri = di.Uri;
entity.InstanceName = di.InstanceName;
entity.ReceivePort = di.ReceivePort;
entity.TransportType= di.TransportType;
entity.RunDate = DateTime.Now;
entity.ReceiveHandler = di.ReceiveHandler;
entity.ServerId = entity.ServerId;
entity.ApplicationId = entity.ApplicationId;
appEntities.BizTalk.Add(entity);
appEn.SaveChanges();
}
}
As you don't show the code where "SaveStatistics" is called it's not sure this will fix your complete problem, but it's at least one method that does not do what you expect it to do.
So I am trying to get Description information from Win32_SystemDriver into a RichTextBox, but I am not able to do that because it only displays the last result from the query. As you can see bellow I tried to build an array but it does not work.
ObjectQuery query8 = new ObjectQuery(
"SELECT * FROM Win32_SystemDriver");
ManagementObjectSearcher searcher8 =
new ManagementObjectSearcher(scope, query8);
foreach (ManagementObject queryObj in searcher8.Get())
{
string[] arrTeamMembers = new string[] { queryObj["Description"].ToString() };
foreach (var item in arrTeamMembers)
{
richTextBox1.Text = item;
}
}
Do you have any ideia how can I display all the info listing into the RichTextBox?
Try following :
List<string> arrTeamMembers = new List<string>();
foreach (ManagementObject queryObj in searcher8.Get())
{
arrTeamMembers.Add(queryObj["Description"].ToString());
}
richTextBox1.Text = string.Join(",", arrTeamMembers);
Your approach is ok. There is one thing which you missed: richTextBox1.Text is a so-called property that stores a string. Now the reason why it shows you only the last driver is that you set this property to a new value for each driver you have in your array. So for the first driver it sets it to "driverA" and for the second to "driverB". What you are looking for is the += operator --> richTextBox1.Text += item;. If you want to add spaces between the drivers you can do something like richTextBox1.Text += $" {item}";. This way you have a leading whitespace but formating is personal preference.
Please note that ManagementObjectSearcher are IDisposable and therefore should be disposed.
ObjectQuery query8 = new ObjectQuery("SELECT * FROM Win32_SystemDriver");
using (ManagementObjectSearcher searcher8 = new ManagementObjectSearcher(scope, query8))
{
List<string> arrTeamMembers = new List<string>();
foreach (ManagementObject queryObj in searcher8.Get())
{
arrTeamMembers.Add(queryObj["Description"].ToString());
}
richTextBox1.Text = string.Join(Environment.NewLine, arrTeamMembers);
}
var query8 = new ObjectQuery("SELECT * FROM Win32_SystemDriver");
var searcher8 = new ManagementObjectSearcher(scope, query8);
var strbuilder = new StringBuilder();
foreach (var queryObj in searcher8.Get())
strbuilder.AppendLine($"{queryObj["Description"].ToString()}");
richTextBox1.Text = strbuilder.ToString();
How to get a list users in Task Manager with status?
I found only how to get a list of domain users
var usersSearcher = new ManagementObjectSearcher(#"SELECT * FROM Win32_UserAccount");
var users = usersSearcher.Get();
You can try this code to get the list of users:
var usersSearcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_UserAccount");
var managementObjects = usersSearcher.Get();
List<string> result = new List<string>();
foreach (ManagementObject item in managementObjects)
{
foreach (var pr in item.Properties)
{
if (pr.Name == "Caption")
{
result.Add(pr.Value?.ToString());
}
}
}
var users = result.Distinct().ToList();
Also you may try this:
var usersSearcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Process");
var managementObjects = usersSearcher.Get();
List<string> allUsers = new List<string>();
foreach (ManagementObject obj in managementObjects)
{
string[] argList = new string[] { string.Empty, string.Empty };
int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
if (returnVal == 0)
{
// return DOMAIN\user
allUsers.Add(argList[1] + "\\" + argList[0]);
}
}
var result = allUsers.Distinct().ToList();
I'm trying to enumerate all existing groups on my local machine.
That's what I tried using wmi :
string _class = "Win32_GroupUser";
string namespace = "\\\\.\\ROOT\\cimv2";
ManagementClass _class = new ManagementClass(namespace + ":" + class );
foreach (ManagementObject _object in _class.GetInstances())
{
richTextBox1.AppendText((_object["GroupComponent"].ToString()));
}
Output example :
\DESKTOP-2MSGC9J\root\cimv2:Win32_Group.Domain="DESKTOP-2MSGC9J",Name="Utilisateurs
du journal de performances"
In this output only the group name Name="Utilisateurs du journal de performances" is important to me.
Is a way to do a wmi query that only return that element in this _object ?
Another foreach with _object maybe.
I find a dirty way using substring after getting my object from wmi.
foreach (ManagementObject _object in _class.GetInstances())
{
string groups = _object["GroupComponent"].ToString();
int i = groups.LastIndexOf('=') + 1;
string groupsName = groups.Substring(i);
richTextBox1.AppendText(groupsName + "\r\n\r\n");
}
I need to get the power settings for a machine using WMI. I am using the MSDN Link to get the required values. I need specific values from the list returned. The following C# code does this:
string NamespacePath = #"root\cimv2\power";
string powerPlanClass = "Win32_powerplan";
string powerSettingClass = "Win32_PowerSettingDataIndex";
ManagementClass powerPlanManagementClass = new ManagementClass(NamespacePath + ":" + powerPlanClass);
ManagementObject powerPlanManagementObject = null;
foreach (ManagementObject managementObject in powerPlanManagementClass.GetInstances())
{
if (managementObject["IsActive"] != null && Boolean.Parse(managementObject["IsActive"].ToString()))
{
powerPlanManagementObject = managementObject;
}
}
Dictionary<string, PowerSetting> powerItems = new Dictionary<string, PowerSetting>()
{
{"AC", new PowerSetting() },
{"DC", new PowerSetting() }
};
foreach (ManagementObject oObject in powerPlanManagementObject.GetRelated(powerSettingClass))
{
var instanceId = oObject["instanceId"];
string[] powerSourceSettings = instanceId.ToString().Split(new string[] { #"\" }, StringSplitOptions.RemoveEmptyEntries);
var powerSourceType = powerSourceSettings[2];
ManagementObjectCollection managementObjects = oObject.GetRelated("Win32_PowerSetting");
var elementName = string.Empty;
foreach (var managementObject in managementObjects)
{
elementName = managementObject["ElementName"].ToString();
}
var indexValue = uint.Parse(oObject["settingindexvalue"].ToString());
if (elementName.Equals("Hibernate after",StringComparison.OrdinalIgnoreCase))
{
if (powerSourceType.Equals("AC", StringComparison.Ordinal))
{
powerItems["AC"].HibernateAfter = indexValue;
}
}
}
Note the match to the string "Hibernate after". This works on a machine with locale en-us but does not work with a different locale. Is there any other way to get the WMI property independent of the machine's locale?
Probably you can use GUID in the InstanceID of Win32_PowerSetting class instead of ElementName. In my machine, it is Microsoft:PowerSetting\{9d7815a6-7ee4-497e-8888-515a05f02364}. Although I couldn't find official document, this GUID, 9d7815a6-7ee4-497e-8888-515a05f02364 seems to be common for some Windows versions and locales as the identifier for "hibernate after" or "hibernate idle".