diff --git a/public_html/deployment/index.php b/public_html/deployment/index.php
index fb620a3611ab019796f9d15d29fc84a3c812eada..c9a84309e2702e4442791710afb4a84c1aba8be0 100644
--- a/public_html/deployment/index.php
+++ b/public_html/deployment/index.php
@@ -121,6 +121,11 @@ $sPhpOut = '
     <div id="footer">
         '.t("menu-brand").' &copy; 2013-' . date("Y") . ' <a href="https://git-repo.iml.unibe.ch/iml-open-source/imldeployment/" target="_blank">Institut f&uuml;r Medizinische Lehre; Universit&auml;t Bern</a>
     </div>
+
+    <!--
+    <script src="/deployment/plugins/shellcmd/load/render.js" />
+    -->
+
     '.$oCLog->render();
 
 $oPage = new Page();
diff --git a/public_html/deployment/plugins/shellcmd/getdata.php b/public_html/deployment/plugins/shellcmd/getdata.php
new file mode 100644
index 0000000000000000000000000000000000000000..12b260e86700c3dbb0e1cd3a20868ea1bd3fdd4c
--- /dev/null
+++ b/public_html/deployment/plugins/shellcmd/getdata.php
@@ -0,0 +1,139 @@
+<?php
+/*
+ * script to be used as ajax poll request to get current status of an action
+ */
+
+header('Content-Type: application/json');
+require_once('plugins_shellcmd.class.php');
+
+$oShell=new shellcmd();
+$oShell->sendResponse();
+
+/*
+
+// width of load=1
+$iMaxWidth=100;
+
+$sPlugin=isset($_GET['plugin']) && $_GET['plugin'] ? preg_replace('/^a-z0-9/', '', $_GET['plugin']) : false;
+
+// ----------------------------------------------------------------------
+// ----------------------------------------------------------------------
+function execCommand($sCmd){
+    echo "DEBUG: ".__FUNCTION__ . "($sCmd)<br>";
+    exec($sCmd, $aOut, $iResult);
+    return [
+        'command'=>$sCmd,
+        'exitcode'=>$iResult,
+        'output'=>$aOut,
+    ];
+}
+
+
+if (!$sPlugin){
+    echo "DEBUG: Missing param for a plugin.<br>";
+    return [ 'error' => 'Missing param for a plugin.' ];
+}
+
+$sPluginfile=$sPlugin.'/command.php';
+$sPluginclass='shellplugin_'.$sPlugin;
+
+echo "DEBUG: sPluginfile=$sPluginfile<br>";
+
+if (!file_exists($sPluginfile)){
+    echo "DEBUG: Plugin seems to be corrupt. File not found: '. $sPluginfile.'<br>";
+    return [ 'error' => 'Plugin seems to be corrupt. File not found: '. $sPluginfile ];
+}
+
+
+include($sPluginfile);
+
+$oPlugin=new $sPluginclass();
+
+echo "DEBUG: sCmd=$sCmd<br>";
+
+$aResult=execCommand($sCmd);
+if (function_exists("parsedata")){
+    $aResult=parsedata($aResult);
+}
+
+echo '<pre>$aResult = '.print_r($aResult, 1).'<pre>';
+return $aResult;
+
+
+// ----------------------------------------------------------------------
+function getLoad(){
+    $sCmd='uptime';
+    $aResult=execCommand($sCmd);
+    $aTmp1=explode(',', $aResult['output'][0]);
+    $aResult['data']=[
+        'uptime'=>$aTmp1[0],
+        'users'=>$aTmp1[1],
+        'load'=>preg_replace('/^.*:/', '', $aTmp1[2]),
+        'load5'=>$aTmp1[3],
+        'load15'=>$aTmp1[4],
+    ];
+    return $aResult;
+}
+
+function getProcesses($sFilter){
+    $sRegex=$sFilter ? $sFilter : 'SomethingThatWontMatchInProcessList';
+    $sCmd="ps -f --forest | egrep -v '($sRegex)' | fgrep -v 'ps -f' | fgrep -v grep";
+    return execCommand($sCmd);
+}
+
+
+// ----------------------------------------------------------------------
+// ----------------------------------------------------------------------
+function load(){
+    global $iMaxWidth;
+    $sReturn='';
+
+    $aData=getLoad()['data'];
+
+    $iMaxLoad=round(max($aData['load'], $aData['load5'], $aData['load15']))+1;
+    $iScale=$iMaxWidth/$iMaxLoad;
+
+    $sScalaPart=str_repeat('_', (round($iScale)-1)).'|';
+    $sScala=str_repeat($sScalaPart, $iMaxLoad).$iMaxLoad;
+
+
+    $sBar1=str_repeat('#', (int)($aData['load']*$iScale));
+    $sBar5=str_repeat(' ', (int)($aData['load5']*$iScale - 1)).'|';
+    $sBar15=str_repeat(' ', (int)($aData['load15']*$iScale - 1)).'^';
+
+    $sReturn.= 'LOAD '.$aData['load'].' .. '.$aData['load5'].' .. '.$aData['load15'].'<br>'
+        . $sScala.'<br>'
+        . substr($sBar1, 0, $iMaxWidth).'<br>'
+        . substr($sBar5, 0, $iMaxWidth).'<br>'
+        . substr($sBar15, 0, $iMaxWidth).'<br>'
+        ;
+
+    return $sReturn;
+}
+
+
+function processes(){
+
+    return 'PROCESSES:<br>'
+        .shell_exec("ps -f --forest | egrep -v '(apache|httpd)' | fgrep -v 'ps -f' | fgrep -v grep")
+        .'<hr>all processes:<br>'
+        .shell_exec("ps -f --forest")
+    ;
+}
+
+// ----------------------------------------------------------------------
+// MAIN
+// ----------------------------------------------------------------------
+
+$sRemove='apache|httpd|php-fpm';
+
+echo '<pre>'
+    . load()
+    // .'<hr size="1">'
+    
+    .'<hr size="1">'
+    .'API DATA'
+    .'<pre>getLoad()='.print_r(getLoad(), 1).'</pre>'
+    .'<pre>getProcesses(\''.$sRemove.'\')='.print_r(getProcesses($sRemove), 1).'</pre>'
+    ;
+*/
\ No newline at end of file
diff --git a/public_html/deployment/plugins/shellcmd/load/plugin.php b/public_html/deployment/plugins/shellcmd/load/plugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec9338047ae1d60dbb39120bad91a5ad9da444b6
--- /dev/null
+++ b/public_html/deployment/plugins/shellcmd/load/plugin.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * 
+ * SHELLCMD PLUGIN :: LOAD
+ * 
+ * ----------------------------------------------------------------------
+ * 2022-08-05  axel.hahn@iml.unibe.ch
+ */
+class shellcmd_load {
+    /**
+     * @var command line to exectute
+     */
+    protected $_command='uptime';
+
+
+    /**
+     * constructor ... returns command
+     * @return string
+     */
+    public function __constructor(){
+        return $this->getCommand();
+    }
+
+    /**
+     * get command
+     * @return string
+     */
+    public function getCommand(){
+        return $this->_command;
+    }
+
+
+    /**
+     * parse output and extract wanted values in section "data"
+     * @return array
+     */
+    public function parsedata($aResult){
+        $aTmp1=array_reverse(explode(',', $aResult['output'][0]));
+        // print_r($aTmp1);
+        $aResult['data']=[
+            'uptime'=>trim($aTmp1[4]),
+            'users'=>trim(str_replace(' users', '', $aTmp1[3])),
+            'load'=>trim(preg_replace('/^.*:/', '', $aTmp1[2])),
+            'load5'=>trim($aTmp1[1]),
+            'load15'=>trim($aTmp1[0]),
+        ];
+        return $aResult;
+    }
+
+}
+/*
+
+EXAMPLE OUTPUT
+
+{
+    "command": "uptime",
+    "exitcode": 0,
+    "output": [
+        " 13:36:54 up 1 day,  7:39,  0 users,  load average: 1.18, 1.29, 1.33"
+    ],
+    "data": {
+        "uptime": "7:39",
+        "users": "0",
+        "load": "1.18",
+        "load5": "1.29",
+        "load15": "1.33"
+    }
+}
+
+*/
\ No newline at end of file
diff --git a/public_html/deployment/plugins/shellcmd/load/render.js b/public_html/deployment/plugins/shellcmd/load/render.js
new file mode 100644
index 0000000000000000000000000000000000000000..f4d310608589579e60c7cdb0171f53e5b7ba5d79
--- /dev/null
+++ b/public_html/deployment/plugins/shellcmd/load/render.js
@@ -0,0 +1,7 @@
+function load_render(aData){
+    var sReturn='';
+    sReturn+=aData['command']+"<br>"
+        + "Load: "+aData["data"]['load']+"<br>"
+        ;
+    return sReturn;
+}
\ No newline at end of file
diff --git a/public_html/deployment/plugins/shellcmd/plugins_shellcmd.class.php b/public_html/deployment/plugins/shellcmd/plugins_shellcmd.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..938c8c57c96560ba70d7b45f6f418571983140a5
--- /dev/null
+++ b/public_html/deployment/plugins/shellcmd/plugins_shellcmd.class.php
@@ -0,0 +1,103 @@
+<?php
+
+class shellcmd {
+
+    protected $_sPlugin=false;
+    protected $_oPlugin=false;
+    protected $_aReturn=false;
+
+    protected $_debug=false;
+
+    /**
+     * constructor
+     * @return bool
+     */
+    public function __construct(){
+        return $this->detectPlugin();
+    }
+
+
+    /**
+     * write debug output ... if enabled
+     */
+    protected function _wd($s){
+        echo $this->_debug ? 'DEBUG '.__CLASS__ . ' '.$s."<br>\n" : '';
+    }
+
+    /**
+     * detect plugin name to load from GET param "plugin"
+     */
+    public function detectPlugin(){
+        $this->_sPlugin=isset($_GET['plugin']) && $_GET['plugin'] ? preg_replace('/^a-z0-9/', '', $_GET['plugin']) : false;
+        $this->_wd("detected plugin: ".$this->_sPlugin);
+        return true;
+    }
+
+
+    /**
+     * initialize the shellcmd plugin
+     * @returm boolean
+     */
+    protected function _loadPlugin(){
+        $this->_oPlugin=false;
+        if (!$this->_sPlugin){
+            $this->_wd("Missing param for a plugin");
+            $this->_aReturn=[ 'error' => 'Missing param for a plugin.' ];
+            return false;
+        }
+        $sPluginfile=$this->_sPlugin.'/plugin.php';
+        $sPluginclass='shellcmd_'.$this->_sPlugin;
+
+        if (!file_exists($sPluginfile)){
+            $this->_wd("Plugin seems to be corrupt. File not found: '. $sPluginfile.");
+            $this->_aReturn=[ 'error' => 'Plugin seems to be corrupt. File not found: '. $sPluginfile ];
+            return false;
+        }
+        include($sPluginfile);        
+        $this->_oPlugin=new $sPluginclass();
+        return true;
+    }
+    /**
+     * helper execute a given command and return array with executed
+     * command, returncode, output
+     * @return
+     */
+    protected function _execCommand($sCmd){
+        exec($sCmd, $aOut, $iResult);
+        return [
+            'command'=>$sCmd,
+            'exitcode'=>$iResult,
+            'output'=>$aOut,
+        ];
+    }
+
+    /**
+     * get data from plugin command and return array with executed
+     * command, returncode, output, parsed data
+     * @return array
+     */
+    public function get(){
+        $this->_loadPlugin();
+        if (!$this->_oPlugin){
+            return $this->_aReturn;
+        }
+        
+        $sCmd=$this->_oPlugin->getCommand();
+        $this->_wd("sCmd=$sCmd");
+        
+        $this->_aResult=$this->_execCommand($sCmd);
+        if (method_exists($this->_oPlugin, "parsedata")){
+            $this->_aResult=$this->_oPlugin->parsedata($this->_aResult);
+        }
+        return $this->_aResult;
+    }
+
+    /**
+     * send response as json
+     */
+    public function sendResponse(){
+        header('Content-Type: application/json');
+        echo json_encode($this->get(), JSON_PRETTY_PRINT);
+    }
+
+}
diff --git a/public_html/deployment/plugins/shellcmd/processes/command.php b/public_html/deployment/plugins/shellcmd/processes/command.php
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391