Powershell config to force a batch file to run within the powershell window? - powershell

I've got a powershell script that eventually passes a stack of arguments into a batch file via invoke-expression command.
However, on one server, when the powershell scripts executes that batch file, that batch file opens in a new window, but on the other server, the batch file executes within the powershell window.
What that means, is that I've got a sleep interval that is starting once the batch file begins executing in the new window, and thus screwing up my timings, unlike the other server, where the sleep interval doesn't begin until after the batch file has finished executing.
So my question is... does anybody know why the behaviours are different between the two servers, and how to get the batch file to execute in the powershell window? I'm thinking it's a configuration thing, but can't actually find anything that tells me how to make it do what I want it to do.....
Thanks!
--edit--
I'm currently just piping the line straight through like this:
E:\Software\ibm\WebSphere\AppServer\bin\wsadmin -lang jython -username $($username) -password $($password) -f "F:\Custom\dumpAllThreads.py" $($servers)
Previously, it was
$invokeString = 'E:\Software\ibm\WebSphere\AppServer\bin\wsadmin -lang jython -username $($username) -password $($password) -f "F:\Custom\dumpAllThreads.py" $($servers)'
$output = invoke-expression $invokeString
Both had the same behaviour.

So my question is... does anybody know why the behaviours are different between the two servers
Most often I've seen this sort of thing related to how a scripts is called. If the same user is logged on multiple times on the same server (i.e., console and RDP) then the window might appear in a different session. Similarly, if the script runs as a scheduled task and the user that runs the task isn't the user logged on, the window will never be visible. If the same user is logged on, it might be visible.
how to get the batch file to execute in the powershell window?
You could try Start-Process with -NoNewWindow, as #Paul mentions.
However....
What that means, is that I've got a sleep interval that is starting once the batch file begins executing in the new window, and thus screwing up my timings, unlike the other server, where the sleep interval doesn't begin until after the batch file has finished executing.
It sounds like your actual problem is that your code has a race condition. You should fix the actual problem. Use Start-Process with the -Wait parameter, or use the jobs system in PowerShell.

Related

Powershell script triggers process only when invoked manually. Timing out when triggered via Scheduled Task

On a Windows 2012 R2 server there is a Powershell script that I can manually invoke to start a process on some EXE, this works just fine.
But when trying to trigger it via a scheduled task (invoking the same script) the start-process within the script just doesn't trigger or finish. Causing the task scheduler to terminate the task due to exceeding the timeout threshold.
Here's the core section of the script:
$exe = "c:\some\app.exe"
$arguments = "-user me -pwd secret"
$process = Start-Process $exe -ArgumentList $arguments -PassThru -Wait
return $process
Is there some way I can get some insights into what start-process is doing or why the same script works when invoked manually but not programmatically?
I want to emphasize that the way the script is invoked from the scheduled task is not a problem! The script triggers because the corresponding log file populates.
Any insights or help on this is greatly appreciated!
quick update on this since I found the problem. It turns out, it had nothing to do with either the powershell script or the scheduled task itself...
On the machine the script is running on, there is a network share that is mapped as the z:\ drive. I use it to save logs to. Now apparently that mapping/mounting is handled differently depending on whether the script is invoked interactively or programatically, because in the latter case it appears that the resoultion of the network path \\network\share\folder1 does not succeed, however there is nothing complaining about it, the process just silently does not start. If however, I point the logs to a physical local path or the explicit full network path itself, there is no problem running the script.
Lesson learned, never trust OS' drive mapping of network paths :D
Cheers

Powershell - Log file

I have a PowerShell script, at its begining I added: $ErrorActionPreference = "Stop". It's good, if there is an error the script won't go further.
Fact is that when an error occurs, the script stop and exit itself and so, I can not see the error.
The best option is to crate a logfile that will write EVERYTHING that was in the PowerShell terminal, including succesful lines.
If not, at least make the terminal keep opened even if an error occurs, but stop the script.
I would recommend Start-Transcript:
The Start-Transcript cmdlet creates a record of all or part of a
PowerShell session to a text file. The transcript includes all command
that the user types and all output that appears on the console.

Automatically execute .cmd file requiring user input

We have a .cmd file we want to be able to execute automatically using Powershell (from TFS Release).
The issue with using start-process in Powershell is that execution gets stuck waiting for user input (Press any key to continue...).
Is there any way that we can pass variables to this call or call it in a different way where we no longer require user input for this .cmd?
Don't use Start-Process.
"`n" | & 'C:\path\to\your.cmd'
Powershell isn't getting stuck, Start-Process is working correctly - it's running the process (assume cmd.exe) and waiting for that process to terminate before continuing.
cmd.exe is prompting for interactive user input (PAUSE) before continuing, again working as you have instructed it to.
The issue is you're running non-interactively, and aren't providing the input required to continue.
You can update the cmd file and add an optional parameter so you can 'skip' the PAUSE when running unattended:
if "%1"=="unattended" goto skippause
pause
:skippause
then run it using unattended:
CMD /c c:\folder\file.cmd unattended

Is there a way to start commandline processes in a new commandline window from a powershell script?

I am using
Start-Process "<PathToFile>.bat"
For .bat files from a lengthy script in Powershell (v3). However, the commandline window pops up for a moment and is immediately closed and the process that normally runs on the commandline, runs in the background with no indication wether it's finished or if any errors occured.
Is there a way to force the command window to stay open until the user exits the window (after the .bat ran)? I suppose even if there is a way that the command window stays open, the PS script will continue to run in the background?
As said by Alex K CMD /K opens a CMD window and then keeps it open.
If you use CMD /C it will call the file, run the commands/process and then exit.
Sadly, it never worked for me with cmd /c. Since I also needed parameters to be handed over to the programm called from the commandline, I opted to write a temporary proxy bat that held the call to the program and the parameters.
Pseudocode here:
"ProgramName /Parameters" | Out-File DirOfTempBatFile -Encoding ascii
$output = Start-Process DirOfTempBatFile -wait
This calls the program (sqlplus with parameters) with keeping the command window open. Additionally, you can access the output of the sqlplus debug messages via $output.

How can I run a PowerShell script after reboot?

I have a powershell script that tails specifics logs. If there is no update to the logs within a specific time span, an alert is then sent to nagios (as this depicts that the service is no longer running).
The powershell script works great when run manually, but my issue is that I want it to load up on reboot. I've tried creating a scheduled task that repeats itself every 5 minutes using the arguments '-noexit -file C::\script.ps1'. The problem is then that my script doesn't actually work when run as a scheduled task.
The execution policy is set to Unrestricted, so the script runs, but the code doesn't execute and work like it does when manually run.
FWIW, the code is:
function Write-EventlogCustom($msg) {
Write-EventLog System -source System -eventid 12345 -message $msg
}
Get-Content -Path C:\test.log -Wait | % {Write-EventlogCustom $_}
So if I update test.log while the powershell script runs a scheduled task, the event log doesn't get updated. However, when I run this script manually, and update to test.log, it does appear in the event viewer.
I'm hoping that a second set of eyes might find something that I may have missed?
As #Tim Ferrill has mentioned, I needed to run the process with task schedulers 'Run with highest privileges' setting. This resolved the issue.