Environment:
Master Linux Jenkins server
Two Windows slave nodes
The windows slaves are running as a service
First Test
I create a Pipeline and use a use a "Execute Windows batch command" in the build section
In the Command box I put "C:\Jenkins\mytest.bat"
I checked the box "Restrict where this project can be run" and write down the name of the Windows slave
I built the pipeline and was successful
Second Test
I create a Declarative Pipeline as follows:
pipeline {
agent { label 'SiebelWindows' }
stages {
stage('Test Bat') {
steps {
bat 'C:\\Jenkins\\mytest.bat'
//bat 'start cmd.exe /c C:\\Jenkins\\mytest.bat'
//call C:\\Jenkins\\mytest.bat
}
}
}
}
In this case the build FAIL with error "cmd is not recognized as a internal o external command"
So, why can I run the .bat with a non-declarative pipeline, but fails with a declarative pipeline?
When I display the "Path" and the "PATH" variables, this was the result
Original_Path
The solution was redefine the PATH enviorement variable, like this
environment {
PATH = "C:\\WINDOWS\\SYSTEM32"
}
#JustAProgrammer aske me if C:\WINDOWS\SYSTEM32 was in the PATH of my Windows machine, and that is correct, but seems like Jenkins master do not know the slave's Windows Path.
I resolve my issue, but I still looking for a complete solution, I need to set the PATH enviorement variable with ALL the path, no only C:\WINDOWS\SYSTEM32
If someone has the problem too although the path variable looks correct, check the length of the PATH variable (echo %PATH%). Windows has some restriction of the length of an environment variable (see Microsoft DevBlog).
Remove some entries or set the PATH explicit like already mentioned.
Check also the configuration of the Environment Injector Plugin, which can override the default user and system PATH variable.
Related
I have a project which builds an application and whenever it builds the application the names it generates are like this MyApp1.1.exe, myapp1.2.exe, myApp,1.3.exe etc. I would like to deploy the application in another environment whenever there is a new build. But the problem is that I'm using the following in command in the batch script, which is is keep throwing me an error
MyApp1.*.exe
But it always throws an error in the command line saying that 'MyApp1.*.exe' is not recognized as internal or external command, operable program or batch file. I know that this should be very simple but I could not seem to find any solution
cmd, which is used to run batch-files, requires that you run for loops to do something for each item. You therefore need to give for some criteria and it will return the list based on that. You can then do something with these metavariables.
#echo off
for %%i in (MyApp*.*.exe) do echo start "" "%%~i"
For the purpose of this demonstration, I am not actually running the executable's, instead I just echo the full command. If you feel that it is suitable for this purpose, then simpy remove echo from the echo start "".. section.
I've been trying to get a Jenkins deploy job to work by running a batch script to do the install of an msi from the Jenkins build machine itself. I've given the appropriate access rights, but still am not able to run the following command remotely, using WMIC
wmic /node:myServerIp /user:"clientpc\my-user" /password:"my-password" process call create "D:\someDir\someOtherDir\test.bat"
The follow response from the above command:
Executing (Win32_Process)->Create()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
ReturnValue = 9;
};
After some research, it looks like return value of '9' is 'Path not found' according to https://msdn.microsoft.com/en-us/library/aa389388(v=vs.85).aspx, but I've verified that the path exists on the remote server.
The test.bat file that I'm trying to run is very simple, and should just write to a text file.
#echo This is a test.> test.txt
I've verified that both files exist on the server, and have granted 'EVERYONE' to the shared folder 'someDir'.
I have tried prefixing 'cmd.exe /c' to the path called:
wmic /node:myServerIp /user:"clientpc\my-user" /password:"my-password" process call create "cmd.exe /c D:\someDir\someOtherDir\test.bat"
...for which I receive:
Invalid Verb Switch.
I've verified that the user access is correct by providing a bad password, in which case permission is denied.
EDIT:
Changed the path from D:\someDir\someOtherDir\test.bat to D:\\someDir\\someOtherDir\\test.bat but now receive the following error:
ERROR:
Description = The RPC server is unavailable.
EDIT 2:
Looks like the RPC user I was using was the cause for the error. Still troubleshooting, but when I use my AD user, as opposed to the administrator I created to run this, I get the following AGAIN...
Executing (Win32_Process)->Create()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
ReturnValue = 9;
};
I was able to get the following to work on an Active Directory domain.
Wmic /node:"ComputerName" process call create "cmd.exe /c (net use o: /delete /y & net use o: \\Server\share /user:Domain\Administrator Password & o:\Dir\Subdir\test.cmd) >> c:\users\MyUser\testout2.txt"
The very simple contents of test.cmd:
echo Just a test >> c:\users\MyUser\testout.txt
date /t >> c:\users\MyUser\testout.txt
time /t >> c:\users\MyUser\testout.txt
The "job" is being sent to "ComputerName" on the domain. The batch/script file the job runs is on a network share. The job running on "ComputerName" will not see any mapped drives, so I delete and map a drive. I don't believe it is ever necessary to delete the drive, but I added that for completeness sake.
After execution, testout2.txt shows the batch file executing the commands and
testout.txt contains the results of the batch file commands as expected.
Things to watch out for:
As mentioned, mapped drives are not visible from the remote job
You are executing in the target machine's environment - drive letters need to make sense to that machine
Internal commands such as 'echo' require the job starts with 'CMD.EXE /c'
Group multiple commands inside parentheses and separate with ampersands (&)
Don't collide file access. I use testout.txt and testout2.txt files. If I had given them the same name, one set of outputs would have been lost.
Nothing you do this way will ever be visible to the user; the job is run in such a way that it can not display on the user's screen.
Sending a password in clear text as I show in the example is a security hazard and should be avoided. I'm not sure of a better way to map drives in this context however.
on local computer are installed an Oracle client (11.2.0) and an OC4J Server (Oracle Containers for J2EE 10g (10.1.3.5.0) (build 090727.2000.36696)), both of them are using the ORACLE_HOME enviroment variable so I need to set ORACLE_HOME pointing to server folder only when server starts
I'm trying to generate batch file that must do:
Set enviroment variable ORACLE_HOME
Start up OC4J server
Unset ORACLE_HOME variable
I'm trying with this script but the third statement never runs.
call setx -m ORACLE_HOME "C:\Servers\oc4j_extended_101350"
call C:\Servers\oc4j_extended_101350\bin\oc4j -start
call REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V ORACLE_HOME
All of this commands works fine executing individually. But, on the same batch script the Start up OC4J "never" ends. Any idea how can i do this works?
Any help would be appreciated
The batch file to start the Oracle server just needs the following 2 lines:
set "ORACLE_HOME=C:\Servers\oc4j_extended_101350"
C:\Servers\oc4j_extended_101350\bin\oc4j.exe -start
That's it if oc4j.exe is not a console application and therefore command processor immediately continues processing the batch file after starting oc4j.exe resulting in closing command process.
Otherwise use:
set "ORACLE_HOME=C:\Servers\oc4j_extended_101350"
start "Oracle Server" C:\Servers\oc4j_extended_101350\bin\oc4j.exe -start
Why this works?
Windows creates automatically a copy of the entire environment table of current process for the new process on creating a new process.
For the command process executing the batch file ORACLE_HOME is set in its environment table as specified in the batch file.
On starting the Oracle server this environment table is copied by Windows for the Oracle server including ORACLE_HOME as currently defined. What is defined in Windows registry does not matter and is not taken into account. The Oracle server does not see if there is also ORACLE_HOME set at all and if so with which value for parent processes or other processes running parallel.
A simple example to demonstrate environment table management by Windows.
Open a command prompt window and enter set x=Hello.
Type set x and you see x=Hello.
Execute start resulting in opening a second command prompt window.
Type in this second command prompt window set x and you get displayed also x=Hello.
Switch back to first command prompt window and run set x=Hi.
Type in this first command prompt window set x and you see x=Hi.
Switch again to second command window, type set x and you still see set x=Hello.
This second command process has got a copy of first command process. So what is changed now in the environment table of first command process is not visible for second command process.
Execute in second command window set x=Bye and verify it with set x.
Switch back to first command window and enter set x.
It is still output x=Hi because also the parent process does not get back what the child process modifies in its copy of the environment table.
Switch to second command window and enter set path= to delete environment variable PATH from environment table of this process.
Execute once more start to open from second command window a third command window.
Enter set path and you get displayed just
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
What happened with system PATH?
System PATH as well as user account related PATH are still set in Windows registry and build together PATH for new processes started from desktop Explorer process. But in the environment tables of second and third command process there is no environment variable PATH anymore. Those two processes must work now without environment variable PATH. Of course for the first command process and all other running processes PATH still exists in their environment tables.
I am trying to run a groovy script using Install4j. I have laid down the files for groovy and added to an environment variable "Groovy_Home". Then I added that to the Path Environment Variable. When I open the command window I am able to run "Groovy buildenv.groovy". It works! Almost magically! However when I use Install4j to create the .bat file that has a working dir of the .groovy file and runs this script:
#echo on
groovy buildenv.groovy > buildenv.output.log
It doesn't seem to work! it complains that it has no idea where the groovy is at. I have added the "Specific environment variables" to "PATH=${PATH}". But that doesn't seem to work either... Any help is greatly appreciated.
Check if the "Include parent environment variables" property of the "Run executable or batch file" action is selected.
If yes, select the "Show console window" property and its "Keep console window" child property and add
SET
to your batch file so you can check the environment variables.
The solution for me was to use Specific environment variables as you told, but not setting PATH=${PATH} (what it does if path is already set?).
Instead in the installer process I add a step of Directory selection type to let user choose the directory where groovy is installed, and use the user entry to set a installer variable. Then I use this variable in the Specific environment variables property of the Run executable or batch file action to set something like PATH=${installer:userGroovyHome}, where userGroovyHome is the Variable name for selection property of Directory selection
I have a bunch of batch files which I want to run sequentially. One of them runs an MSI which adds a folder to the PATH. How can I make sure that subsequent batch files will notice this change, without restarting CMD? I'm using Windows Server 2008 R2 x64.
I've tried call, cmd /c and start "", in the hope that starting a new process will work, but it doesn't.
in run-both-scripts.bat
call script1.bat <-- This runs an MSI which modifies the PATH
call script2.bat <-- This relies on the PATH changes which were made by the MSI in script1.bat
To clarify: this is fairly straightforward to reproduce.
Start CMD
Create an environment variable manually, not using setx, to mimic what the MSI does.
Right click on Computer -> Properties -> Advanced System Settings -> Environment variables -> New
Create an environment variable called, say, hello with the value hi there.
In your CMD window, type echo %hello%. You'll get %hello%.
Try cmd /c "echo %hello%. You'll get %hello%.
Try start "" to open a new CMD process; type echo %hello%. You'll get %hello%.
Try start "" echo %hello% to run the command in a new CMD process. You'll get %hello%.
Finally, try manually opening a new CMD window from the Start menu and type echo %hello% from there. You'll see hi there.
So you can see that the only way I've been able to make CMD see the change to the environment variable is by restarting CMD.
Ok, did some research, and found out why the soloutions we've been throwing at you don't work. When you start cmd.exe as an application, it looks at the current environment variables and copies it to memory. When you start cmd in a batch file, it will not look at the environment variables, instead it will look at the variables set in the current batch file, and utilise those. Thats the problem when your storing data on memory. The only way this is possible is if you copy the current environment variables into a text file as memory on a hard disk. Now, the question is how to go about doing this.
After heavy research, the only thing I could find that related to the topic was the use of start /i, however, when I tested this it didn't work. (start /? for more info).
In other words, other the setx, I don't think this is possible with batch.
Mona