I have the following function definition in my profile:
function design {
Set-Location $env:CC72\Designer
.\RunDesigner.bat
}
But when I execute the function design, PowerShell executes batch RunDesigner.bat twice and two instances of it are started:
PS C:\Users\s3201> design
Starting Designer...
Starting Designer...
PS C:\customer\Designer>
Why?
Update 1
The content of the batch is the following:
set LOC_WIN32=c:\Customer\xxxxxx
set LOC_UNIX=c:/Customer/xxxxxxx
echo Starting Designer...
start %LOC_WIN32%\bin\xxxxxxx.exe %LOC_UNIX%/Designer/lib/xxxxxxxx.tcl -guiFile %1
Update 2
If I start Vim from the directory where mentioned batch resides then they start both - Vim and batch file.
Therefore the reason for the message in begin of the question is clear - PowerShell tries to start that batch first, does not find it, writes the message and the starts Vim. But why it tries to start the that batch first?
Obviously, the root cause is in some PowerShell definitions. Which ones? (Aliases I checked).
Related
I'm calling a bat-file from a step in my yaml file. The bat is located locally on the PC where the build agent is.
The bat is called successfully. It changes the PATH-variable and runs a program afterwards. The program runs successfully however when finished the build step is still marked as unsuccessful because
[error]PowerShell exited with code '1'.
As background information as to why I'm using a bat-file instead of ps1: I'm migrating our current build and it runs over a central bat-file. I don't want to change it.
Is there an environment variable I can change or anything else I can do to ensure the powershell returns 0 instead of 1?
Have you considered changing the batch file exit code?
Exit codes for batch files
Use the command EXIT /B %ERRORLEVEL% at the end of the batch file to
return the error codes from the batch file
EXIT /B at the end of the batch file will stop execution of a batch file.
use EXIT /B < exitcodes > at the end of the batch file to return custom return codes.
Environment variable %ERRORLEVEL% contains the latest errorlevel in the batch file,which is the latest error codes from the last command executed. To know about Environment variable see the below note.
Note: Environment variables are a set of dynamic named values that can
affect the way, running processes will behave on a computer. For
example, an environment variable with a standard name can store the
location that a particular computer system uses to store user profile
this may vary from one computer system to another.
In the batch file , it is always a good practice to use environment
variables instead of constant values. Since the same variable get
expanded to different values on different computers.
Example:
Batch file for Copying File to a Folder
md "C:manageengine"
copy "\\sharename\foldername\samplefile.txt" "C:\manageengine"
exit /b %ERRORLEVEL%
https://www.manageengine.com/products/desktop-central/returning-error-code-on-scripts-how-to.html
EDIT: Some more thoughts about the problem- The batch file probably returned 1 as an exit code because one of the commands or programs used within it returned some kind of error code (or at least didn't return 0 exit code).
for summing up, your question was not very clear mainly because you didn't separate all the factors and variable withing your problem, thus not knowing where the problem is.
Force changing the exit code isn't the right way to fix your problem.
I have a batch script which performs file version controlling after a Backup event has taken place. This batch script, writing to a normal txt logfile, calls a PowerShell script to send this Logfile as an attachment with a success notification email. I have managed to release the writing lock on the log file, to allow PS to attach and send the file, but the Batch script does not stop after the entire sequence has been completed.
When I check the log file, I see that the shell instance has placed a 'Pause' in the script, instead of a self-termination (as it is instructed), and results in:
Press any key to continue... with a waiting shell
an app locked logfile, which won't allow the script to run again, unless the logfile is released.
This is the sequence of events:
The only Pause I have, is in < bak_send_exec.bat > - its sole purpose is to start a PS script:
PowerShell.exe -noprofile -executionpolicy bypass
If I remove it, the PS does not start. If I have it in there, the PS starts and executes flawlessly, but the logfile stays locked in a shell instances which is in Paused state, until someone kills the cmd.exe instances which locked the file.
This runs on a weekend at 01:00 am, so user intervention should not be required.
VC Script Summary:
This inter-connected batch files renames two identical files (in different locations) with timestamps. The timestamp is written to a variable for use in a notification email, which is sent using a PowerShell command. The entire process is logged to a txt log file (file overwritten when script runs again), and the log file is included with a Notification Email, mentioned earlier.
Script Calls:
Initial Start Command: Triggers the Version Control Procedures and Logs Progress with versioncontrol_post.bat > TSLog.txt 2>&1
versioncontrol_post.bat: Performs main procedure, then ends with CALL bak_send_exec.bat
bak_send_exec.bat: The suspected cause... Coding of entire file is three lines long, but required as mentioned earlier, for policy relaxation:
#ECHO OFF
PowerShell.exe -noprofile -executionpolicy bypass -file bak_send.ps1
PAUSE
bak_send.ps1: Performs main procedure to make a copy of the temporary log (TSLog.txt) to its final home, releases the TSLog file to work with the new duplicate of it, and continues to take that new duplicate and attach it to an email and sends email. The final line in the procedure is EXIT.
Fault finding tells me that the issue is not with the PowerShell script, but rather with the script that calls it. Taking out the PAUSE command results in the PowerShell not starting.
Does anyone have a possible solution to this "feature"?
Real n00b to powershell. I was wondering if the community could help me build a pretty simple script.
Really, I can achieve everything I need in windows batch files - but these only complete one task at a time. I want a master script (a powershell script) to call each individual batch process in turn. That is, I want to run Batch_1 and then run Batch_2 only when a task from a program that Batch_1 calls has finished.
Is this possible? Is it a case of using some form of IF THEN ELSE type scenario or is there a way to make powershell wait for some event to happen?
Thanks!
GPC
You can use the FOR command, from regular windows shell (cmd.exe) to solve this problem. The following command executes every cmd file in current directory:
FOR %f IN (*.cmd) DO %f
The following command executes every file, in order, as returned by inner ´DIR´ command:
FOR /F %f IN ('DIR /b /oen *.cmd *.bat') DO %f
Normally calling out from a batch file to a console program is synchronous. A PowerShell script for this is trivial:
master-script.ps1 contents:
---------------------------
c:\batch1.bat
c:\batch2.bat
Now if the batch file is calling a Windows subsystem exe (non a console EXE) then this gets trickier because those execute async. If that's the case, update your question to indicate that.
Let's say I have 5 batch files that run sequentially one after another (executed via the Windows task scheduler on a normal Windows XP PC):
Script1.bat
Script2.bat
Script3.bat
Script4.bat
Script5.bat
Suppose one of the scripts fail (an error condition is detected -- details on how this happens is not important for my question here). How do I stop the other scripts from running if they all run within the task scheduler? For example, if Script1.bat fails, I don't want to run Script2-5.bat. If Script3.bat fails, I don't want to run Script4-5.bat, etc.
I thought about writing a flag value to a temporary file that each script would read from. At the beginning of each script (except for the first one), it will check to see if the flag is valid. The first script would clear out this flag at the beginning each time these set of batch files run.
Surely there is a better way to do this or maybe there is a standard for how to handle this type of situation? Thanks!
Write a master.bat file that conditionally calls each of the scripts in sequence. Then schedule the master instead of directly scheduling the 5 scripts.
#echo off
call Script1.bat
if %errorlevel%==0 call Script2.bat
if %errorlevel%==0 call Script3.bat
if %errorlevel%==0 call Script4.bat
if %errorlevel%==0 call Script5.bat
In vbscript, how do I run a batch file or command, in the current cmd prompt window,
without starting a new process.
For example. According to script56.chm (the vbscript help apparently)
Windows Script Host
Run Method (Windows Script Host)
"Runs a program in a new process"
So if I have code that uses that e.g. a VBS file, and a BAT file.
An environment variable g has the value abc g=abc
from that command window,
The VBS file calls the BAT file with windows scripting host Run.
The bat process sets g=z. and finishes.. and the vbs process finishes.
The environment variable is left untouched as g=abc.
I know
CreateObject("Wscript.Shell").Run "c:\test.bat", 0
starts a new window as is clear when using 1 instead of 0. (since 0 hides the window)
How do I
-run the bat file from the vbs, in the same cmd environment that the vbs was called in, so changes affect the cmd environment it was called in?
-In the two windows case which this one is at the moment, how do I access the environment of the parent cmd window, from the batch file?
how do I run a batch file or command, in the current cmd prompt window, without starting a new process?
I don't think you can; your vbscript runs under a script host engine (such as cscript.exe or wscript.exe), and batch files are interpreted by the command interpreter (typically cmd.exe). Both are separate executables and neither is, to my knowledge, available as an in-process library, so you cannot interpret .vbs and .cmd files within the same process. I also highly doubt that the script host engine that is running your VBScript also could run the batch file in its parent cmd.exe - I don't think you can 'inject' a new batch file into a running cmd.exe.
how do I access the environment of the parent cmd window, from the batch file?
Not just access, but change - MSDN's "Changing Environment Variables" is quite explicit on this: "Altering the environment variables of a child process during process creation is the only way one process can directly change the environment variables of another process. A process can never directly change the environment variables of another process that is not a child of that process." You are trying to change the environment of the parent, not child, process. (I do wonder what 'directly' means in the context of this quote, though).
I would guess that the reason for this is security; imagine the havoc that could be wreaked if arbitrary processes could (maliciously or accidentally) change the PATH (or COMSPEC) environment variable of a running process, such as your vbscript host engine process - it could fail to launch your bat file entirely, breaking your program.
It would seem that you're out of luck - however, there are lots of other mechanisms for passing information between processes. Here are a couple of suggestions that are fairly simple to implement when talking between a batch file & vbscript, although it's by no means exhaustive:
Exit codes
Writing to & Parsing the consoleoutput (stdout) or a temp file
If you absolutely need to set environment variables in the parent cmd.exe (and also absolutely need the intermediate step of a vbscript), then you may have to write a wrapper batch file which runs the vbscript, consumes information produced by it and then sets environment variables; because the wrapper cmd is executing in the top-level cmd process, it will be able to change the env vars there.
Footnote: Note that you can change the permanent system/user environment variables (as opposed to process environment variables) from within a VBScript, but I wouldn't recommend this if you are trying to create a transient state; besides this won't affect already-running processes (like the parent cmd.exe) anyway.