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
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?
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?
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)
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:
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.