Run PSEXEC process in ASP.NET as different user - c#

I'm trying to connect from my ASP web application published on IIS server to some servers using psExec, start application and get the output.
When I try to start process without setting credentials I get this error:
Access is denied
but if I do the same as administrator, I'm only getting empty fields for output, errors and exception variables. Also, when I do it from my local pc using visual studio it works properly.
What am I doing wrong? Here is my code:
try
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(866);
p.StartInfo.StandardErrorEncoding = Encoding.GetEncoding(866);
p.StartInfo.FileName = #"C:\inetpub\wwwroot\Monitoring\bin\PsExec.exe";
server = "dp-next.b42";
p.StartInfo.Arguments = #" \\" + server + " \"c:\\program files\\omniback\\bin\\omnirpt.exe\" -report list_sessions -timeframe 12 12";
p.StartInfo.UserName = "admin";
p.StartInfo.Domain = "domain";
string pass = "password";
SecureString s = new SecureString();
foreach(char c in pass)
{
s.AppendChar(c);
}
p.StartInfo.Password = s;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.Start();
output = output + p.ProcessName;
//output = p.StandardOutput.ReadToEnd();
while ((res = p.StandardOutput.ReadLine()) != null)
{
i++;
output = output + res;
}
errors = p.StandardError.ReadToEnd();
p.Close();
}
catch (Exception ex)
{
exe = ex.ToString();
}

I once had to develop something very similar. Here is what I did.
Instead of using:
p.StartInfo.UserName = "admin";
p.StartInfo.Domain = "domain";
p.StartInfo.Password = s;
I put username and password directly inside PsExec command arguments (respectively with -u and -p). In your case:
p.StartInfo.Arguments = #" \\" + server + " -u YOUR_DOMAIN\\YOUR_USERNAME -p YOUR_PASSWORD \"c:\\program files\\omniback\\bin\\omnirpt.exe\" -report list_sessions -timeframe 12 12";
More info on PsExec usage here.

Related

System.Diagnostic.Process class works in console application but not work in web api

I am running doors.exe using Process class. When I run it in the console application, there is no problem, but the program hangs in the web application. What could be the reason for this?
here is my code below;
public string ExecuteDoorsScript(string dxlScriptPath, string userName, string password)
{
//Start the process
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = #"C:\Program Files\IBM\Rational\DOORS\9.6\bin\doors.exe";
info.Arguments = "-b \"" + dxlScriptPath + "\" -u " + userName + " -P " + password + "-W -d 1234567#databasepath.it";
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
info.CreateNoWindow = true;
var process = Process.Start(info);
//Wait for the window to finish loading.
var output = process.StandardOutput.ReadToEnd();
var error = process.StandardError.ReadToEnd();
//Wait for the process to end.
process.WaitForExit();
if (!String.IsNullOrEmpty(error))
{
throw new Exception("Doors run dxl error: " + error);
}
return output;
}
my dxl script;
string topfoldername = "/Test"
void listIndices(Folder parent, int level)
{
Item i
Folder f
for i in parent do {
f = folder(i)
cout << (uniqueID i) ";" (name i) ";" ((type i)) ";" "\n"
}}
listIndices(folder topfoldername, 1)

How can I take ownership of a file in c# using takeown or icacls?

