How to Schedule JCL Jobs From Windows OS to Periodically and Automatically Execute on z/OS
By Subhasish Sarkar / July 19, 2021
In the latest tutorial from Subhasish Sarkar, learn how to schedule JCL jobs to periodically execute on z/OS automatically from your local machine, running the Microsoft Windows OS
Step 1: Install Zowe CLI
Read through the instructions for Installing Zowe CLI and install it in your local system. Then make sure that you have Node.js and node package manager (NPM) installed by running simple commands (to find the installed version) and a simple test program.Test Node.js installation
To see if Node.js has been successfully installed, open the Windows Command Prompt, PowerShell or a similar command-line tool, and type the node -v command. This should print a version number, so you should see something like v13.11.0 as the output.
Microsoft Windows [Version 10.0.18363.1082] (c) 2019 Microsoft Corporation. All rights reserved. C:\Users\user1>node -v v13.11.0Test NPM installation
To see if NPM has been successfully installed, type the npm -v command in the terminal. This should print the NPM version number that’s installed, so you should see something like 6.13.7 as the output.
C:\Users\user1>npm -v 6.13.7
Create a test file and run it to verify that Node.js works on your system
A simple way to test that Node.js works on your system is to create a simple JavaScript file (named hello.js, for example) and add the code console.log('Node.js is installed!')to the file. To run the code, open your command-line program, navigate to the location where you have saved the file, and type node hello.js. This starts Node.js and runs the code in the hello.js file. You should see the output: Node.js is installed!
Microsoft Windows [Version 10.0.18363.1082] (c) 2019 Microsoft Corporation. All rights reserved. C:\Users\user1>CD C:\Users\user1\Desktop C:\Users\user1\Desktop>node hello.js Node.js is installed!Zowe CLI installation verification
At the command prompt, run the zowe --version command. The output displays the current installed version of Zowe CLI, and you should see something like 6.22.0 as the output. If you see the desired output, you can be confident that Zowe CLI is successfully installed on your system.
C:\Users\user1>zowe --version 6.22.0
Step 2: Code Some REXX EXECs
You need to code four simple REXX EXECs. Let’s create the following REXX EXECs:- SMPREX00
- SMPREX01
- SMPREX02
- SMPREX03
SMPREX00 ****** ********************************* Top of Data ********************************** 000001 /* REXX **************************************************************/ 000002 SAY ' >>>>> ' 000003 SAY ' REXX PROGRAM #01' 000004 SAY ' <<<<< ' ****** ******************************** Bottom of Data ******************************** SMPREX01 ********************************* Top of Data ********************************** /* REXX **************************************************************/ SAY ' >>>>> ' SAY ' REXX PROGRAM #02' SAY ' <<<<< ' ******************************** Bottom of Data ******************************** SMPREX02 ********************************* Top of Data ********************************** /* REXX **************************************************************/ SAY ' >>>>> ' SAY ' REXX PROGRAM #03' SAY ' <<<<< ' ******************************** Bottom of Data ******************************** SMPREX03 ********************************* Top of Data ********************************** /* REXX **************************************************************/ SAY ' >>>>> ' SAY ' REXX PROGRAM #04' SAY ' <<<<< ' ******************************** Bottom of Data ********************************
As you can see, each REXX program prints only three display messages. This is to keep things simple—remember, we are not here to learn how to code REXX EXECs!
Step 3: Code Some JCL Jobs
Now it’s time to code four JCL jobs. Let’s name them REXEXC00, REXEXC01, REXEXC02 and REXEXC03.Job REXEXC00 runs the first REXX program, SMPREX00, in the first job step, and sets the maximum condition code of the job to 01 in the second and final job step.
REXEXC00 ********************************* Top of Data ********************************** //REXEXC00 JOB (5990),'BATCH IVP',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID, // TIME=NOLIMIT //********************************************************************** //********************************************************************** //REXJ EXEC PGM=IKJEFT01,DYNAMNBR=45 //SYSPROC DD DISP=SHR,DSN=HLQ1.HLQ2.JOBS //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * %SMPREX00 //* //IDCAMS EXEC PGM=IDCAMS,COND=(0,NE,REXJ) //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //SYSIN DD * SET MAXCC=1 //* // ******************************** Bottom of Data ********************************Note: DDName SYSPROC references the partitioned data set (PDS) that houses the REXX EXEC or the SMPREX00 program source code as a member.
Job REXEXC01 runs the REXX program SMPREX01.
REXEXC01 ********************************* Top of Data ********************************** //REXEXC01 JOB (5990),'BATCH IVP',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID, // TIME=NOLIMIT //********************************************************************** //********************************************************************** //REXJ EXEC PGM=IKJEFT01,DYNAMNBR=45 //SYSPROC DD DISP=SHR,DSN=HLQ1.HLQ2.JOBS //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * %SMPREX01 //* // ******************************** Bottom of Data ********************************Job REXEXC02 runs the third REXX program, SMPREX02, in the first job step, and sets the maximum condition code of the job to 02 in the second and final job step.
REXEXC02 ********************************* Top of Data ********************************** //REXEXC02 JOB (5990),'BATCH IVP',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID, // TIME=NOLIMIT //********************************************************************** //********************************************************************** //REXJ EXEC PGM=IKJEFT01,DYNAMNBR=45 //SYSPROC DD DISP=SHR,DSN=HLQ1.HLQ2.JOBS //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * %SMPREX02 //* //IDCAMS EXEC PGM=IDCAMS,COND=(0,NE,REXJ) //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //SYSIN DD * SET MAXCC=2 //* // ******************************** Bottom of Data ********************************Job REXEXC03 runs the fourth REXX program, SMPREX03.
REXEXC03 ********************************* Top of Data ********************************** //REXEXC03 JOB (5990),'BATCH IVP',CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID, // TIME=NOLIMIT //********************************************************************** //********************************************************************** //REXJ EXEC PGM=IKJEFT01,DYNAMNBR=45 //SYSPROC DD DISP=SHR,DSN=HLQ1.HLQ2.JOBS //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * %SMPREX03 //* // ******************************** Bottom of Data ********************************
Step 4: Learn How to Manage Zowe z/OSMF Profiles
Now let’s create a Zowe z/OSMF profile to be used specifically for this PoC project. Run the following command at the command prompt:zowe profiles create zosmf-profile Zowe-zOSMF-Profile-SS-POC-Project --host LPR1 --port nnnnn --user XXXXXX --password ZZZZZZZZ --reject-unauthorized falseThis creates a Zowe z/OSMF profile called “Zowe-zOSMF-Profile-SS-POC-Project” to connect to z/OSMF at host LPR1 and port nnnnn, and allow self-signed certificates.
C:\Users\user1>zowe profiles create zosmf-profile Zowe-zOSMF-Profile-SS-POC-Project --host LPR1 --port nnnnn --user XXXXXX --password ZZZZZZZZ --reject-unauthorized false Profile created successfully! Path: C:\Users\user1\.zowe\profiles\zosmf\Zowe-zOSMF-Profile-SS-POC-Project.yaml host: LPR1 port: nnnnn user: XXXXXX password: ZZZZZZZZ rejectUnauthorized: falseReview the created profile and edit if necessary, using the profile update command.
Set the profile (that you just created) as the default profile for type zosmf. Run the following command:
C:\Users\user1>zowe profiles set-default zosmf-profile Zowe-zOSMF-Profile-SS-POC-ProjectThe default profile for zosmf is set to Zowe-zOSMF-Profile-SS-POC-Project.
To check if your default profile for type zosmf was set correctly, run the zowe profiles list zosmf-profilescommand:
C:\Users\user1>zowe profiles list zosmf-profiles SSMtM2020 Zowe-zOSMF-Profile-SS-POC-Project (default)If you already have a Zowe z/OSMF profile that you want to use and you don’t want to create a new one, you can use your existing profile. Just make sure that you have the correct profile set as your default profile for type zosmf.
For a list of various commands that you can issue through the Zowe CLI, run the zowe --help command.
Step 5: Create Your Windows Batch Zowe Script
Let’s name our Windows batch Zowe script “Batch-Execution-#01.bat”. The batch script should consist of the following lines of code:SETLOCAL ENABLEDELAYEDEXPANSION cd C:\Users\user1\AppData\Roaming\npm set LogFileName=Output for /f "tokens=*" %%i in ('zowe zos-jobs submit data-set "PDSNAME(REXEXC00)" --wfo --rff retcode --rft string') do set RC=%%i if "%RC%"=="CC 0001" ( for /f "tokens=*" %%i in ('zowe zos-jobs submit data-set "PDSNAME(REXEXC01)" --wfo --rff retcode --rft string') do set RC=%%i ) if "%RC%"=="CC 0000" ( for /f "tokens=*" %%i in ('zowe zos-jobs submit data-set "PDSNAME(REXEXC02)" --wfo --rff retcode --rft string') do set RC=%%i ) if "%RC%"=="CC 0002" ( for /f "tokens=*" %%i in ('zowe zos-jobs submit data-set "PDSNAME(REXEXC03)" --wfo --rff retcode --rft string') do set RC=%%i ) if "%RC%"=="CC 0000" ( echo Logged time = %time% %date%, ALL THE FOUR JOBS RAN SUCCESSFULLY ON z/OS!> C:\Users\subsarka\Desktop\%LogFileName%.txt echo Logged time = %time% %date%, THE WINDOWS BATCH ZOWE SCRIPT 'Batch-Execution-#01.bat' HAS SUCCESSFULLY COMPLETED ITS EXECUTION.>> C:\Users\subsarka\Desktop\%LogFileName%.txt )Note that this Windows batch Zowe script is used for multiple JCL jobs submission post verification of MAXCC. The code line cd C:\Users\user1\AppData\Roaming\npm is mandatory, as Jenkins doesn’t recognize Zowe as an executable file, so you must provide the path. Delayed expansion can cause variables within a batch file to be expanded at execution time rather than at parsing time, and this option is turned on with the SETLOCAL EnableDelayedExpansion command. for /f is used as a loop command to perform an action against each Zowe command. tokens=* means any output and %%i stores that output. Two Zowe commands placed one after another will not work, and post execution of the first command the script will exit. Therefore, using the for command you can run multiple Zowe commands in a single script. The script runs four JCL jobs, one after another, by waiting for the job to come to the output queue (wfo), and then recording their MAXCC and proceeding with the execution of the next JCL job only when the specified logical MAXCC condition is met. If required, you can include comments in your script by using the REM statement, as follows.
REM This is used for REMarks in a batch script file. This is not an executable statement.Your Windows batch Zowe script has been coded so that all four of the JCL jobs will be submitted for execution on z/OS. As you can understand, the MAXCC being returned by a job after it has completed its execution holds the key to the submission of all the four JCL jobs to z/OS.
You can save the batch script anywhere on your local Windows machine. I have chosen to create the file in the path ‘C:\Users\user1\Desktop’. In the same path, create a new, empty text file called ‘Output.txt’.
Step 5: Create a Simple Python Script
In the same path where our Windows batch Zowe script and ‘Output.txt’ file are located, create a Python script named ‘AutoSchedule.py’. The Python script contains the following few lines of code (see Figure 1).
Figure 1. Python script lines of code
Step 6: Convert the Python (.py) Script Into an Executable (.exe)
Now, we will convert the Python (.py) script into an executable (.exe) by utilizing a Python package called PyInstaller. If not already installed on your local system, you can install PyInstaller by executing the command ‘pip install pyinstaller’.To create the executable, execute the command ‘pyinstaller --onefile {FILE_NAME}.py’. In our case, we need to execute the command:
pyinstaller --onefile "C:\Users\user1\Desktop\AutoSchedule.py"Upon successful execution of the command, the following two lines displayed at the end of the command output are of interest to us.
INFO: Appending archive to EXE C:\Users\user1\Desktop\dist\AutoSchedule.exe INFO: Building EXE from EXE-00.toc completed successfully.‘C:\Users\user1\Desktop\dist\AutoSchedule.exe’ denotes the path where you can find the executable.
When the executable has been created successfully, three folders, namely, dist, __pycache__ and build, along with a ‘AutoSchedule.spec’ file, will exist at the path ‘C:\Users\user1\Desktop’ (see Figures 2-6).

