Monitoring OS X Mountain Lion (10.8) with OpsMgr 2012 R2

On  of the things I love to do in IT is connect systems that were not designed to communicate with each other. This is one of the reasons that I was pretty exited when introduced cross platform capabilities in OpsMgr. Because recently the cross platform agent has been redesigned to work with a super light weight agent (OMI) on UX like systems, I thought it would be a worthwhile exercise to explore it in a bit more detail. Now what would be a fun project for exploring this topic? Well… what about monitoring my girlfriends Apple Mac 🙂

This is the first part of creating a management pack for the latest version of Apple’s OS X (10.8) Mountain Lion. This post will show you how to compile the new OMI agent (Open Management Infrastructure), set up communication with the agent through Powershell and finally create a Management Pack to communicate with the OMI agent.

The following parts will be handled in this series:

Part 1 – Apple OSX MP – Configuring your Mac for OMI

Part 2 – Apple OSX MP -The compiling and installing of the OMI agent on your Mac

Part 3 – Apple OSX MP – Query OMI with Powershell

Part 4 – OSX MP – Creating an OSX Management Pack

Posted in Apple Mac, Management Pack, OpsMgr 2012 | Leave a comment

Part 3 – Apple OSX MP – Querying OMI with Powershell

In part 2 (Part 2 – Apple OSX MP -The compiling and installing of the OMI agent on your Mac) we got the OMI agent running on our Apple Mac and were able to query it with the OMI client. No we will go one step further and do some cross-platform querying with Powershell.

First of all make sure you are running at lease Powershell version 3.0. Earlier versions of Powershell do not contain the  Get-CimInstance commandlet which we need to query OMI.

We also need to make sure we can resolve our Mac by FQDN. In my test lab I just added the my Mac to the hosts file so that I can resolve and ping demos-mac.local.

So lets try to connect to OMI by using the following Powershell script:

$username = “root”

$password = “*********”

$secstr = New-Object -TypeName System.Security.SecureString

$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}

$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr

$Session = New-CimSession -ComputerName demos-Mac.local -Authentication Basic -Credential $Cred

Get-CimInstance -CimSession $Session -ClassName OMI_Identify -Namespace root/omi

Personally I like to use the Poweshell ISE that comes standard with Windows, so I plugged the code into the code Window and hit run.


… Oh dear, Powershell spat out lots of angry red errors at us. At this point we have a few options:

1. Allow encrypted traffic from the Windows Computer from which we are running the Powershell Script.

2. Import the certificates generated by the OMI Agent.

3. Generate your own certificates.

In this blog I will go for the second option, and import the Certificates generated by the OMI agent. To import the certificates from the OMI agents we need to convert and export them from the machine on which the OMI agent is installed.

First browse to the directory in which OIM is installed, in my case /opt/omi1.0.7/etc/ssl/certs

OpenSSL can combine a separate certificate (usercert.pem or usercert.cer) and private key file (userkey.pem) into PKCS12 format using the pkcs12 command:

sudo openssl pkcs12 -export -out omikey.p12 -in ./omi.pem -inkey ./omikey.pem


After executing the previous command you should have a new omikey.p12 file.

On the Windows machine open a certificate mmc snapin which displays the certificates for the computer account.


Import the omikey.p12 into the Trusted Root Certification Authoroties.


Before we run the Powershell script again we need to make a few changes. First add the line:

$options = New-CimSessionOption -UseSsl -SkipCACheck

and add -SessionOption $options  to the end of the following line:

$Session = New-CimSession -ComputerName demos-Mac.local -Authentication Basic -Credential $Cred

The script now looks like:

$username = “root”

$password = “*********”

$secstr = New-Object -TypeName System.Security.SecureString

$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}

$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr

$options = New-CimSessionOption -UseSsl -SkipCACheck

$Session = New-CimSession -ComputerName demos-Mac.local -Authentication Basic -Credential $Cred -SessionOption $options