I know there are other posts on the matter but none have presented me with a working solution.
I'm trying to take ownership of files under C:\Windows\Media so I can replace them with my own. Currently I've been trying to do that by running either takeown or icacls in CMD, but neither seem to work. The takeown method actually returns success from CMD but I still get access denied when trying to delete the file. With the icacls method I get "the handle is invalid" and still get access denied.
The program is running as administator fyi.
And also in the icacls method changing Environment.Username to "Administrators" doesn't change anything.
Any help is appreciated!
Here is the code for the takeown method:
string[] soundFiles;
soundFiles = Directory.GetFiles(#"C:/Windows/Media", "*.wav");
//string cmdargs = #"/c takeown /F C:\Windows\Media";
string shortcmdargs = #"/c takeown /F ";
//Process.Start("CMD.exe", cmdargs);
string output = "null";
foreach(string file in soundFiles)
{
try
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = shortcmdargs + #"C:\Windows\Media\" + Path.GetFileName(file);
p.Start();
output = p.StandardOutput.ReadToEnd();
System.IO.File.Delete(file);
System.IO.File.Copy("neco.wav", file);
}
catch(Exception exce)
{
MessageBox.Show("Output: " + output + "\neException: " + exce);
}
}
And here is what I get when running it:
Here is the code for the icacls method:
string[] soundFiles;
soundFiles = Directory.GetFiles(#"C:/Windows/Media", "*.wav");
string cmdargs = #"/c takeown /F C:\Windows\Media";
string shortcmdargs = #"/c takeown /F ";
Process.Start("CMD.exe", cmdargs);
string output = "null";
foreach(string file in soundFiles)
{
try
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = #"/c icacls " + #"C:\Windows\Media\" + Path.GetFileName(file) + " /grant " + Environment.UserName + ":(OI)(CI)F /T";
p.Start();
output = p.StandardOutput.ReadToEnd();
System.IO.File.Delete(file);
System.IO.File.Copy("neco.wav", file);
}
catch(Exception exce)
{
MessageBox.Show("Output: " + output + "\neException: " + exce);
}
}
And here is what I get with it:

.NET webservice attemp to print on a network printer not working

I am working on a c# web service using .net framwork 4.0
and I have a file (print.exe) which executes printing, the file works when I double click it manually, it prints, but when using the webservice it give an error that No printer installed.
this the code of the webmethod:
[WebMethod]
public String Print_In_Kitchen(Int32 OrderID, String Lang)
{
System.Security.SecureString secPass = new System.Security.SecureString();
string paswd = "96321";
for (int i = 0; i < paswd.Length; i++)
{
secPass.AppendChar(paswd[i]);
}
Process proc = new Process();
proc.StartInfo.FileName = #"C:\EXE_Print.exe";
proc.StartInfo.Arguments = #"" + OrderID + " " + Lang + " " + "\"" + ConfigurationManager.ConnectionStrings["constr"].ConnectionString + "\"";
proc.StartInfo.UserName = "omar";
proc.StartInfo.Password = secPass;
proc.StartInfo.Domain = "Futec";
proc.StartInfo.Verb = "runas";
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Verb = "runas";
proc.StartInfo.RedirectStandardInput = true;
proc.Start();
string s = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
return s;
}
I have searched for a solution but haven't found any useful link or explanation for this, saw this question here but with no answer:pdf print through .net process
and I am new to .NET
My gut feeling is that the User that the Service is running as, doesn't have access to that printer.
You could try changing StartInfo.UseShellExecute to true but I would also check the permissions of your services user.

Run a command in a windows remote server and get back the console output in C# .NET

I have a remote server name (windows), username and password.
Using C# .Net, I want to run a command on the remote server and get back the console output
Is there a way to do it in C#?
I was able to run the command using WMI with the following code (partial) but with no luck of getting the console output. I could only get back the Process ID.
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
ManagementClass processClass = new ManagementClass(scope, managementPath,objectGetOptions);
ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
inParams["CommandLine"] = "cmd.exe /c "+ mycommand;
ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);
Any Ideas?
This function is what I came up with after some research. Hope it helps someone else.
public string executeCommand(string serverName, string username, string password, string domain=null, string command)
{
try
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
if (null != username)
{
if (null != domain)
{
startInfo.Arguments = "/C \"psexec.exe \\\\" + serverName + " -u " + domain+"\\"+username + " -p " + password + " " + command + "\"";
}
else
{
startInfo.Arguments = "/C \"psexec.exe \\\\" + serverName + " -u " + username + " -p " + password + " " + command + "\"";
}
}
else
{
startInfo.Arguments = "/C \"utils\\psexec.exe "+serverName+" "+ command + "\"";
}
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
if (process.ExitCode == 0 && null != process && process.HasExited)
{
return process.StandardOutput.ReadToEnd();
}
else
{
return "Error running the command : "+command;
}
}
catch (Exception ex)
{
throw ex;
}
}
You can try executing a command with PsTools. One of many features they offer is PsExec. It allows you to run a command on a remote server. It should also return the results into a console (on local PC where it was run from).