Figure 2. Folders dist, __pycache__ and build, along with the ‘AutoSchedule.spec’ file, get created with the successful creation of the executable

Figure 3. Content of the dist folder

Figure 4. Content of the __pycache__ folder

Figure 5. Content of the build folder; note that a sub-folder named ‘AutoSchedule’ gets created within the build folder.

Figure 6. Content of the ‘AutoSchedule.spec’ file
Step 7: Scheduling Part
Let’s say we’ve decided that our four JCL Jobs should get automatically executed on z/OS every two minutes. We will make use of the ‘SCHTASKS /CREATE’ command to achieve this. You can learn more about the options to create a scheduled task by running the SCHTASKS /CREATE /? command in the Windows Command Prompt.Let’s create a .bat file named ‘AutoSchedule.bat’ in the path ‘C:\Users\user1\Desktop’. The content of the .bat file should be:
SCHTASKS /Create /SC MINUTE /MO 2 /TN AutoSched /TR C:\Users\user1\Desktop\dist\AutoSchedule.exe /FAs you can probably understand, the batch script executes the Python executable that we had created previously and the frequency of execution of the executable is every two minutes indefinitely.
It’s now time to execute the batch script, ‘AutoSchedule.bat’. After the batch script has executed successfully, you should be able to see output like the one shown below.
C:\Users\user1\Desktop>AutoSchedule.bat C:\Users\user1\Desktop>SCHTASKS /Create /SC MINUTE /MO 2 /TN AutoSched /TR C:\Users\user1\Desktop\dist\AutoSchedule.exe /F SUCCESS: The scheduled task "AutoSched" has successfully been created.The ‘Success’ message clearly tells us that a scheduled task named ‘AutoSched’ has been successfully created. To view the scheduled task ‘AutoSched’, we will use the Microsoft Windows Task Scheduler Graphical User Interface (GUI) (see Figure 7).