Get-CimInstance -CimSession $Session -ClassName OMI_Identify -Namespace root/omi

Lets see what the output is of this script:


Awsome! We just connected to our Mac using WinRM!

Posted in Apple Mac, Management Pack, MP, OpsMgr 2012 | 6 Comments

Part 2 – Apple OSX MP -The compiling and installing of the OMI agent on your Mac

After Xcode is installed we can now compile the OMI package, which can be downloaded here: OMI Source 1.0.7. You can also check for the latest version here:  https://collaboration.opengroup.org/omi/

If you downloaded the OMI Package on your MAC, double click the package to unzip the archive. If you are using Windows, you will need something like 7zip (freely available) to unzip the archive.

I unzipped my archive and saved it to Document/omi-1.0.7, but you can choose your own directory. Before we can compile OMI we need to download compile and install the package pkg-config. Pkg-config is used by the OMI package for configuration so we need to satisfy this dependency. The latest pkg-config source can be downloaded here. I have found that some of the newer versions of the pkg-config package do not compile well on a Mac so I use the pkg-config-0.18.1.tar.gz which should also work for you. After downloading the package I unzipped the archive and saved it to Documents/pkg-config-0.18.1. Now open a terminal window (open a finder window and click Applications -> Utilities -> Terminal) and cd into the pkg-config-0.18.1 directory. Once in the directory issue the ./configure command at the command prompt.

If there are no errors creating the configuration, issue the make command.

Now if there are no errors, issue the sudo make install command. This will prompt you for an admin password because it wants to install the compiled files.

We also need to set the pkg-config path so it can find all the libraries:

  • export PKG_CONFIG_PATH=/usr/lib/pkgconfig

Also before compiling, check that the file /usr/lib/pkgconfig/openssl.pc has the same paths as in the screenshot:

Now the OMI package install is not made for OSX, this is why the PAM modules need to be registered manually if we want to use certificates for secure communication. To create the PAM entry, create a file named “omi” in the /etc/pam.d directory. In the omi file ad the following text entries:

#%PAM-1.0

# The configuration of omi is generated by the omi installer.

# sshd: auth account password session

auth optional pam_krb5.so use_kcminit

auth optional pam_ntlm.so try_first_pass

auth optional pam_mount.so try_first_pass

auth required pam_opendirectory.so try_first_pass

account required pam_nologin.so

account required pam_sacl.so sacl_service=ssh

account required pam_opendirectory.so

We are now all set to build the OMI package. CD into the omi-1.0.7 directory and issue the commands:

  • ./configure
  • make
  • sudo make install

Note that after issuing the ./configure command you will receive the error “pam script is not supported on Mac-OS yet“. You can safely ignore this error because already we registered the PAM modules manually.

Just like we did with building the pkg-config package, if OMI installed successfully, the output should look something like this:

So let’s test our OMI installation. If you are not logged in as root, su into root (su root). Then cd into /opt/omi-1.0.7/bin and start the OMI server by typing ./omiserver -d You can find all the server commands by running ./omiserver –help Now we can test the omi server by running ./omicli id the output should be something like in the screenshot:

So woohoo! Our OMI server is running on our Mac and accessible by a client. In part 3 of this blog we will explore how to query the OMI server by using Powershell.

Posted in Apple Mac, Management Pack, MP, OpsMgr 2012 | 1 Comment

Part 1 – Apple OSX MP – Configuring your Mac for OMI

So let’s get started!

The first thing we need to do is getting our Apple Mac ready for compiling OMI. To compile OMI on a Mac demands some changes in some of the source files of the OMI package. At this point I would like to give credit due to the following post that shows you how to compile OMI for Linux: Managing Linux via OMI: Installation. Before you change the settings on your Mac shown in this blog, please be aware that this might pose a security risk so I would advise against doing this on a production system. Ok Lets get started. The first thing we need to do is make sure we are working with the latest version of OSX. The version that we will be using is OS X 10.8 Mountain Lion.