How to create a RAM Disk with imdisk and C#?

I'm trying to create a RAM Directory via imdisk in C#. Since the cmd command is something like: imdisk -a -s 512M -m X: -p "/fs:ntfs /q /y"
I looked up how to process cmd commands with C# and found several hints regarding ProcessStartInfo(). This class works almost the way I intend it to, but since imdisk needs administrator priviliges I'm kinda stuck. Even though the code block is executed without exceptions, I don't see any new devices within the Windows Explorer.
try
{
string initializeDisk = "imdisk -a ";
string imdiskSize = "-s 1024M ";
string mountPoint = "-m "+ MountPoint + " ";
string formatHdd = "-p '/fs:ntfs /q /y' ";
SecureString password = new SecureString();
password.AppendChar('0');
password.AppendChar('8');
password.AppendChar('1');
password.AppendChar('5');
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.FileName = "cmd";
procStartInfo.Verb = "runas";
procStartInfo.UserName = "Admin";
procStartInfo.Password = password;
procStartInfo.Arguments = initializeDisk + imdiskSize + mountPoint + formatHdd;
Process.Start(procStartInfo);
catch (Exception objException)
{
Console.WriteLine(objException);
}
I hope someone can give me a little hint, right now I'm out of ideas.
Well I solved my problem in a different way. Somehow it seems that imdisk didn't format the new RamDisk the way it should and therefor no disk were created. As soon as I deleted the formatting option the disk is created and needs to be formatted. Therefore I started another process and used the cmd command "format Drive:"
For anyone who is interested, my solution is as follows:
class RamDisk
{
public const string MountPoint = "X:";
public void createRamDisk()
{
try
{
string initializeDisk = "imdisk -a ";
string imdiskSize = "-s 1024M ";
string mountPoint = "-m "+ MountPoint + " ";
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
procStartInfo.FileName = "cmd";
procStartInfo.Arguments = "/C " + initializeDisk + imdiskSize + mountPoint;
Process.Start(procStartInfo);
formatRAMDisk();
}
catch (Exception objException)
{
Console.WriteLine("There was an Error, while trying to create a ramdisk! Do you have imdisk installed?");
Console.WriteLine(objException);
}
}
/**
* since the format option with imdisk doesn't seem to work
* use the fomat X: command via cmd
*
* as I would say in german:
* "Von hinten durch die Brust ins Auge"
* **/
private void formatRAMDisk(){
string cmdFormatHDD = "format " + MountPoint + "/Q /FS:NTFS";
SecureString password = new SecureString();
password.AppendChar('0');
password.AppendChar('8');
password.AppendChar('1');
password.AppendChar('5');
ProcessStartInfo formatRAMDiskProcess = new ProcessStartInfo();
formatRAMDiskProcess.UseShellExecute = false;
formatRAMDiskProcess.CreateNoWindow = true;
formatRAMDiskProcess.RedirectStandardInput = true;
formatRAMDiskProcess.FileName = "cmd";
formatRAMDiskProcess.Verb = "runas";
formatRAMDiskProcess.UserName = "Administrator";
formatRAMDiskProcess.Password = password;
formatRAMDiskProcess.Arguments = "/C " + cmdFormatHDD;
Process process = Process.Start(formatRAMDiskProcess);
sendCMDInput(process);
}
private void sendCMDInput(Process process)
{
StreamWriter inputWriter = process.StandardInput;
inputWriter.WriteLine("J");
inputWriter.Flush();
inputWriter.WriteLine("RAMDisk for valueable data");
inputWriter.Flush();
}
public string getMountPoint()
{
return MountPoint;
}
}
Doesn't cmd.exe need to have the /C command line option passed through to run a command passed through as an argument? May well be that cmd.exe is just ignoring what you're passing through in procStartInfo.Arguments because you haven't prepended "/C " onto the front of the Arguments.

Categories