Scenario #1: Executing .NET code in the current Thread
Scenario #2: Spawning a new Process in .NET
Scenario #3: Making a WMI request
Scenario #1: Executing .NET code in the current Thread
Executing .NET code as a different user may be necessary when performing disk operations, network operations, manipulating services, or other tasks that require security permissions. To start the Impersonation, the WindowsIdentity.Impersonate() method needs to be called with an authorization token for the impersonated user. This entire process requires making an external call to the Windows API to authenticate the user. While it sounds difficult, the MSDN page for the Impersonate() method provides a working sample that can be used as a basis for your own code.
Scenario #2: Spawning a new Process in .NET
Creating a new process already requires setting up a Process object or a ProcessStartInfo object. To set this object to execute as a different user requires just a bit of extra work to pass in a username and password. The following code snippet shows how to create a ProcessStartInfo object to start the command prompt as an Impersonated user.
String userName;
SecureString password;
// Code to get and set userName and password.
ProcessStartInfo startInfo = new ProcessStartInfo(“cmd.exe”);
startInfo.UserName = userName;
startInfo.Password = password;
// Add other parameters to startInfo as needed
Process.Start(startInfo);
Scenario #3: Making a WMI request
A WMI request queries the current or a remote server for system information to monitor the system. This functionality resides in the System.Management namespace, and isn't a common one to work with. WMI does allow for the queries to be ran as another user by creating a ConnectionOptions object, as the below example outlines.
String userName;
SecureString password;
// Code to get and set userName and password.
ConnectionOptions connectOptions = new ConnectionOptions();
options.UserName = userName;
options.Password = password;
ManagementPath path = new ManagementPath(“path to wmi object to query”);
ManagementScope scope = new ManagementScope(path, connectOptions);
// Once we have a scope object, we can either create an ObjectQuery object and query that way
scope.Connect();
ObjectQuery query = new ObjectQuery(“query to execute”);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection collection = searcher.Get();
// Or we can create an ObjectGetOptions and a ManagementObject
ObjectGetOptions options = new ObjectGetOptions();
ManagementObject mgmtObject = new ManagementObject(scope, path, options);
mgmtObject.Get();
// Can now retrieve values from ManagementObject like a Dictionary
string value = mgmtObject[“key name”].ToString();