question

HkanMagnusson-4069 avatar image
0 Votes"
HkanMagnusson-4069 asked HkanMagnusson-4069 commented

Calling Powershell Start-Service from C# with a valid command does not execute

I have a problem that i have been googling on for hours and hours.

I try to run a remote Powershell script to start up a process. Exit and then let it run. It takes hours. The problem is that the process seem to exit directly after beeing started, without errors or any information in logs.

I know it starts, it create the logfile specified (but empty) and i get a response from Start-Process with process id and other information. If i take the script and paste it inside a Powershell command window on the client in question. It runs without any problems. So the script does not seem to be faulty.

Im new to this so bear with me.

             InitialSessionState initial = InitialSessionState.CreateDefault();
             initial.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;
             Runspace runspace = RunspaceFactory.CreateRunspace(initial);
             runspace.Open();

             var ps = PowerShell.Create();
             ps.Runspace = runspace;
             ps.AddCommand("Invoke-Command");
             ps.AddParameter("ComputerName", Host);
             ps.AddParameter("Credential", CreateCredentials());
               
             ScriptBlock filter = ScriptBlock.Create(command);
             ps.AddParameter("ScriptBlock", filter);
             Collection<PSObject> results = ps.Invoke();
             return results;

My command line that i pass lookes like this:

Start-Process -FilePath C:\Some\Valid\Path\prog.exe -ArgumentList "Long list of arguments specific to exe" -PassThru -RedirectStandardOutput C:\Log\Path\current.log

Does someone have any ideas, what im i missing?


dotnet-csharpwindows-server-powershell
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

HkanMagnusson-4069 avatar image
0 Votes"
HkanMagnusson-4069 answered HkanMagnusson-4069 commented

@MotoX80 Okay, now i have done some testing and research. It turns out that you are right about it not beeing tied to any window per se. However it is tied to the PS Session. And when that sucker ends it kills the process. This can be solved using the -InDisconnectedSession flag. If i set this in the Invoice-Command call, it does not kill the process. Untill 2 hours :( And i need way more time.

This limit can be reset by using:

$TimeOut = New-PSSessionOption -IdleTimeoutMSec (New-TimeSpan -Days 7).TotalMilliSeconds
-InDisconnectedSession -SessionOption $TimeOut

But i have not been able to set this yet.

             ps.AddCommand("Invoke-Command");
             ps.AddParameter("ComputerName", Host);
             ps.AddParameter("ScriptBlock", filter);
             ps.AddParameter("Credential", CreateCredentials());
             ps.AddParameter("InDisconnectedSession");
             ps.AddParameter("SessionName", "CoolSessionName");
             ps.AddParameter("SessionOption", "$psOption");

I dont know how to create this $TimeOut variable and tie it to the parameter SessionOption in my script. Since it is a variable that needs to execute before the Invoke-Command.

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I don't have any experience calling PS from C# using this technique.

https://docs.microsoft.com/en-us/powershell/scripting/developer/prog-guide/runspace10-code-sample?view=powershell-7.1

Maybe something like this...

 ps.AddCommand("New-PSSessionOption");
 ps.AddParameter(whatever);
 Timeout = powershell.Invoke();
    
    
 ps.AddCommand("Invoke-Command");
 ps.AddParameter("ComputerName", Host);
 ps.AddParameter("ScriptBlock", filter);
 ps.AddParameter("Credential", CreateCredentials());
 ps.AddParameter("InDisconnectedSession");
 ps.AddParameter("SessionName", "CoolSessionName");
 ps.AddParameter("SessionOption", Timeout);

Have you considered creating a .ps1 script file and just shelling out a Powershell.exe process to execute it?

0 Votes 0 ·

Hello MotoX80

Thank you for all your help. I have found the solution now. I just ran a separate script like that before i dissconnected from the host and it worked. Now the process runs and terminates as it should. Problem is solved. :)

0 Votes 0 ·
MotoX80 avatar image
0 Votes"
MotoX80 answered MotoX80 commented

My command line that i pass lookes like this:

Start-Process -FilePath C:\Some\Valid\Path\prog.exe -ArgumentList "Long list of arguments specific to exe" -PassThru -RedirectStandardOutput C:\Log\Path\current.log

Add "-RedirectStandardError C:\Log\Path\current.err" to capture any errors that it might encounter.

· 5
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for the answer. I added this to the script but no change. The log does not appear. I also tapped in on the Warning, error and information DataAdded events. But they dont fire either.

0 Votes 0 ·

Hey MotoX80, is it possible that it could be a problem with sessions?

When the session ends perhaps the exe is not yet allowed to run?

0 Votes 0 ·
MotoX80 avatar image MotoX80 HkanMagnusson-4069 ·

Some thoughts....

If you delete the current.log file on the remote computer, and then rerun your process, if the file is recreated, then your session would appear to be ok.

Check the task manager on the remote computer and make sure that an instance of prog.exe is not already running (hung?).

Instead of running prog.exe, launch a simple command line program like c:\windows\system32\whoami.exe to verify that it writes the current userid into the current.log file.

Does prog.exe just write to the console (stdout)? Any option where the exe will write to an eventlog or to it's own log file? You may have to resort to tracing it's activity using Process Monitor. That will show you file/registry/network activity for prog.exe.

https://docs.microsoft.com/en-us/sysinternals/downloads/procmon

0 Votes 0 ·

Yes, when i rerun the script from my C# program it recreated the log file every time. No problem with that.

The process it not running on the remote computer, i made sure that its not hung or anything.

But your ideas got me thinking that the process of prog.exe might be tied to the window where it was oppend. So i started a process in a normal cmd command line window and it started fine. I let it run a few minutes and then closed the window. It then killed the process. It did not go on in the background as i have thought.

The problem might simply be that when i remotely log on to my host computer it does everyting in the background and does not spawn windows. And when the PS object is destroyed by the computer connected to the host. So does the process.

Is there a way to spawn a window with the process on the host that lives on even when i dissconect from the host? To leave out -NoNewWindow parameter does not seem to help.





0 Votes 0 ·
Show more comments