How to convert (and fixup) the RedHat RPM to run on Debian/Ubuntu

In an earlier post I had shown how I got the Xplat agent running on Ubuntu. I perfected the technique over time, and what follows is a step-by-step process on how to convert and change the RedHat package to run on Debian/Ubuntu. Of course this is still a hack… but some people asked me to detail it a bit more. At the same time, the cross platform team is working to update the the source code on codeplex with extra bits that will make more straightforward to grab it, modify it and re-compile it than it is today. Until then, here is how I got it to work.

I assume you have already copied the right .RPM package off the OpsMgr server’s /AgentManagement directory to the Linux box here. The examples below refer to the 32bit package, but of course the same identical technique would work for the 64bit version.

We start by converting the RPM package to DEB format:

root# alien -k scx-1.0.4-258.rhel.5.x86.rpm –scripts

scx_1.0.4-258_i386.deb generated


Then we need to create a folder where we will extract the content of the package, modify stuff, and repackage it:

root# mkdir scx_1.0.4-258_i386

root# cd scx_1.0.4-258_i386

root# ar -x ../scx_1.0.4-258_i386.deb

root# mkdir debian

root# cd debian

root# mkdir DEBIAN

root# cd DEBIAN

root# cd ../..

root# rm debian-binary

root# mv control.tar.gz debian/DEBIAN/

root# mv data.tar.gz debian/

root# cd debian

root# tar -xvzf data.tar.gz

root# rm data.tar.gz

root# cd DEBIAN/

root# tar -xvzf control.tar.gz

root# rm control.tar.gz

Now we have the “skeleton” of the package easily laid out on the filesystem and we are ready to modify the package and add/change stuff to and in it.


First, we need to add some stuff to it, which is expected to be found on a redhat distro, but is not present in debian. In particular:

1. You should copy the file “functions” (that you can get from a redhat/centos box under /etc/init.d) under the debian/etc/init.d folder in our package folder. This file is required/included by our startup scripts, so it needs to be deployed too.

Then we need to chang some of the packacge behavior by editing files under debian/DEBIAN:

2. edit the “control” file (a file describing what the package is, and does):


3. edit the “preinst” file (pre-installation instructions): we need to add instructions to copy the “issue” file onto “redhat-release” (as the SCX_OperatingSystem class will look into that file, and this is hard-coded in the binary, we need to let it find it):


these are the actual command lines to add for both packages (DEBIAN or UBUNTU):

# symbolic links for libaries called differently on Ubuntu and Debian vs. RedHat

ln -s /usr/lib/ /usr/lib/

ln -s /usr/lib/ /usr/lib/

the following bit would be Ubuntu-specific:

#we need this file for the OS provider relies on it, so we convert what we have in /etc/issue

#this is ok for Ubuntu (“Ubuntu 9.0.4 \n \l” becomes “Ubuntu 9.0.4”)

cat /etc/issue | awk '/\\n/ {print $1, $2}' > /etc/redhat-release

while the following bit is Debian-specific:

#this is ok for Debian (“Debian GNU/Linux 5.0 \n \l” becomes “Debian GNU/Linux 5.0”)

cat /etc/issue | awk '/\\n/ {print $1, $2, $3}' > /etc/redhat-release


4. Then we edit/modify the “postinst” file (post-installation instructions) as follows:

a. remove the 2nd and 3rd lines which look like the following



as they are only useful for the RPM system, not DEB/APT, so we don’t need them.

b. change the following 2 functions which contain RedHat-specific commands:

