I am using below code to connect remote computer however it needs that the remote computer must be exist at '#drivers/etc/hosts' file.
If i don't write the information about remote computer on /etc/hosts file it gives below error;
the rpc server is unavailable
How can i connect to rdp without modifying '#drivers/etc/hosts' file ?
public void GetSystemInformation()
{
ConnectionOptions options = new ConnectionOptions();
options.Username = "test";
options.Password = "test";
options.EnablePrivileges = true;
ManagementScope scope = new ManagementScope("\\\\someip\\root\\cimv2", options);
scope.Connect();
//Query system for Operating System information
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
// Display the remote computer information
Console.WriteLine("Computer Name : {0}",m["csname"]);
Console.WriteLine("Windows Directory : {0}", m["WindowsDirectory"]);
Console.WriteLine("Operating System: {0}", m["Caption"]);
Console.WriteLine("Version: {0}", m["Version"]);
Console.WriteLine("Manufacturer : {0}",m["Manufacturer"]);
}
}
Related
I am having issues starting/stopping/recycling my application pool that is located on a remote server. I have coded a function that will tell me what application pools are on a server (along with their status). However, I get the error "System.Management.ManagementException: This method is not implemented in any class" whenever I run the following snippet of code.
// getScope creates a ManagementScope object
ManagementScope scope = getScope(serverName, "microsoftiisv2", username, password);
scope.Connect();
ObjectQuery objectquery = new ObjectQuery("SELECT * FROM IISApplicationPoolSetting");
ManagementObjectSearcher mos = new ManagementObjectSearcher(scope, objectquery);
ManagementObjectCollection moc = mos.Get();
foreach (ManagementObject mo in moc)
{
string path = mo["Name"].ToString();
string name = path.Split('/')[2];
string pstate = mo["AppPoolState"].ToString();
if (name == applicationPoolName && pstate == "2")
{
string[] parameters = { "" };
mo.InvokeMethod("Stop", null);
// I have also tried the following alternatives:
// mo.InvokeMethod( "Stop", parameters )
}
}
I have tried looking at the Windows documentation, but have had no success understanding why my code does not work.
Currently I'm using following methods to get hardware information (network adapter, processor, hdd)
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectSearcher mbs = new ManagementObjectSearcher("Select * From Win32_processor");
ManagementObject dsk = new ManagementObject(#"win32_logicaldisk.deviceid=""c:""");
My app is desktop, client-server (app and db are installed on server).
This methods get information for client. Is there a way to get hardware information for some node on lan - I want to get hardware information for server?
This is a subroutine I use in order to query remote hosts (here I assume I already configured WMI on the remote computer):
public string getWMI(string[] parameters)
{
string ip = parameters[0];
string username = parameters[1];
string password = parameters[2];
string query = parameters[3];
string result = "";
ConnectionOptions options = new ConnectionOptions();
ManagementScope scope;
options.Username = username;
options.Password = password;
try
{
scope = new ManagementScope("\\\\" + ip + "\\root\\cimv2", options);
scope.Connect();
if (scope.IsConnected)
{
ObjectQuery q = new ObjectQuery(query);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, q);
ManagementObjectCollection objCol = searcher.Get();
foreach (ManagementObject mgtObject in objCol)
{
result = result + mgtObject.GetText(TextFormat.CimDtd20);
}
}
else
{
}
}
catch (Exception e)
{
writeLogFile("WMI Error: " + e.Message);
writeLog("WMI Error: " + e.Message);
}
return result;
}
In that subroutine I use a direct query such as "select * from Win32_ComputerSystem" but you can use ManagementClass as well.
I want to get hardware information for server?
WMI can poin to another server as long as:
The eserver exposes WMI
The fireawall does not block it.
Your user account has the rights on the other server.
Simple like that.
I have three remote PC's to which I remotely connect. I am trying to write a simple Windows application that would display in a single window whether a particular process is running on either of the machines, e.g.
Server1: Chrome not running
Server2: Chrome IS running
Server3: Chrome IS running
I used WMI and C#. So far I've got this much:
ConnectionOptions connectoptions = new ConnectionOptions();
connectoptions.Username = #"domain\username";
connectoptions.Password = "password";
//IP Address of the remote machine
string ipAddress = "192.168.0.217";
ManagementScope scope = new ManagementScope(#"\\" + ipAddress + #"\root\cimv2");
scope.Options = connectoptions;
//Define the WMI query to be executed on the remote machine
SelectQuery query = new SelectQuery("select * from Win32_Process");
using (ManagementObjectSearcher searcher = new
ManagementObjectSearcher(scope, query))
{
ManagementObjectCollection collection = searcher.Get();
foreach (ManagementObject process in collection)
{
// dwarfs stole the code!! :'(
}
}
I think it is all set up correctly, but if I MessageBox.Show(process.ToString()) inside the foreach loop, I get a whole bunch of message boxes with the following text:
\\username\root\cimv2:W32_Process.Handle="XXX"
I am kind of stuck. Is there any way I can "translate" that XXX to a process name? Or else, how can actually get the names of the processes so I can use an if statement to check whether it is a "chrome" process?
Or...is my implementation an overkill? Is there an easier way to accomplish this?
Thanks a lot!
In your foreach, try this:
Console.WriteLine(process["Name"]);
You can filter the name of the process to watch in the WQL sentence, so you can write something like this
SelectQuery query = new SelectQuery("select * from Win32_Process Where Name='Chrome.exe'");
Try this sample app
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";
ManagementScope Scope;
if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase))
{
ConnectionOptions Conn = new ConnectionOptions();
Conn.Username = "";
Conn.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_Process Where Name='Chrome.exe'");
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
foreach (ManagementObject WmiObject in Searcher.Get())
{
//for each instance found, do something
Console.WriteLine("{0,-35} {1,-40}","Name",WmiObject["Name"]);
}
}
catch (Exception e)
{
Console.WriteLine(String.Format("Exception {0} Trace {1}",e.Message,e.StackTrace));
}
Console.WriteLine("Press Enter to exit");
Console.Read();
}
}
}
Try Process.GetProcesses("chrome", "computerName");
Defined in System.Diagnostics.Process as
public static Process[] GetProcessesByName(
string processName,
string machineName)
I am trying to write a mini w32 executable to remotely uninstall an application using WMI.
I can list all the installed applications using this code below but i couldnt find a way to uninstall the application remotely thru WMI and C#
I know I can do same using msiexec as a process but I wish to solve this using WMI if its possible...
Thanks,
Cem
static void RemoteUninstall(string appname)
{
ConnectionOptions options = new ConnectionOptions();
options.Username = "administrator";
options.Password = "xxx";
ManagementScope scope = new ManagementScope("\\\\192.168.10.111\\root\\cimv2", options);
scope.Connect();
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Product");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
// Display the remote computer information
Console.WriteLine("Name : {0}", m["Name"]);
if (m["Name"] == appname)
{
Console.WriteLine(appname + " found and will be uninstalled... but how");
//need to uninstall this app...
}
}
}
Have a look at WMI Code Creator (a free tool from Microsoft) — it can generate WMI code for you in various languages, including C#.
Here's an example illustrating the Win32_Product.Uninstall method usage. You need to know the GUID, name and version of the application you want to uninstall, as they are the key properties of the Win32_Product class:
...
ManagementObject app =
new ManagementObject(scope,
"Win32_Product.IdentifyingNumber='{99052DB7-9592-4522-A558-5417BBAD48EE}',Name='Microsoft ActiveSync',Version='4.5.5096.0'",
null);
ManagementBaseObject outParams = app.InvokeMethod("Uninstall", null);
Console.WriteLine("The Uninstall method result: {0}", outParams["ReturnValue"]);
If you have partial info about the application (e.g. only name or name and version), you can use a SELECT query to obtain the corresponding Win32_Process object:
...
SelectQuery query = new SelectQuery("Win32_Product", "Name='Microsoft ActiveSync'");
EnumerationOptions enumOptions = new EnumerationOptions();
enumOptions.ReturnImmediately = true;
enumOptions.Rewindable = false;
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query, options);
foreach (ManagementObject app in searcher.Get())
{
ManagementBaseObject outParams = app.InvokeMethod("Uninstall", null);
Console.WriteLine("The Uninstall method result: {0}", outParams["ReturnValue"]);
}
This only helps kills processes on the local machine. How do I kill processes on remote machines?
You can use wmi. Or, if you don't mind using external executable, use pskill
I like this (similar to answer from Mubashar):
ManagementScope managementScope = new ManagementScope("\\\\servername\\root\\cimv2");
managementScope.Connect();
ObjectQuery objectQuery = new ObjectQuery("SELECT * FROM Win32_Process Where Name = 'processname'");
ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(managementScope, objectQuery);
ManagementObjectCollection managementObjectCollection = managementObjectSearcher.Get();
foreach (ManagementObject managementObject in managementObjectCollection)
{
managementObject.InvokeMethod("Terminate", null);
}
I use the following code. psKill is also a good way to go but sometimes you need to check the some other stuff, for example in my case remote machine was running multiple instances of same process but with different command line arguments, so following code worked for me.
ConnectionOptions connectoptions = new ConnectionOptions();
connectoptions.Username = string.Format(#"carpark\{0}", "domainOrWorkspace\RemoteUsername");
connectoptions.Password = "remoteComputersPasssword";
ManagementScope scope = new ManagementScope(#"\\" + ipAddress + #"\root\cimv2");
scope.Options = connectoptions;
SelectQuery query = new SelectQuery("select * from Win32_Process where name = 'MYPROCESS.EXE'");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
ManagementObjectCollection collection = searcher.Get();
if (collection.Count > 0)
{
foreach (ManagementObject mo in collection)
{
uint processId = (uint)mo["ProcessId"];
string commandLine = (string) mo["CommandLine"];
string expectedCommandLine = string.Format("MYPROCESS.EXE {0} {1}", deviceId, deviceType);
if (commandLine != null && commandLine.ToUpper() == expectedCommandLine.ToUpper())
{
mo.InvokeMethod("Terminate", null);
break;
}
}
}
}