Next we need to install Xcode (free of charge). Login to the App Store with your Apple ID and install Xcode.

In Xcode we need to change a settings before we can edit/compile/install the omi package. From the menu click Preferences and then the Downloads button. We need to add the Command Line Tools.

Your Mac does not allow you to edit source code downloaded form the internet by default. To change this we must browse to System Preferences -> Security & Privacy and change the Allow applications downloaded from: setting to Anywhere.

We also want to be able to login with SSH, so we enable this System Preferences -> Sharing and checking the Remote Login check box.

OMI expects to run under the root account, so we will want to enable it. To do this you must enable the root user:

  1. Choose Apple menu -> System Preferences, and then click Users & Groups.
  2. Click the lock icon to unlock it, and then type an administrator name and password.
  3. In the Network Account Server section, click Join or Edit.
  4. Click Open Directory Utility.
  5. Click the lock icon to unlock it, and then enter your administrator name and password.
  6. Choose Edit -> Enable Root User, and then enter a root user password in the Password and Verify fields.

Your Mac should now be ready to compile, configure, and install the OMI package as shown in part 2.

Posted in Apple Mac, Management Pack, MP, OpsMgr 2012 | 1 Comment

JScript Discovery

The other day I got a email asking if I had some example code for discovering SCOM objects by using JScript. My first thought was that it shouldn’t be to hard, but after searching the internet there was next to nothing on using JScript in SCOM discoveries.  I was interested if I could get it to work, so here is the result.

The code snippet is a complete discovery for the application component MPAlchemy.JScript.Example.Class1.

var SourceID = WScript.arguments(0);
var ManagedEntityId = WScript.arguments(1);
var PrincipalName = WScript.arguments(2);

    var scriptAPI = new ActiveXObject('MOM.ScriptAPI');

oDiscoveryData = scriptAPI.CreateDiscoveryData(0, SourceID, ManagedEntityId);

var oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='MPAlchemy.JScript.Example.Class1']$");

oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", PrincipalName);
oInstance.AddProperty("$MPElement[Name='MPAlchemy.JScript.Example.Class1']/Name$", PrincipalName);
oInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", PrincipalName);

oDiscoveryData.AddInstance(oInstance);

scriptAPI.Return(oDiscoveryData);

Below you will find the complete listing for the management pack.

