I have created a Powershell script that I call from a batch file, and everything works fine when I call the batch file. The problem I am running into is I need to set the batch file to run in Task Scheduler. It starts fine, but it keeps hanging up because the task scheduler never says "The operation completed successfully" (0x0). Instead, it stays at "The task is currently running" (0x41301). Please advise, and I understand this is not the most ideal way to call a Powershell Script but for our environment and limited knowledge of scripting it works the best for us.
You should just use Task Scheduler to run PowerShell.
Create a new task, go to Actions tab, then choose New..., and inside this new window, you can run any program, like you run something from cmd.
Inside Program/script square, you simply put Powershell.exe, and inside Add arguments (optional) powershell arguments. This will work the same, as you would type in normal command line:
powershell <arguments>
So if you want to run script, that is saved in your disk, simply put this in arguments list:
C:\LocalisationOfScript\script.ps1 "argument 1" argument2
If you want more options, just add common parameters before this:
-windowstyle hidden -executionpolicy bypass C:\LocalisationOfScript\script.ps1 "argument 1" argument2
Of even this:
-windowstyle hidden -executionpolicy bypass if (Test-path C:\script\script.ps1) { C:\script\script.ps1 "argument 1" argument2 } else { return -1 }
And finally:
Start-Process Powershell.exe -argumentslist "-a -b -c copy" -windowstyle hidden -wait -erroraction stop
You can even add try, catch to last example.
Thank you for all the comments, i researched you advice and came across the exit command i forgot to add to the end of my script, so when i call my script it left the session to exchange open after i applied the exit command to the end of the script the program has been running without error (knock on wood) sense the fix and after i closed and reopened Task Scheduler the last run message changed to (0x0)
Related
I have a batch file structured like below:
cd "C:\my\scripts\directory
powershell -f myPowershellSCript.ps1
exit %errorlevel%
This batch file is being sent through an in house remote shell application (which is mostly a black box to me) in a non-interactive way to another machine to be run. I can execute the application and watch it's output on the terminal locally. The script is completing the powershell script and then just dropping back to the remote shell on the test machine without ever running the last line in the batch file. I see the cmd.exe shell drop back to a prompt at C:\my\scripts\directory on the remote machine and just wait. Because it's non-interactive the script never completes.
I'd like to tag that last exit line onto the end of the line that calls powershell, but everything I've tried (below) has not worked. I fear that powershell is taking everything as input instead of batch interpreting them as two separate commands.
powershell -f SecurePaymentsTestLauncher.ps1 && exit 1
powershell -nonInteractive -f SecurePaymentsTestLauncher.ps1 && exit 1
powershell -nonInteractive -command "& 'SecurePaymentsTestLauncher.ps1'" && exit 1
powershell -nonInteractive -command "& 'SecurePaymentsTestLauncher.ps1'" ; exit 1
powershell -nonInteractive -f SecurePaymentsTestLauncher.ps1 ; exit 1
still produces the same result. No return from the remote execution.
How do I append a second command to a batch file line when the first command is a call to powershell?
Is your PowerShell process exiting status 0? The && conditional operator only executes the command it precedes when the command it follows exits 0. If you want to exit 1 regardless of whether PowerShell exits zero or non-zero, use a single &.
In your powershell command, you might also need to call the .ps1 script name as .\SecurePaymentsTestLauncher.ps1 and add the -ExecutionPolicy RemoteSigned arguments.
Try
cd "C:\my\scripts\directory"
start powershell -f myPowershellSCript.ps1
exit %errorlevel%
Using 'start' in front of powershell instantiates a separate powershell host outside of the batch script host, which will allow your ps1 file to do its thing while your batch script goes straight to 'exit %errorlevel%'
I'm launching a script from Oracle Data Integrator using an OS command.
Long story short: the ps1 script is invoked using powershell.exe -noninteractive script
The problem is that the caller, ODI, does not recognize the termination of the powershell script, where if i call the script in the same way from the console it correctly terminate (and I can eventually read the errorlevel i set as parameter to the exit, that is the last command I wrote in the script).
Has someone had this behaviour of powershell script? It successfully executes but the command remains pending in the task manager (the same command that ran by me in the cmd prompt exit successfully).
I found the solution, just add < NUL to the caller command:
powershell.exe script.ps1 < NUL
I'm writing a script that normally will get called by another application (VMware vCenter Server). From that application I trigger a batch file (redirect.bat) and pass a variable which is the powershell script name (TestMe.ps1).
The script is placed on a Windows Server and when I go into the command prompt of the Windows Server and call the redirect script, I see that my PowerShell script runs as expected. However when I trigger it from the app the Powershell script is not run or doesn't produce output. I have confirmation that the redirect.bat is run, because the redirect.bat writes a line in a log file.
The vCenter Server app is running under Local System account. Could it be a permissions error? Is LocalSystem allowed to run Powershell scripts?
I now have no clue if the Powershell script even starts, because it (of course) is not visible in my console when running. The batch file always returns errorlevel = 0.
Any tips on how to insert debugging info in the script that should always give output? Tips on how to troubleshoot this?
redirect.bat:
set POWERSHELL=C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -nologo -noprofile -noninteractive
SET ERRORLEVEL =
echo %1 > G:\DataStoreAlarms\Log\Redirect-batch.txt
start %POWERSHELL% -command "&"%1""
echo Error level: %ERRORLEVEL% >> G:\DataStoreAlarms\Log\Redirect-batch.txt
I call redirect.bat from the command line and from the app like this:
redirect.bat G:\DataStoreAlarms\Scripts\TestGabrie.ps1
TestGabrie.ps1:
$String = "This is a test"
$String | Out-File -FilePath "G:\DataStoreAlarms\Log\Powershell.txt" -Append
Regards
Gabrie
Problem seemed to be the START command:
start %POWERSHELL% -command "&"%1""
After changing it to this, it worked:
%POWERSHELL% -command "&"%1""
Thanks for all your help.
So i have fairly easy powershell script that contains following:
import-module activedirectory
Get-ADUser -Filter *
remove-module activedirectory
If i run it from powershell it runs OK, but when i try to call it from CMD nothing happens, it just opens powershell and thats it. I am using following command to run it:
powershell.exe -file "D:\test.ps1"
I noticed also following thing, 2 powershell.exe processes run after i execute this. If i exit from CMD from one powershell then i start seeing lists that this PS query should be returning. Is there a way to get this working since i am trying to run ps script as scheduled job. The crucial part here is import module when i run it over cmd which is not happening for some reason.
It's powershell 2.0 running on Windows 2008R2. I tried this script on win 2012r2, works fine from CMD... Looks like ps 2.0 limitation?
Could be a couple of things going on here. Since your windows opens and closes you wont get to see any errors that might be occurring. What is your ExecutionPolicy set to? Get-ExecutionPolicy
When I make scheduled tasks of my scripts I usually set up my action as such
Program/Script = %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
Arguments = -ExecutionPolicy Unrestricted -NoProfile -File C:\data\script.ps1
Start In = %SystemRoot%\system32\WindowsPowerShell\v1.0
Also, I don't believe it matters in this case but be sure you have the script "Running with highest privilege" if required.
I have a list of Windows packages that I'm installing via powershell using the following command:
& mypatch.exe /passive /norestart
mypatch.exe is being passed from a list and it doesn't wait for the prior install to finish - it just keeps going. It builds up a huge window of installs that are pending installation. Also, I can't use $LASTEXITCODE to determine if the install succeeded or failed.
Is there anyway to make the installs wait before starting the next?
Start-Process <path to exe> -Wait
JesnG is correct in using start-process,
however as the question showed passing arguments, the line should be:
Start-Process "mypatch.exe" -argumentlist "/passive /norestart" -wait
The OP also mentioned determining if the install succeeded or failed. I find that using a "try, catch throw" to pick up on error states works well in this scenario
try {
Start-Process "mypatch.exe" -argumentlist "/passive /norestart" -wait
} catch {
# Catch will pick up any non zero error code returned
# You can do anything you like in this block to deal with the error, examples below:
# $_ returns the error details
# This will just write the error
Write-Host "mypatch.exe returned the following error $_"
# If you want to pass the error upwards as a system error and abort your powershell script or function
Throw "Aborted mypatch.exe returned $_"
}
Sure, write a one line batch script that runs the installer. The batch script will wait for the installer to finish before returning. Call the script from PowerShell which will in turn wait for the batch script to finish.
If you have access to how mypatch is written, you could have that create some random file when it completes that PowerShell can check for its existence in a while loop and just sleeps while the file doesn't exist.
If you don't, you could also have that batch script create a dummy file when the installer completes.
Yet another way, though probably the worst of all of these is to just hard-code a sleep timer (start-sleep) once you call the installer.
EDIT just saw JensG's answer. Didn't know about that one. Nice