<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>The Wombelix Post - Control-M</title><link href="https://dominik.wombacher.cc/" rel="alternate"/><link href="/feeds/tag_control-m.atom.xml" rel="self"/><id>https://dominik.wombacher.cc/</id><updated>2021-08-21T00:00:00+02:00</updated><entry><title>Create BMC Control-M usage reports from CLI instead GUI</title><link href="https://dominik.wombacher.cc/posts/create-bmc-control-m-usage-reports-via-cli-instead-gui.html" rel="alternate"/><published>2021-08-21T00:00:00+02:00</published><updated>2021-08-21T00:00:00+02:00</updated><author><name>Dominik Wombacher</name></author><id>tag:dominik.wombacher.cc,2021-08-21:/posts/create-bmc-control-m-usage-reports-via-cli-instead-gui.html</id><summary type="html">&lt;!-- SPDX-FileCopyrightText: 2023 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;I had to solve a quite interesting problem recently, the Task was to generate Control-M usage reports on a monthly basis and send them via E-Mail.&lt;/p&gt;
&lt;p&gt;Control-M provides a Solution  ... &lt;a class="read-more" href="/posts/create-bmc-control-m-usage-reports-via-cli-instead-gui.html"&gt; [read more]&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;!-- SPDX-FileCopyrightText: 2023 Dominik Wombacher &lt;dominik@wombacher.cc&gt; --&gt;
&lt;!--  --&gt;
&lt;!-- SPDX-License-Identifier: CC-BY-SA-4.0 --&gt;
&lt;p&gt;I had to solve a quite interesting problem recently, the Task was to generate Control-M usage reports on a monthly basis and send them via E-Mail.&lt;/p&gt;
&lt;p&gt;Control-M provides a Solution for that: &lt;strong&gt;BMC Control-M Usage Reporting Tool&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;But it's a Java GUI Application that can't be automated or run in Batch mode. So I decided to write a small &amp;quot;wrapper&amp;quot; in Java which re-use the original Classes from the Control-M Usage Reporting Tool (Version 9.0.00).&lt;/p&gt;
&lt;p&gt;That way the results are 100% identical without any (unsupported) customizing but it can be executed from the command line.&lt;/p&gt;
&lt;p&gt;I want to make clear: All Control-M Copyrights belong to BMC, including the Java Code and Classes. All what my little wrapper does, is loading the Class which comes with the original Tool and call the same methods as it would be done in the GUI to generate the report.&lt;/p&gt;
&lt;p&gt;Therefore I want to share the Code of my wrapper and the necessary cmd file (yes, all this is only running on Windows due to hardcoded backslashes in file paths in the used Class) to start it.&lt;/p&gt;
&lt;p&gt;Downloading the required Jar file from BMC, Building the Project (I used &amp;quot;Export: Runnable JAR file&amp;quot; in Eclipse), adding the necessary &lt;em&gt;data/env.txt&lt;/em&gt; and &lt;em&gt;data/config.ini&lt;/em&gt; is up to you.
I suggest you take a look into the directory structure and files of the &lt;em&gt;BMC Control-M Usage Reporting Tool&lt;/em&gt;, it isn't that hard figure it out and get it working :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ctmusagereport&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="code java literal-block"&gt;
&lt;span class="pygments-kn"&gt;package&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nn"&gt;ctmusagereport&lt;/span&gt;&lt;span class="pygments-p"&gt;;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-kn"&gt;import&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nn"&gt;java.io.File&lt;/span&gt;&lt;span class="pygments-p"&gt;;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-kn"&gt;import&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nn"&gt;com.bmc.ctmem.usagetool.Enhancement.ZipFiles&lt;/span&gt;&lt;span class="pygments-p"&gt;;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-kn"&gt;import&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nn"&gt;com.bmc.ctmem.usagetool.dbaccess.AddOnsReport&lt;/span&gt;&lt;span class="pygments-p"&gt;;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-kn"&gt;import&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nn"&gt;com.bmc.ctmem.usagetool.dbaccess.DBAccess&lt;/span&gt;&lt;span class="pygments-p"&gt;;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-kn"&gt;import&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nn"&gt;com.bmc.ctmem.usagetool.dbaccess.DBAccessManager&lt;/span&gt;&lt;span class="pygments-p"&gt;;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-kn"&gt;import&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nn"&gt;com.bmc.ctmem.usagetool.dbaccess.EndpointReport&lt;/span&gt;&lt;span class="pygments-p"&gt;;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-kn"&gt;import&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nn"&gt;com.bmc.ctmem.usagetool.dbaccess.JobCountReport&lt;/span&gt;&lt;span class="pygments-p"&gt;;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-kn"&gt;import&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nn"&gt;com.bmc.ctmem.usagetool.dbaccess.Params&lt;/span&gt;&lt;span class="pygments-p"&gt;;&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-kd"&gt;public&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-kd"&gt;class&lt;/span&gt; &lt;span class="pygments-nc"&gt;Main&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-p"&gt;{&lt;/span&gt;&lt;span class="pygments-w"&gt;
    &lt;/span&gt;&lt;span class="pygments-kd"&gt;public&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-kd"&gt;static&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-kt"&gt;void&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-nf"&gt;main&lt;/span&gt;&lt;span class="pygments-p"&gt;(&lt;/span&gt;&lt;span class="pygments-n"&gt;String&lt;/span&gt;&lt;span class="pygments-o"&gt;[]&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;args&lt;/span&gt;&lt;span class="pygments-p"&gt;)&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-p"&gt;{&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-c1"&gt;// Used to Load Env and Config File also to Generate and Get Report Directory&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-n"&gt;Params&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;par&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-o"&gt;=&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;Params&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;instance&lt;/span&gt;&lt;span class="pygments-p"&gt;();&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-k"&gt;try&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-p"&gt;{&lt;/span&gt;&lt;span class="pygments-w"&gt;
            &lt;/span&gt;&lt;span class="pygments-n"&gt;par&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;LoadEMEnvironmentsFromFile&lt;/span&gt;&lt;span class="pygments-p"&gt;();&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-p"&gt;}&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-k"&gt;catch&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-p"&gt;(&lt;/span&gt;&lt;span class="pygments-n"&gt;Exception&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;e&lt;/span&gt;&lt;span class="pygments-p"&gt;)&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-p"&gt;{&lt;/span&gt;&lt;span class="pygments-w"&gt;
            &lt;/span&gt;&lt;span class="pygments-n"&gt;e&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;printStackTrace&lt;/span&gt;&lt;span class="pygments-p"&gt;();&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-p"&gt;}&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-k"&gt;try&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-p"&gt;{&lt;/span&gt;&lt;span class="pygments-w"&gt;
            &lt;/span&gt;&lt;span class="pygments-n"&gt;par&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;LoadConfigParamFromFile&lt;/span&gt;&lt;span class="pygments-p"&gt;();&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-p"&gt;}&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-k"&gt;catch&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-p"&gt;(&lt;/span&gt;&lt;span class="pygments-n"&gt;Exception&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;e&lt;/span&gt;&lt;span class="pygments-p"&gt;)&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-p"&gt;{&lt;/span&gt;&lt;span class="pygments-w"&gt;
            &lt;/span&gt;&lt;span class="pygments-n"&gt;e&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;printStackTrace&lt;/span&gt;&lt;span class="pygments-p"&gt;();&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-p"&gt;}&lt;/span&gt;&lt;span class="pygments-w"&gt;

        &lt;/span&gt;&lt;span class="pygments-c1"&gt;// Initiates DB Connection based on values in data/env.txt&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-n"&gt;DBAccessManager&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;dbam&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-o"&gt;=&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;DBAccessManager&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;instance&lt;/span&gt;&lt;span class="pygments-p"&gt;();&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-n"&gt;dbam&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;RefreshDBAccessManager&lt;/span&gt;&lt;span class="pygments-p"&gt;();&lt;/span&gt;&lt;span class="pygments-w"&gt;

        &lt;/span&gt;&lt;span class="pygments-c1"&gt;// Get DB Connection for Environment 0 (first line in env file)&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-n"&gt;DBAccess&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;con&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-o"&gt;=&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;dbam&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;GetDBAccess&lt;/span&gt;&lt;span class="pygments-p"&gt;(&lt;/span&gt;&lt;span class="pygments-mi"&gt;0&lt;/span&gt;&lt;span class="pygments-p"&gt;);&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-n"&gt;con&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;GetEMVersionFromDB&lt;/span&gt;&lt;span class="pygments-p"&gt;();&lt;/span&gt;&lt;span class="pygments-w"&gt;

        &lt;/span&gt;&lt;span class="pygments-c1"&gt;// Creates new Directory in reports/ with datetime now (&amp;quot;yyyy-MM-dd-HHmmss&amp;quot;)&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-n"&gt;par&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;CreateReportDir&lt;/span&gt;&lt;span class="pygments-p"&gt;();&lt;/span&gt;&lt;span class="pygments-w"&gt;

        &lt;/span&gt;&lt;span class="pygments-c1"&gt;// Trigger Generation of all Reports identical to GUI (Wizard / FlowManager)&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-k"&gt;new&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;JobCountReport&lt;/span&gt;&lt;span class="pygments-p"&gt;(&lt;/span&gt;&lt;span class="pygments-n"&gt;par&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;GetReportDirName&lt;/span&gt;&lt;span class="pygments-p"&gt;());&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-k"&gt;new&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;AddOnsReport&lt;/span&gt;&lt;span class="pygments-p"&gt;(&lt;/span&gt;&lt;span class="pygments-n"&gt;par&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;GetReportDirName&lt;/span&gt;&lt;span class="pygments-p"&gt;());&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-k"&gt;new&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;EndpointReport&lt;/span&gt;&lt;span class="pygments-p"&gt;(&lt;/span&gt;&lt;span class="pygments-n"&gt;par&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;GetReportDirName&lt;/span&gt;&lt;span class="pygments-p"&gt;(),&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-kc"&gt;true&lt;/span&gt;&lt;span class="pygments-p"&gt;);&lt;/span&gt;&lt;span class="pygments-w"&gt;

        &lt;/span&gt;&lt;span class="pygments-c1"&gt;// For easier handling, add all generated files to &amp;quot;reports.zip&amp;quot; in Generated Report Directory&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-n"&gt;File&lt;/span&gt;&lt;span class="pygments-o"&gt;[]&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;fileReportsDir&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-o"&gt;=&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-k"&gt;new&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;File&lt;/span&gt;&lt;span class="pygments-p"&gt;(&lt;/span&gt;&lt;span class="pygments-n"&gt;par&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;GetReportDirName&lt;/span&gt;&lt;span class="pygments-p"&gt;()).&lt;/span&gt;&lt;span class="pygments-na"&gt;listFiles&lt;/span&gt;&lt;span class="pygments-p"&gt;();&lt;/span&gt;&lt;span class="pygments-w"&gt;
        &lt;/span&gt;&lt;span class="pygments-n"&gt;ZipFiles&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;Zip&lt;/span&gt;&lt;span class="pygments-p"&gt;(&lt;/span&gt;&lt;span class="pygments-n"&gt;fileReportsDir&lt;/span&gt;&lt;span class="pygments-p"&gt;,&lt;/span&gt;&lt;span class="pygments-w"&gt; &lt;/span&gt;&lt;span class="pygments-n"&gt;par&lt;/span&gt;&lt;span class="pygments-p"&gt;.&lt;/span&gt;&lt;span class="pygments-na"&gt;GetReportDirName&lt;/span&gt;&lt;span class="pygments-p"&gt;());&lt;/span&gt;&lt;span class="pygments-w"&gt;
    &lt;/span&gt;&lt;span class="pygments-p"&gt;}&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;&lt;span class="pygments-p"&gt;}&lt;/span&gt;&lt;span class="pygments-w"&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;ctmusagereport.cmd&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
java -cp &amp;quot;./*;ctmusagereport_lib/*&amp;quot; ctmusagereport.Main

&lt;/pre&gt;
&lt;p&gt;I tested it successfully with &lt;em&gt;&amp;quot;OpenJDK11U-jdk_x64_windows_hotspot_11.0.12_7&amp;quot;&lt;/em&gt; from &lt;a class="reference external" href="https://adoptium.net/"&gt;https://adoptium.net/&lt;/a&gt; on Windows Server 2016.&lt;/p&gt;
&lt;p&gt;What I like about working with Control-M is that you can Script and Customize almost everything somehow, even worse that I had to find a workaround like that for the usage reporting, would be great if BMC would offer such an CLI option with the original Tool.&lt;/p&gt;
</content><category term="Code"/><category term="Control-M"/><category term="Code"/><category term="Java"/></entry></feed>