Retrieving properties from a complex SQL query in C# - c#

I am querying an SCCM database for package and application properties. What it seems like is that if I use a simple query, I can view and access the properties. On a more complex query where I am assigning variable names to keep the properties separate I cannot.
In the example code below, the query for packages will print out those properties as expected. In the query for applications, all it seems to know about is either AL or DT for the name and the value comes back as a ManagementBaseObject. In fact, the code as posted will crash every time on printing out those property values.
Very confusing, appreciate any input to get this working.
using System;
using System.Management;
namespace Application
{
public class MainApplication
{
static void Main(string[] args)
{
ManagementObjectCollection packages = GetPackages();
ManagementObjectCollection applications = GetApplications();
// * Works! *
foreach (var package in packages)
{
Console.WriteLine("Package Name: {0} ", package.Properties["PackageName"].Value.ToString());
Console.WriteLine("Package ID: {0} ", package.Properties["PackageID"].Value.ToString());
Console.WriteLine("Setup Command: {0} ", package.Properties["CommandLine"].Value.ToString());
}
// * Does not work! *
foreach (var application in applications)
{
Console.WriteLine("Package Name: {0} ", application.Properties["AL.LocalizedDisplayName"].Value.ToString());
Console.WriteLine("Package ID: {0} ", application.Properties["DT.ContentID"].Value.ToString());
Console.WriteLine("Setup Command: {0} ", application.Properties["DT.LocalizedDescription"].Value.ToString());
}
}
private static ManagementObjectCollection GetPackages()
{
String queryString = "SELECT PackageName,PackageID,CommandLine,Comment FROM SMS_Program WHERE Comment LIKE '%LISTMANUAL%' ORDER BY PackageName";
ObjectQuery query = new ObjectQuery(queryString);
ManagementScope scope = new ManagementScope("\\\\somebox.somedomain.com\\root\\sms\\site_DC1");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection objectCollection = searcher.Get();
Console.WriteLine(objectCollection.Count);
return objectCollection;
}
private static ManagementObjectCollection GetApplications()
{
String queryString = "SELECT DT.LocalizedDisplayName,DT.LocalizedDescription,DT.AppModelName,DT.ContentID,AL.LocalizedDisplayName,AL.ModelName FROM SMS_DeploymentType AS DT JOIN SMS_ApplicationLatest AS AL on AL.ModelName=DT.AppModelName JOIN SMS_PackageToContent AS PTC on PTC.ContentUniqueID = DT.ContentID WHERE DT.IsLatest='TRUE' AND DT.LocalizedDescription LIKE '%LISTMANUAL%' ORDER BY AL.LocalizedDisplayName";
ObjectQuery query = new ObjectQuery(queryString);
ManagementScope scope = new ManagementScope("\\\\somebox.somedomain.com\\root\\sms\\site_DC1");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection objectCollection = searcher.Get();
Console.WriteLine(objectCollection.Count);
return objectCollection;
}
}
}

Related

populate combobox with WMI query using C#

