May, 2009

  • musc@> $daniele.work.ToString()

    Installing the OpsMgr 2007 R2 SCX Agent on Ubuntu

    • 0 Comments

    You know since the beta1 of Xplat I have been busy with modifying the Redhat management pack and monitor CentOS with OpsMgr. Now, CentOS is a distribution that is pretty similar to RedHat, so the RPM package just runs, and it is only a matter of hacking a modified MP.

    I never went really further in my experiments, mostly due to lack of time… but then yesterday I got a comment to this older post asking about Ubuntu. Of course I know about Ubuntu, and have been using Debian-based distributions for years. I actually even prefer them over RPM-based distributions such as RedHat or SuSE (personal preference). Heck, even this weblog is running on Debian!

    Anyway, I never really tried to see if one of the existing RPM packages for RedHat or SuSE could be modified to run on Ubuntu. I will eventually test this on Debian too, but for now I used Ubuntu which tends to have slightly newer packages and libraries, overall. The machine I tested on is a Ubuntu Server 8.04.2. Older/newer versions might slightly differ.

    BEWARE THAT ALL THAT FOLLOWS BELOW IS NOT SUPPORTED BY MICROSOFT. It is only described here for EXPERIMENTAL (==fun) purpose. DO NOT USE THIS IN A PRODUCTION ENVIRONMENT.

    So, you are warned. Now let’s hack it.

    The first thing to do is to copy the Redhat agent’s RPM package off your OpsMgr2007 R2 server in the “usual” path “C:Program FilesSystem Center Operations manager 2007AgentManagementUnixAgents”. Let’s grab the RHEL5 agent, which is called scx-1.0.4-248.rhel.5.x86.rpm in R2 RTM.

    First we need to CONVERT the RPM package to the DEB package format used by Ubuntu, by using the ALIEN package:

    sudo apt-get update
    sudo apt-get install alien
    sudo bash
    alien -k scx-1.0.4-248.rhel.5.x86.rpm --scripts
    dpkg -i scx_1.0.4-248_i386.deb

    image

    The converted package will install… but the script execution will fail in a few places – most notably in the generation of the certificate, as it is not able to locate the right openssl libraries, as shown in the screenshot above.

    If the libssl.so.6 file cannot be found, you might be missing the “libssl-dev” package, which you can install as follows:

    apt-get install libssl-dev

    But even if it is installed, you will find that the files are still missing. This is not really true: actually, the files are there, but on Ubuntu they have a different name than on RedHat, that’s all. You can therefore create hardlinks to the “right” files, so that they are aliased and get found afterwards:

    cd /usr/lib
    ln -s libcrypto.so.0.9.8 libcrypto.so.6
    ln -s libssl.so.0.9.8 libssl.so.6

    So now when installing the package, the certificate generation will work:

    image

    You are nearly ready to go. You have to start the service by using the init scripts – the “service” command is RedHat-specific, that will still fail.

    /etc/init.d/scx-cimd start is the “standard” way of starting daemons from init on Unix.

    But it still fails, as it seems that the init script provided in the RedHat package is really searching for a file called “functions” which is present on RedHat and on CentOS, which provides re-usable functions for startup scripts to include:

    image

    How do you fix this? I just copied the /etc/init.d/functions file from a CentOS box to my Ubuntu box.

    I copied it via SCP from the CentOS box I have:

    cd /etc/init.d

    scp root@centos.huis.dom:/etc/init.d/functions .

    You can probably also find and fetch the file from the Internet (both CentOS and RedHat should have accessible repositories with all the files in their distributions, since it is open sourced).

    After you have the file in place, the init script will be able to include it, will find the functions it needs, and the daemon/service will now start (even if with minor errors I have not investigated for now, but that don’t seem to be causing troubles):

    image

    and here you can see it is finally running:

    image

    So let’s try to issue a few queries as shown in a previous posts:

    image

    IT WORKS!!!

    But… there is a “but”: not all classes actually return instances and values just yet. Most notably the “SCX_OperatingSystem” class does not seem to return anything right awy. That is a very important class, because is the one we would use to first discover the Operating System object in the Management Packs. So we need to fix it. The reason why the class does not return anything, is that the SCX provider is looking into the /etc/redhat-release file to return what OS version/distribution the machine is running. And the file is obviously not there on Ubuntu.

    On all Linuxes there is a similar file, called /etc/issue... which again, we can copy with the other name and trick the provider into working:

    cd /etc

    cp issue redhat-release

    And NOW, the SCX_OperatingSystem Class also returns an instance:

    image

    The next step would be “cooking” an MP to discover Ubuntu. More on this on a later post (maybe). I did not test all classes and their implementation… you can try to poke at them by following the instructions and commands on my previous post here. But this should get you started.

    Disclaimer

    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.
    THIS WORK IS NOT ENDORSED AND NOT EVEN CHECKED, AUTHORIZED, SCRUTINIZED NOR APPROVED BY MY EMPLOYER, AND IT ONLY REPRESENT SOMETHING WHICH I'VE DONE IN MY FREE TIME. NO GUARANTEE WHATSOEVER IS GIVEN ON THIS. THE AUTHOR SHALL NOT BE MADE RESPONSIBLE FOR ANY DAMAGE YOU MIGHT INCUR WHEN USING THIS INFORMATION. The solution presented here IS NOT SUPPORTED by Microsoft.

  • musc@> $daniele.work.ToString()

    Get-WmiCustom (aka: Get-WMIObject with timeout!)

    • 12 Comments

    I make heavy use of WMI.

    But when using it to gather information from customer’s machines for assessments, I sometimes find the occasional broken WMI repository. There are a number of ways in which WMI can become corrupted and return weird results. Most of the times you would just get errors, such as “Class not registered” or “provider load failure”. I can handle those errors from within scripts.

    But there are some, more subtle - and annoying – ways in which the WMI repository can get corrupted. the situations I am talking about are the ones when WMI will accept your query… will say it is executing it… but it will never actually return any error, and just stay stuck performing your query forever. Until your client application decides to time out. Which in some cases does not happen.

    Now that was my issue – when my assessment script (which was using the handy Powershell Get-WmiObject cmdlet) would hit one of those machines… the whole script would hang forever and never finish its job. Ok, sure, the solution to this would be actually FIXING the WMI repository and then try again. But remember I am talking of an assessment: if the information I am getting is just one piece of a bigger puzzle, and I don’t necessarily care about it and can continue without that information – I want to be able to do it, to skip that info, maybe the whole section, report an error saying I am not able to get that information, and continue to get the remaining info. I can still fix the issue on the machine afterward AND then run the assessment script again, but in the first place I just want to get a picture of how the system looks like. With the good and with the bad things. Especially, I do want to take that whole picture – not just a piece of it.

    Unfortunately, the Get-WmiObject cmdlet does not let you specify a timeout. Therefore I cooked my own function which has a compatible behaviour to that of Get-WmiObject, but with an added “-timeout” parameter which can be set. I dubbed it “Get-WmiCustom”

    Function Get-WmiCustom([string]$computername,[string]$namespace,[string]$class,[int]$timeout=15)
    {
    $ConnectionOptions = new-object System.Management.ConnectionOptions
    $EnumerationOptions = new-object System.Management.EnumerationOptions

    $timeoutseconds = new-timespan -seconds $timeout
    $EnumerationOptions.set_timeout($timeoutseconds)

    $assembledpath = "\\" + $computername + "\" + $namespace
    #write-host $assembledpath -foregroundcolor yellow

    $Scope = new-object System.Management.ManagementScope $assembledpath, $ConnectionOptions
    $Scope.Connect()

    $querystring = "SELECT * FROM " + $class
    #write-host $querystring

    $query = new-object System.Management.ObjectQuery $querystring
    $searcher = new-object System.Management.ManagementObjectSearcher
    $searcher.set_options($EnumerationOptions)
    $searcher.Query = $querystring
    $searcher.Scope = $Scope

    trap { $_ } $result = $searcher.get()

    return $result
    }

    You can call it as follows, which is similar to how you would call get-WmiObject

    get-wmicustom -class Win32_Service -namespace "root\cimv2" -computername server1.domain.dom

    or, of course, specifying the timeout (in seconds):

    get-wmicustom -class Win32_Service -namespace "root\cimv2" -computername server1.domain.dom –timeout 1

    and obviously, since the function returns objects just like the original cmdlet, it is also possible to pipe them to other commands:

    get-wmicustom -class Win32_Service -namespace "root\cimv2" -computername server1.domain.dom –timeout 1 | Format-Table

Page 1 of 1 (2 items)