Automating the Linux SCCM Client install with Orchestrator

Orchestrator can be used to automate the installation of SCCM on template deployed Linux machines.  Microsoft’s growing support for Linux platforms allows SCCM to be used for centralised reporting while opening the door for SCCM to become a unified platform deployment system at some stage in the future.

System Center Orchestrator has a considerable strength in being able to be activated via REST request.  This allows runbooks to be activated from either PowerShell or any system utilising web based interfaces.  It allows for a process to deploy a Linux template then immediately initiate an SCCM client install remotely.  

Attached to this blog is an example Orchestrator runbook that allows the SCCM client to be installed on remote machines.

Prerequisites

Orchestrator will need to use an administrative account to install software on Linux machines.  It is assumed that the credentials to a known account will exist on the target machines.   

The administrative account to be used with the install must be added to the /etc/sudoers file so as not to prompt for passwords when the account is installing software. 

Both of these changes must pre-exist in any Linux template being cloned

SCCM Client for Linux installation

The latest version of the SCCM client installation files must be downloaded from Microsoft.  The current version I have been using was released October 2014 and is available in the compressed format of “Config Mgr Clients for Linux.exe” http://www.microsoft.com/en-au/download/details.aspx?id=39360 .The contents of this self-extracting archive need to be copied to a local subdirectory on your Orchestrator server.

Optionally, you may wish to update Orchestrator’s SSH client if Linux distributions have been hardened.

A copy of the putty variant of Secure Copy (pscp.exe) must also be available on the Orchestrator server.  This will be used to transfer the SCCM client installation files (ccm-Universalx64.tar & install) to the machine of your choosing.  Ideally, an updated copy of plink.exe should also be downloaded… both files may be found here:http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

Workflow / Runbook Process

With this example, the automated SCCM client install uses the following actions:

1.    An online check is completed that verifies that port 22 is open on the targeted Linux machine.

2.     New Linux machines will prompt for saving details of their connection as trusted resources.  This is a one off prompt but until their client key is accepted, no further automation can be performed against the machine.  A simple way to ensure the client key has been accepted is by sending a “y” character when invoking a simple SSH command.  The action can be rerun harmlessly and it ensures that new client keys don’t cause problems with a workflow.

3.     Client Installation Files are transferred to the /tmp directory of the targeted Linux machine.  This uses:

$p = Start-Process cmd.exe - "/c E:\SCORCH\sccm\pscp.exe -l $ -pw $ -C - E:\SCORCH\sccm\install $`@$`:/tmp/" -wait - Hidden -PassThru

 

4.   The /tmp/install file is made executable  

 chmod  +x /tmp/install

 

5.   The  client is installed.  The syntax being:

 /tmp/./install -mp %SCCMSERVER% /tmp/ccm-Universalx64.tar -sitecode %SITE% -keepdb -fsp %FALLBACKSTATUSPOINT%

 The order in which elements of the command are placed has been critical with the SCCM client range.  The parameter “” is used in case of reinstall and is not a requirement of a fresh install.  The elements highlighted as bold in the above command all need to be customised for your particular environment.

6.   The target machine is rebooted.  This is to ensure all services are in a running state.

7.   The new Linux machine is approved as a client within SCCM

Code Snippet – SCCM Client Approval

The code snippet below shows how the Runbook activity uses powershell to appove an installed client.

#Example inputs (received as Orchestrtor Variabls / published data)
 
$SCCMServer = "sccmserver.domain.com"
$ClientMachine = "rhel7.domain.com"
 
[PSCustomObject]$InputObject = new-object pscustomobject -property @{
   VIRTUAL_MACHINE = "$ClientMachine"
}
 
# BEGIN
 
#Trap any critical errors for Orchestrator to display
 
$ErrorActionPreference = "Stop"
trap { 
    throw  ($_ | format-list * -force | out-string) 
}
 
##Connect to SCCM Server
$PSSession = new-pssession -computername $SCCMServer -ConfigurationName Microsoft.PowerShell32
 
$WinRMResult = Invoke-Command -session $PSSession -Scriptblock{
 
  $inobject = $args[0]
 
  $ClientMachine    = $inobject.VIRTUAL_MACHINE
  $Result = "FAIL"
  Set-ExecutionPolicy Unrestricted -Force
 
  ###  BEGIN
  #Import the SCCM modules
  Import-Module (Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) ConfigurationManager.psd1) 
 
  #Change to the Configuration Manager Drive
  $SCCMDrive = Get-PSDrive | Where-Object {  $_.Provider.Name -eq "CMSite"}
  Set-Location "$($SCCMDrive):"
 
  # The number of times to try the loop
  $loopcount = 20
  # set the default response of the script
  $result = "FAIL"
 
  do {
        $ofoundmachine = Get-CMDevice -Name  $ClientMachine          
        if ($ofoundmachine  -ne $null){
               Approve-CMDevice -DeviceName  $ClientMachine
               sleep 15 
 
               $ofoundmachine = Get-CMDevice -Name  $ClientMachine
 
               if ($ofoundmachine.IsApproved -eq 1){
                     #machine has been approved
                     $message = "Device $($VirtualMachine) exists and has been approved"
                     $result = "pass"
                   }
                else
                   {
                      $message = "Device $($ClientMachine) exists but IS NOT approved"
                    }
                    $loopcount = 0
                }  
           else
           {
                $message = "Device $($ClientMachine) does not Exist"
                # Wait 10 seconds before checking again
                sleep 10 
                $loopcount = $loopcount - 1 
            }
 
 
    } until($loopcount -eq 0)
 
     ### Create Object to return variables to the calling script
     ### Populate it with the variables we are interested in
 
     [PSCustomObject]$ReturnObject = new-object pscustomobject -property @{
          SCRIPTRESULT  = $result 
          SCRIPTMESSAGE = $Message
      }
 
      #send the object back up the pipe
      $ReturnObject
 
        } -argumentlist $InputObject 
 
#Retrieve the returned strings
 
$Result      = $WinRMResult.SCRIPTRESULT
$Message     = $WinRMResult.SCRIPTMESSAGE
 
# Clear the used PSSession
Remove-PSSession $PSSession

A copy of the example runbook is available for download here: sccmclientinstallrunbook.ois_export

*  The example workflow prompts for a username and password for Linux when it is being invoked.  It would be better to use system variables, not only for ease but to also ensure that the account credentials arent automatically logged.    

*  The PowerShell script for approving clients could be prone to inconsistency due to wait timeouts.  It works in a single site environment but has required some tweaking to do so.  It could do with some real world testing in a larger environment although it is good enough to serve as an example for improvement.