Desired State Configuration for Linux


As you (may) know, Desired State Configuration for Linux is available since May 6 on the Microsoft Open Source github ! This version works like a charm alongside Windows Management Framework v5.

The goal of this post is to show you how it works and what you need in order to get it working. Everything here has been tested with the lastest version available:

Open Management Infrastructure

Open Management Infrastructure (OMI) is an OMI Open Source Project that permit to enable CIM/WBEM DMTF standards.

[su_note note_color=”#ffffff” radius=”6″]OMI’s primary goal is to provide a rich, high-performance, standards-based management stack that is suitable for a wide range of management applications. This includes cloud management, storage management, server hardware management, device management, and network management, on both large and small systems (embedded and mobility). To support this goal, OMI implements DMTF CIM/WBEM standards with the following characteristics: A very small footprint A provider generator model which makes the task of creating providers very easy High portability to a wide variety of hardware and software High performance Support for WS-Management OMI is an open source project to further the development of a production quality implementation of the DMTF CIM/WBEM standards. The OMI CIMOM is also designed to be portable and highly modular. In order to attain its small footprint, it is coded in C, which also makes it a much more viable CIM Object Manager for embedded systems and other infrastructure components that have memory constraints for their management processor. OMI is also designed to be inherently portable. It builds and runs today on most versions of UNIX(r) and Linux. In addition to OMI’s small footprint, it also demonstrates very high performance. At the technical level, the OMI Project operates on the principle of consensus-based decision making, with a light-weight process of approving code check-ins. The Project Management Committee recognizes merit among the community of technical contributors by granting individuals approval rights (Committers)[/su_note]

In other words when you install OMI on your linux box, you will be able to connect using a CIM Session on it using PowerShell Cmdlets !

OMI Installation

OMI installation is pretty simple. You can use the following lines in order to do this logged as root.

yum -y groupinstall 'Development Tools'
yum -y install pam-devel openssl-devel python python-devel wget curl-devel

cd /tmp
tar -xvf omi-
cd omi-1.0.8

Local Configuration Manager

The Local Configuration Manager for Linux brings the same tools as on Windows. It means you can configure your server using PULL or PUSH DSC. Microsoft has done a great work porting it on Linux !

LCM Installation

Local Configuration Manager is pretty simple too, you can use the following lines in order to do this logged as root.

cd /tmp
tar -xvf PSDSC.tar
cd dsc
mv * /tmp
make reg

Connect using CIM Session

Our Linux has OMI installed and configured with LCM.The first thing to do is open the WSMan HTTPS port in firewall

iptables -A INPUT -p tcp --dport 5986 -j ACCEPT
service iptables restart

Now let’s start the OMI Server,

/opt/omi-1.0.8/bin/omiserver -d

If you want to run this in an active console, to troubleshoot, you could use this


Right now our omi server is running smoothly, but if it’ll start with the system it’d be better, no ?

Michael Green has posted a solution for this on his Technet blog. Open a vim editor in your console and save this script as /etc/init.d/omiserver

#! /bin/sh

 # Provides:          omiserver
 # Required-Start:    $local_fs $remote_fs
 # Required-Stop:    $local_fs $remote_fs
 # Default-Start:     3 4 5
 # Default-Stop:      0 1 2 6
 # Short-Description: omiserver initscript
 # Description:      omiserver


 # Do NOT "set -e"

 export OMI_HOME=/opt/omi-1.0.8/

 # Define LSB log_* functions.
 # Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
 . /lib/lsb/init-functions
 # Function that starts the daemon/service
         /opt/omi-1.0.8/bin/omiserver -d

 # Function that stops the daemon/service
       pid=`cat $PIDFILE`
        kill -9 $pid

 case "$1" in
         echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
         exit 3

And now, we just have to regikster the script as a service.

chmod 755 /etc/init.d/omiserver
chkconfig omiserver on
service omiserver start

Let’s now use PowerShell to build a CIM Session and connect to Local Configuration Manager 🙂

$Credentials = get-credential
$CimOptions = New-CimSessionOption -SkipCACheck -SkipCNCheck -UseSsl -SkipRevocationCheck
$CimSession = New-CimSession -Credential $Credentials -ComputerName -port 5986 -Authentication Basic -SessionOption $CimOptions

Now, you’re connected to the CIM Session, let’s confirm it works !

Get-CimInstance -CimSession $CimSession -namespace root/omi -ClassName omi_identify
InstanceID             : 2FDB5542-5896-45D5-9BE9-DC04430AAABE
SystemName             : DSCLinux
ProductName            : OMI
ProductVendor          : Microsoft
ProductVersionMajor    : 1
ProductVersionMinor    : 0
ProductVersionRevision : 8
ProductVersionString   : 1.0.8-1
Platform               : LINUX_X86_64_GNU
OperatingSystem        : LINUX
Architecture           : X86_64
Compiler               : GNU
ConfigPrefix           : GNU
ConfigLibDir           : /opt/omi-1.0.8/lib
ConfigBinDir           : /opt/omi-1.0.8/bin
ConfigIncludeDir       : /opt/omi-1.0.8/include
ConfigDataDir          : /opt/omi-1.0.8/share
ConfigLocalStateDir    : /opt/omi-1.0.8/var
ConfigSysConfDir       : /opt/omi-1.0.8/etc
ConfigProviderDir      : /opt/omi-1.0.8/etc
ConfigLogFile          : /opt/omi-1.0.8/var/log/omiserver.log
ConfigPIDFile          : /opt/omi-1.0.8/var/run/
ConfigRegisterDir      : /opt/omi-1.0.8/etc/omiregister
ConfigSchemaDir        : /opt/omi-1.0.8/share/omischema
ConfigNameSpaces       : {interop, root-omi, root-cimv2, root-Microsoft-DesiredStateConfiguration...}
PSComputerName         :

 Push DSC Configuration on Linux

As usual with DSC we’ll need resources for Linux, they are now available on github here. Once downloaded and unzipped. Put the nx resource in the same dire as usual C:\Program Files\WindowsPowerShell\Modules.

You can confirm that the resource is correctly imported using Get-DscResource and see it listed. This is not a scripted resource, but a binary one.

So let’s now start with a quick configuration.

Configuration MyDSCDemo {

   Import-DSCResource -Module nx

   Node "" {    

        nxFile myTestFile {

            Ensure = "Present" 
            Type = "File"
            DestinationPath = "/tmp/dsctest"   
            Contents="This is my DSC Test!"

Set-Location C:\temp

Our MOF file is now available in C:\temp\MyDSCDemo 🙂

Start-DscConfiguration -CimSession $CimSession -wait -Verbose -Path C:\temp\MyDSCDemo
Get-DscConfiguration -CimSession $CimSession

[su_frame align=”center”]dsc_linux_02[/su_frame]

Pull DSC Configuration on Linux

In order to make the LCM pull a configuration we have to configure it. To do this, this is EXACTLY the same process as in Windows.

Get-DscLocalConfigurationManager -CimSession $CimSession
ActionAfterReboot              :
AllowModuleOverWrite           : False
CertificateID                  :
ConfigurationDownloadManagers  : {}
ConfigurationID                :
ConfigurationMode              : ApplyAndMonitor
ConfigurationModeFrequencyMins : 30
Credential                     :
DebugMode                      :
DownloadManagerCustomData      :
DownloadManagerName            :
LCMCompatibleVersions          :
LCMState                       :
LCMVersion                     :
MaxPendingConfigRetryCount     :
StatusRetentionTimeInDays      :
PartialConfigurations          : {}
RebootNodeIfNeeded             : False
RefreshFrequencyMins           : 15
RefreshMode                    : PUSH
ReportManagers                 : {}
ResourceModuleManagers         : {}
PSComputerName                 :
PSComputerName                 :


Assuming you already have a pull Server on your network, let’s build a configuration and change it to a pulled one.

Configuration MyDSCDemo {

   Import-DSCResource -Module nx

   Node "" {    

        nxFile myTestFile {
            Ensure = "Present" 
            Type = "File"
            DestinationPath = "/tmp/dsctest"   
            Contents="PULL Server Test"


Set-Location C:\temp


Ouf MOF file is created let’s move it to our Pull Server.

$Guid = [guid]::NewGuid() 
$source = “C:\temp\MyDSCDemo\” 
$target= “c:\program files\windowspowershell\dscservice\configuration\$Guid.mof” 
Copy-Item $source $target -force
New-DscCheckSum $target

[su_frame align=”center”]dsc_linux_03[/su_frame]

And finally, configure the LCM in Pull mode.

Configuration SetPullMode {
    param (
    Node {
        LocalConfigurationManager {
            ConfigurationMode = ‘ApplyOnly’
            ConfigurationID = $guid
            RefreshMode = ‘Pull’
            DownloadManagerName = ‘WebDownloadManager’
            DownloadManagerCustomData = @{
            ServerUrl = ‘';
                        AllowUnsecureConnection = ‘true’ }

SetPullMode –guid 72dfef13-56aa-4a53-a8aa-fa190acfbc09
Set-DSCLocalConfigurationManager –cimsession $cimsession -Path C:\breizhcamp\demo-1\SetPullMode –Verbose -wait
Get-DscLocalConfigurationManager -CimSession $CimSession

[su_frame align=”center”]dsc_linux_04[/su_frame]

Let’s now force the PULL request

Update-DscConfiguration -CimSession $CimSession

[su_frame align=”center”]dsc_linux_05[/su_frame]

The job will take 2-3 seconds to finish. Let’s verify everything is correctly applied !

Get-DscConfiguration -CimSession $CimSession

[su_frame align=”center”]dsc_linux_06[/su_frame]


Ok it seems LCM is working on both Push & Pull mode! Very cool 🙂

If you have any questions, please ask in comments.

I want to thanks Bartek Bielawski for his help !