Can someone help me with this problem.I'm trying to populate combobox with the value from WMI query. But I don't know how to do it. Googled to find the solution but to no avail.
private void Form_Load1(object sender, EventArgs e)
{
ManagementScope oScope = new ManagementScope("\\root\\cimv2");
ObjectQuery oQuery = new ObjectQuery("select DisplayName from Win32_Service");
ManagementObjectSearcher oSearcher = new ManagementObjectSearcher(oScope, oQuery);
ManagementObjectCollection oCol = oSearcher.Get();
foreach (ManagementObject col in oCol)
{
String displayName = col["DisplayName"].ToString();
comboBox1.Items.Add(displayName);
}
I change to foreach loop but it displays all the properties value. How to choose 'DisplayName' instead? Thanks

How to get Battery Health Using C#

I'm trying to get two values, DesignCapacity and FullChargeCacity, but they are not returning a value.
I'm using the code below:
public static bool CheckBattery()
{
bool _testResult = false;
string computer = ".";
try
{
ManagementScope scp = new ManagementScope(#"\\" + computer + #"\root\cimv2");
scp.Connect();
SelectQuery sql = new SelectQuery("CIM_Battery");
ManagementObjectSearcher mos = new ManagementObjectSearcher(scp,sql);
ManagementObjectCollection moc = mos.Get();
List<string> resultList = new List<string>();
foreach (ManagementObject o in moc)
{
foreach (PropertyData property in o.Properties)
{
resultList.Add( property.Name + ":" +property.Value);
}
File.WriteAllLines("bat.txt", resultList.ToArray());
//UInt16 availability = (UInt16)o["Availability"];
//resultList.Add("Availability," + availability.ToString());
//UInt16 batterystatus = (UInt16)o["BatteryStatus"];
//resultList.Add("BatteryStatus," + batterystatus.ToString());
//string status = (string)o["Status"];
//resultList.Add("Status," + status);
//UInt32 Desigcap = (UInt32)o["DesignCapacity"];
}
}
catch (Exception ex)
{
string errr = ex.Message;
}
return _testResult;
}
How Can I avoid to get null values in this properties? In fact iterating the objects im getting this information:
Availability:2
BatteryRechargeTime:
BatteryStatus:2
Caption:Internal Battery
Chemistry:2
ConfigManagerErrorCode:?
ConfigManagerUserConfig:?
CreationClassName:Win32_Battery
Description:Internal Battery
DesignCapacity:?
DesignVoltage:17119
DeviceID:3338SANYO AL12A32
ErrorCleared:?
ErrorDescription:?
EstimatedChargeRemaining:100
EstimatedRunTime:71582788
ExpectedBatteryLife:
ExpectedLife:?
FullChargeCapacity:?
InstallDate:?
LastErrorCode:
MaxRechargeTime:
Name:AL12A32
PNPDeviceID:
PowerManagementCapabilities:System.UInt16[]
PowerManagementSupported:False
SmartBatteryVersion:
Status:OK
StatusInfo:?
SystemCreationClassName:Win32_ComputerSystem
SystemName:MX02L180
TimeOnBattery:?
TimeToFullCharge:?
To get those particular values you need to do separate queries against different classes.
DesignCapacity can be queried from BatteryStaticData
FullChargeCacity can be queried from BatteryFullChargedCapacity
You'll need to use a different scope in the code also for the query. These classes are found in root/WMI instead of root/cimv2
string scope = "root/WMI";
string query = "SELECT DesignedCapacity FROM BatteryStaticData";
using (ManagementObjectSearcher batteriesQuery = new ManagementObjectSearcher(scope, query))
{
using (ManagementObjectCollection batteries = batteriesQuery.Get())
{
foreach (ManagementObject battery in batteries)
{
if (battery != null)
{
foreach (var property in battery.Properties)
{
Console.Log("Property name: " + property.Name + " Property value: " + property.Value);
}
}
}
}
}

WMI to retrieve website physical path in c#

I've created this VBScript WMI script:
On Error Resume Next
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
Set objWMIService = GetObject("winmgmts:\\localhost\root\MicrosoftIISv2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM IIsWebVirtualDirSetting", _
"WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
WScript.Echo "Path: " & objItem.Path
WScript.Echo
Next
Which returns the physical path (C:\inetpub\wwwroot\webapplication1) to all the applications in IIS.
Now I'm trying to use C# to populate a combobox with those values:
public static ArrayList Test2()
{
ArrayList WebSiteListArray = new ArrayList();
ConnectionOptions connection = new ConnectionOptions();
ManagementScope scope =
new ManagementScope(#"\\" + "localhost" + #"\root\MicrosoftIISV2",
connection);
scope.Connect();
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope,
new ObjectQuery("SELECT * FROM IIsWebVirtualDirSetting"), null);
ManagementObjectCollection webSites = searcher.Get();
foreach (ManagementObject webSite in webSites)
{
WebSiteListArray.Add(webSite.Path);
}
return WebSiteListArray;
}
But the output is the virtual path:
(`IIsWebVirtualDirSetting.Name="W3SVC/1/ROOT/webapplication1"`)
What needs to be changed in my query?
Note: I need to support IIS6 and .NET 4.0
Finally got it...
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\MicrosoftIISv2",
"SELECT * FROM IIsWebVirtualDirSetting");
foreach (ManagementObject queryObj in searcher.Get())
{
result.Add(queryObj["Path"]);
}
I prefer like this:
Connect at my local network server SOMEREMOTESERVER:
ConnectionOptions connection = new ConnectionOptions();
connection.Authentication = System.Management.AuthenticationLevel.PacketPrivacy;
ManagementScope scope =
new ManagementScope(#"\\SOMEREMOTESERVER\root\MicrosoftIISV2",
connection);
scope.Connect();
ObjectQuery query = new ObjectQuery("SELECT * FROM IISWebServerSetting");
var collection = new ManagementObjectSearcher(scope, query).Get();
foreach (ManagementObject item in collection)
{
var value = item.Properties["ServerBindings"].Value;
if (value is Array)
{
foreach (ManagementBaseObject a in value as Array)
{
Console.WriteLine(a["Hostname"]);
}
}
ManagementObject maObjPath = new ManagementObject(item.Scope,
new ManagementPath(
string.Format("IISWebVirtualDirSetting='{0}/root'", item["Name"])),
null);
PropertyDataCollection properties = maObjPath.Properties;
Console.WriteLine(properties["path"].Value);
Console.WriteLine(item["ServerComment"]);
Console.WriteLine(item["Name"]);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine();
}

Control Microsoft NLB with WMI c#

I try to control NLB with WMI.
WqlObjectQuery wql = new WqlObjectQuery (#"SELECT * FROM MicrosoftNLB_Node");
ManagementObjectSearcher search = new ManagementObjectSearcher(wql);
foreach (var obj in search.Get())
{
MessageBox.Show(obj.ToString());
}
I get a error message "Invalid class"
Try this:
ManagementObjectSearcher search = new ManagementObjectSearcher(
#"root\MicrosoftNLB",
#"SELECT * FROM MicrosoftNLB_Node");
foreach (var obj in search.Get())
{
MessageBox.Show(obj.ToString());
}
The MicrosoftNLB_Node class it's part of the Root\MicrosoftNLB namespace, So it seems which you are not setting the namespace before to connect to the WMi service.
try this
ManagementObjectSearcher search = new ManagementObjectSearcher(#"root\MicrosoftNLB",wql);

Visual Studio 2010 SP1 breaks things?

I'm using this little code snippet to catch Java processes with certain parameters:
string query = "Select * From Win32_Process Where Name = 'javaw.exe'";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection processList = searcher.Get();
foreach (ManagementObject obj in processList)
{
string cmdLine = obj.GetPropertyValue("CommandLine").ToString();
if (cmdLine.IndexOf("someapplication") != -1)
{
// ...
}
}
This code worked like a charm just a couple of days ago when I didn't have SP1 for VS2010. Now it throws a null pointer exception on line 7. I'm trying to compile for .NET Framework 2.0.
Help!? :/
if (cmdLine != null && cmdLine.IndexOf("someapplication") != -1)
It probably has less to do with SP1 and more to do with a Java update. Just check for null:
string query = "Select * From Win32_Process Where Name = 'javaw.exe'";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection processList = searcher.Get();
foreach (ManagementObject obj in processList)
{
object cmdLineValue = obj.GetPropertyValue("CommandLine");
if(cmdLineValue != null) {
string cmdLine = cmdLineValue.ToString();
if (cmdLine.IndexOf("someapplication") != -1)
{
// ...
}
}
}

Categories