configure_pegasus_service() {

           /usr/lib/lsb/install_initd /etc/init.d/scx-cimd


start_pegasus_service() {

           service scx-cimd start


c. We need to change in the Debian equivalents for registering a service in INIT and starting it:

configure_pegasus_service() {

               update-rc.d scx-cimd defaults


start_pegasus_service() {

              /etc/init.d/scx-cimd start


5. Modify the “prerm” file (pre-removal instructions):

a. Just like “postinst”, remove the lines



b. Locate the two functions stopping and un-installing the service

stop_pegasus_service() {

         service scx-cimd stop


unregister_pegasus_service() {

          /usr/lib/lsb/remove_initd /etc/init.d/scx-cimd


c. Change those two functions with the Debian-equivalent command lines

stop_pegasus_service() {

           /etc/init.d/scx-cimd stop


unregister_pegasus_service() {

           update-rc.d -f scx-cimd remove


At this point the change we needed have been put in place, and we can re-build the DEB package.

Move yourself in the main folder of the application (the scx_1.0.4-258_i386 folder):

root# cd ../..

Create the package starting from the folders

root# dpkg-deb –build debian

dpkg-deb: building package `scx' in `debian.deb'.

Rename the package (for Ubuntu)

root# mv debian.deb scx_1.0.4-258_Ubuntu_9_i386.deb

Rename the package (for Debian)

root# mv debian.deb scx_1.0.4-258_Debian_5_i386.deb

Install it

root# dpkg -i scx_1.0.4-258_Platform_Version_i386.deb

All done! It should install and work!


Next step would be creating a Management Pack to monitor Debian and Ubuntu. It is pretty similar to what Robert Hearn has described step by step for CentOS, but with some different replacements of strings, as you can imagine. I have done this but have not written down the procedure yet, so I will post another article on how to do this as soon as I manage to get it standardized and reliable. There is a bit more work involved for Ubuntu/Debian… as some of the daemons/services have different names, and certain files too… but nothing terribly difficult to change so you might want to try it already and have a go at it!

In the meantime, as a teaser, here’s my server’s ( performance, being monitored with this “hack”:




The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my own personal opinion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.

Create a Script-Based Unit Monitor in OpsMgr2007 via the GUI

Warning for people who landed here: this post is VERY OLD. It was written in the early days of struggling with OpsMgr 2007, and when nobody really knew how to do things.
I found that this way was working – and it surely does – but what is described here is NOT the recommended way to do things nowadays. This post was only meant to fill in a gap I was feeling existed, back in 2007.
But as time passes, and documentation gets written, knowledge improves.
Therefore, I recommend you read the newly released Composition chapter of the MP Authoring Guide instead – and start building your custom modules to embed scripts as Brian Wren describes in there, so that you can share them between multiple rules and monitors.

This said, below is the original post.

Create a Script-Based Unit Monitor in OpsMgr2007 via the GUI

There is not a lot of documentation for System Center Operations Manager 2007 yet.
It is coming, but there's a lot of things that changed since the previous release and I think some more would only help. Also, a lot of the content I am seeing is either too newbie-oriented or too developer-oriented, for some reason.

I have not yet seen a tutorial, webcast or anything that explains how to create a simple unit monitor that uses a VBS script using the GUI.

So this is how you do it:

Go to the "Authoring" space of OpsMgr 2007 Operations Console.
Select the "Management Pack objects", then "Monitors" node. Right click and choose "Create a monitor" -> "Unit Monitor".

You get the "Create a monitor" wizard open:

Choose to create a two-states unit monitor based on a script. Creating a three- state monitor would be pretty similar, but I'll show you the most simple one.
Also, choose a Management pack that will contain your script and unit monitor, or create a new management pack.

Choose a "monitor target" (object classes or instances – see this webcast about targeting rules and monitors:… ) and the aggregate rollup monitor you want to roll the state up to.

Choose a schedule, that is: how often would you like your script to run. For demonstration purposes I usually choose a very short interval such a two or three minutes. For production environments, tough, choose a longer time range.

Choose a name for your script, complete with a .VBS extension, and write the code of the script in the rich text box:

As the sample code and comments suggest, you should use a script that checks for the stuff you want it to check, and returns a "Property Bag" that can be later interpreted by OpsMgr workflow to change the monitor's state.
This is substantially different than scripting in MOM 2005, where you could only launch scripts as responses, loosing all control over their execution.

For demonstration purpose, use the following script code:

On Error Resume Next
Dim oAPI, oBag
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oBag = oAPI.CreateTypedPropertyBag(StateDataType)
strFileName = "c:\testfolder\testfile.txt"
strContent = "test "
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objTS = objFS.OpenTextFile(strFileName,FOR_APPENDING)
If Err.Number <> 0 Then
Call oBag.AddValue("State","BAD")
Call oBag.AddValue("State","GOOD")
objTS.Write strContent
End If
Call oAPI.Return(oBag)

[edited on 29th of May as pointed out by Ian: if you cut and paste the example script you might need to change the apostrophes (“) as that causes the script to fail when run – it is an issue with the template of this blog.] [edited on 30th of May: I fixed the blog so that now post content shows just plain, normal double quotes instead than fancy ones. It seems like a useful thing when from time to time I post code…]

The script will try to write into the file c:\testfolder\testfile.txt.
If it finds the file and manages to write (append text) to it, it will return the property "State" with a value of "GOOD".
If it fails (for example if the file does not exist), it will return the property "State" with a value of "BAD".

In MOM 2005 you could only let script generate Events or Alerts directly as a mean to communicate their results back to the monitoring engine. In OpsMgr 2007 you can let your script spit out a property bag and then continue the monitoring workflow and decide what to do depending on the script's result.


So the next step is to go and check for the value of the property we return in the property bag, to determine which status the monitor will have to assume.

We use the syntax Property[@Name='State'] in the parameter field, and we search for a content that means an unhealthy condition:


Or for the healty one:

Then we decide which status will the monitor have to assume in the healty and unhealty conditions (Green/Yellow or Green/Red usually)

Optionally, we can decide to raise an Alert when the status changes to unhealthy, and close it again when it goes back to healty.


Now our unit monitor is done.
All we have to do is waiting it gets pushed down to the agent(s) that should execute it, and wait for its status to change.
In fact it should go to the unhealthy state first.
To test that it works, just create the text file it will be searching for, and wait for it to run again, and the state should be reset to Healthy.

Have fun with more complex scripts!