What to specify for Local ManagementScope - c#

I am trying to connect (locally) to get a list of virtual machines and their properties. I have hacked some code I found, but my code is failing to connect so I can only assume that the connection string is wrong.
Using Server 2012, Hyper-V
private void listVirtualMachines() {
ManagementScope manScope = new ManagementScope(#"\\LOCALHOST\root\cimv2");
if (manScope.IsConnected) {
ObjectQuery queryObj = new ObjectQuery("SELECT * FROM Msvm_ComputerSystem");
// connect and set up our search
ManagementObjectSearcher vmSearcher = new ManagementObjectSearcher(manScope, queryObj);
ManagementObjectCollection vmCollection = vmSearcher.Get();
// loop through the machines
foreach (ManagementObject vm in vmCollection) {
// display VM details
LogString(vm["ElementName"].ToString());
LogString(vm["EnabledState"].ToString());
LogString(vm["Description"].ToString());
}
} else {
//WE END UP HERE EVERY TIME!
LogString("Cannot Connect to ManagementScope!");
}
} //funct

In Server 2012, Msvm_ComputerSystem is in the WMI namespace root\virtualization\v2 so the code should be:
ManagementScope manScope = new ManagementScope(#"\\.\root\virtualization\v2");
manScope.Connect();

Related

Telling if a remote server is up or down using C#

I was wondering if it's possible to tell if a remote server is up or down using C#? First I have a method to shut down the server:
private static void RestartSecondServer()
{
Console.WriteLine("Computer details retrieved using Windows Management Instrumentation (WMI)");
//Connect to the remote computer
ConnectionOptions co = new ConnectionOptions();
co.Username = #"***********";
co.Password = "*********";
ManagementScope ms = new ManagementScope("\\\\******\\root\\cimv2", co);
//Query remote computer across the connection
ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher query1 = new ManagementObjectSearcher(ms, oq);
ManagementObjectCollection queryCollection1 = query1.Get();
foreach (ManagementObject mo in queryCollection1)
{
string[] ss = {""};
mo.InvokeMethod("Reboot", ss);
Console.WriteLine(mo.ToString());
Console.WriteLine("Reboot complete");
//Process.Start("shutdown", "/r /t 0");
}
}
Now I want to create a method to see if this remote server which is in the process of being restarted is down. I tried a generic pinging method but it was returning true/success.
Can a server be successfully pinged if it's in the process of being restarted? Is it possible to tell if the server is being restarted?

Detect if screensaver, configured by GPO, is running on remote PC

I am trying to detect if screen saver is running on a remote PC using WMI. The remote PC is Windows 7, but it should work for W8/W10 as well.
So far I was testing having screen saver set manually on the remote PC (via control panel) and relying on WMI Win32_Process containing SCREEN_SAVER_NAME.SCR:
ConnectionOptions options = new ConnectionOptions();
options.Username = "Username";
options.Password = "password";
ManagementScope scope =
new ManagementScope(
"\\\\10.1.1.1\\root\\cimv2", options);
scope.Connect();
while (true)
{
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Process");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (var item in queryCollection)
{
if ((string)item["Description"] == "PhotoScreensaver.scr")
{
Console.WriteLine("screensaver running");
}
}
}
This works fine when the screen saver is set via control panel on the remote PC.
However, when setting the screen saver via group policy, WMI Win32_Process no longer lists the .SCR file and my software obviously doesn't work as expected.
Any idea how to detect running screen savers, which was set using GPO?

WMI management scope connect to local instead of remote

I tried to connect to a remote PC and query for its processes but when I run the code, it got connected with my local PC and obtained its processes instead of the remote PC.
The code is
ManagementScope scope = new ManagementScope(#"\\remote-user\\root\\cimv2");
scope.Connect();
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Process");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
You appear to be passing a username ("remote-user") instead of a hostname of the remote machine to your management scope. Change your code to e.g.:
ConnectionOptions options = new ConnectionOptions();
options.Password = "remoteUserPassword"; // you may want to avoid plain text password and use SecurePassword property instead
options.Username = "remote-user";
ManagementScope scope = new ManagementScope(#"\\remoteMachineHostname\root\cimv2", options);
(I assume that remote-user is Full computer name) change:
ManagementScope scope = new ManagementScope(#"\\remote-user\\root\\cimv2");
to:
ManagementScope scope = new ManagementScope(#"\\<FullComputerName>\root\cimv2");
another option:
ManagementScope scope = new ManagementScope("\\\\<FullComputerName>\\root\\cimv2");
See this link (it's Microsoft example)
Edit
if you want to connect with deffrent user you need to pass ConnectionOptions (see above link)

Getting system information using c#

I have some problem (c#).
I can retrieve some mainboard info from win32-baseboard but when I want to get Model
but an error accrued.
How can we get a list of installed software on windows (like xp).
How can we get a list of installed Peripheral device on Windows (with detail) (like scanner, webcam).
How to obtain total amount of ram (just) directly.
Use WMI (I suspect you already using it):
Model is blank. Try Manufacturer property. Also get the Product property to get the model.
Installed software: Get the Win32_Product class.
Try Win32_PnPSignedDriver class and iterate through.
Use Win32_ComputerSystem class and get TotalPhysicalMemory property.
Get WMIEXPLORER and play with it. LINK
Sample for C#:
If you require to connect to remote computer with credentials (strUsername and strPassword variables):
private ManagementScope CreateNewManagementScope(string server)
{
string serverString = #"\\" + server + #"\root\cimv2";
ManagementScope scope = new ManagementScope(serverString);
if (!chkUseCurrentUser.Checked)
{
ConnectionOptions options = new ConnectionOptions
{
Username = strUsername,
Password = strPassword,
Impersonation = ImpersonationLevel.Impersonate,
Authentication = AuthenticationLevel.PacketPrivacy
};
scope.Options = options;
}
return scope;
}
Get the services:
private void GetServicesForComputer(string computerName)
{
ManagementScope scope = CreateNewManagementScope(computerName);
SelectQuery query = new SelectQuery("select * from Win32_Service");
try
{
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
ManagementObjectCollection services = searcher.Get();
List<string> serviceNames =
(from ManagementObject service in services select service["Caption"].ToString()).ToList();
lstServices.DataSource = serviceNames;
}
}
catch (Exception exception)
{
lstServices.DataSource = null;
lstServices.Items.Clear();
lblErrors.Text = exception.Message;
Console.WriteLine(Resources.MainForm_GetServicesForServer_Error__ + exception.Message);
}
}
Some screens from wmiexplorer:

Use PInvoke to Capture CD Rom Information of Remote Machine

I'm using C# to call GetVolumeInformation on a remote machine. I can hit the remote harddrives easily as there is a default share setup of c$ or whatever. However, CD/DVD do not have a default setup. How can I read the remote CD/DVD drive using a PInvoke call or something else?
If I can't do it using C#, I could always use PowerShell or WMI.
The WMI allows you to get system information of a remote machine without problems, only you need set the remote WMI access in the machine and use a valid user and password. on this case you can use the Win32_LogicalDisk and Win32_CDROMDrive classes to retrieve the info which you need.
Try this C# sample.
using System;
using System.Collections.Generic;
using System.Management;
using System.Text;
namespace GetWMI_Info
{
class Program
{
static void Main(string[] args)
{
try
{
string ComputerName = "localhost";//set the remote machine name here
ManagementScope Scope;
if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
ConnectionOptions Conn = new ConnectionOptions();
Conn.Username = "";//user
Conn.Password = "";//password
Conn.Authority = "ntlmdomain:DOMAIN";
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn);
}
else
Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);
Scope.Connect();
ObjectQuery Query = new ObjectQuery("SELECT * FROM Win32_CDROMDrive");
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
foreach (ManagementObject WmiObject in Searcher.Get())
{
Console.WriteLine("{0,-35} {1,-40}","DeviceID",WmiObject["DeviceID"]);// String
Console.WriteLine("{0,-35} {1,-40}","Drive",WmiObject["Drive"]);// String
}
}
catch (Exception e)
{
Console.WriteLine(String.Format("Exception {0} Trace {1}",e.Message,e.StackTrace));
}
Console.WriteLine("Press Enter to exit");
Console.Read();
}
}
}
Using Powershell and WMI.
Try this:
Get-WmiObject -computername MyremotePC Win32_CDROMDrive | Format-List *
You need administrative credential on remote computer.
You can P/invoke in powershell the GetVolumeInfomation adding it as type using Add-Type (Some example here).
If you're trying to read data on the disk of a remote CD/DVD that isn't shared I don't know any way to do it.

Categories

Resources