<ManagementPack ContentReadable="true" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <Manifest>
    <Identity>
      <ID>MPAlchemy.JScript.Example</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>MPAlchemy.JScript.Example</Name>
    <References>
      <Reference Alias="SC">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>6.1.7221.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Windows">
        <ID>Microsoft.Windows.Library</ID>
        <Version>6.1.7221.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Health">
        <ID>System.Health.Library</ID>
        <Version>6.1.7221.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>6.1.7221.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="MPAlchemy.JScript.Example.Class1" Accessibility="Internal" Abstract="false" Base="Windows!Microsoft.Windows.LocalApplication" Hosted="true" Singleton="false">
          <Property ID="Name" Type="string" Key="true" CaseSensitive="false" Length="256" MinLength="0" />
        </ClassType>
      </ClassTypes>
    </EntityTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="MPAlchemy.JScript.Example.Discovery" Enabled="true" Target="Windows!Microsoft.Windows.Computer" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="MPAlchemy.JScript.Example.Class1" />
        </DiscoveryTypes>
        <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
          <IntervalSeconds>60</IntervalSeconds>
          <SyncTime />
          <ScriptName>ExampleDiscovery.js</ScriptName>
          <Arguments>$MPElement$ $Target/Id$ $Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Arguments>
          <ScriptBody><![CDATA[
var SourceID = WScript.arguments(0);
var ManagedEntityId = WScript.arguments(1);
var PrincipalName = WScript.arguments(2);

    var scriptAPI = new ActiveXObject('MOM.ScriptAPI');

oDiscoveryData = scriptAPI.CreateDiscoveryData(0, SourceID, ManagedEntityId);

var oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='MPAlchemy.JScript.Example.Class1']$");

oInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", PrincipalName);
oInstance.AddProperty("$MPElement[Name='MPAlchemy.JScript.Example.Class1']/Name$", PrincipalName);
oInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", PrincipalName);

oDiscoveryData.AddInstance(oInstance);

scriptAPI.Return(oDiscoveryData);]]></ScriptBody>
          <TimeoutSeconds>60</TimeoutSeconds>
        </DataSource>
      </Discovery>
    </Discoveries>
  </Monitoring>
  <Presentation>
    <Views>
      <View ID="MPAlchemy.JScript.Example.StateView" Accessibility="Internal" Enabled="true" Target="MPAlchemy.JScript.Example.Class1" TypeID="SC!Microsoft.SystemCenter.StateViewType" Visible="true">
        <Category>AvailabilityHealth</Category>
        <Criteria />
      </View>
    </Views>
    <Folders>
      <Folder ID="MPAlchemy.JScript.Example.ViewFolder" Accessibility="Internal" ParentFolder="SC!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
    </Folders>
    <FolderItems>
      <FolderItem ElementID="MPAlchemy.JScript.Example.StateView" Folder="MPAlchemy.JScript.Example.ViewFolder" />
    </FolderItems>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="MPAlchemy.JScript.Example">
          <Name>MPAlchemy JScript Example</Name>
        </DisplayString>
        <DisplayString ElementID="MPAlchemy.JScript.Example.Class1">
          <Name>MPAlchemy JScript Example Class1</Name>
        </DisplayString>
        <DisplayString ElementID="MPAlchemy.JScript.Example.Class1" SubElementID="Name">
          <Name>Name</Name>
          <Description>Name</Description>
        </DisplayString>
        <DisplayString ElementID="MPAlchemy.JScript.Example.Discovery">
          <Name>MPAlchemy JScript Example Discovery</Name>
          <Description />
        </DisplayString>
        <DisplayString ElementID="MPAlchemy.JScript.Example.StateView">
          <Name>State</Name>
          <Description />
        </DisplayString>
        <DisplayString ElementID="MPAlchemy.JScript.Example.ViewFolder">
          <Name>MPAlchemy JScript Example</Name>
          <Description />
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>

Download the management pack here: MPAlchemy.JScript.Example.zip

Posted in JScript, Management Pack, OpsMgr 2012 | Tagged , , | Leave a comment

Creating a SCOM instance in C#

This post is more as a not to self: How to create a SCOM (SDK) instance for a custom Management Pack in C#:

 

http://msdn.microsoft.com/en-us/library/hh964567.aspx

 

EnterpriseManagementGroup mg = new EnterpriseManagementGroup(“localhost”);
ManagementPack mp = mg.GetManagementPack(“RePackaging.Library”, null, new Version());
ManagementPackClass requestClass = mp.GetClass(“RePackaging.Request”);
CreatableEnterpriseManagementObject request = new CreatableEnterpriseManagementObject(mg, requestClass);

// Set a property by name
request[requestClass, “SoftwareTitle”].Value = “Software Application A”;

// Set a property by reference
ManagementPackProperty property = requestClass[“Requester”];
request[property].Value = “Domain\\User1”;

// Set a property by identifier (the DisplayName property)
Guid propertyGuid = new Guid(“883cd2bb-eb57-b4ff-bbf2-69b7cf4570dc”);
request[propertyGuid].Value = “Software Application A – Domain\\User1”;

request.Commit();

Posted in MP, OpsMgr 2012 | Tagged | Leave a comment

Creating an extesion attribute with the VSE

If you need to add an extension attribute to a class, the linked post will show you how to achieve this step-by-step:

 

http://blogs.technet.com/b/emreguclu/archive/2012/11/07/extending-windows-computer-class-using-visual-studio-authoring-extensions-vsae.aspx

| Leave a comment