Figure 7. Locate the scheduled task ‘AutoSched’ using the Microsoft Windows Task Scheduler GUI. Note that the trigger condition says that once the task has been scheduled, it will be triggered every two minutes indefinitely.
Double click on the Task Name entry for the scheduled task ‘AutoSched’ (see Figure 8).

Figure 8. More details about the scheduled task ‘AutoSched’ displayed using the Microsoft Windows Task Scheduler GUI
To use the Microsoft Windows Task Scheduler GUI, search using the words ‘Task Scheduler’ (see Figure 9).

To confirm that the scheduled task ‘AutoSched’ is executing every two minutes, check the message in the ‘Output.txt’ file.
Logged time = 16:08:47.62 Mon 07/12/2021, ALL THE FOUR JOBS RAN SUCCESSFULLY ON z/OS Logged time = 16:08:47.62 Mon 07/12/2021, THE WINDOWS BATCH ZOWE SCRIPT 'Batch-Execution-#01.bat' HAS SUCCESSFULLY COMPLETED ITS EXECUTION. The Python script 'AutoSchedule.py' has successfully completed its execution.The time portion should be updated every two minutes as the Python script completes successful execution every two minutes.
You should also be easily able to verify the fact that all the four JCL jobs—namely, REXEXC00, REXEXC01, REXEXC02 and REXEXC03—are successfully getting submitted to z/OS every two minutes.
Tagged as:
z/OS / Linux on IBM Z / z/VM / z/VSE / Article / Application development / TechTips / Performance / Open source on IBM Z / Automation / REXX / Node.js
About the author
Subhasish Sarkar (SS) is an IBM Z Champion and a senior product manager (IMS Product Management) at BMC Software.
See more by Subhasish Sarkar