Share via


Let's Deploy SCCM Linux Client via PowerShell

So installing the System Center Configuration Manager client for Linux is simple.  It doesn't require a reboot, there are few parameters, and it can be scriptable.  So typically most Linux admins will have some sort of remote automation tool, such as Puppet.  But sometimes they don't or it's not Linux admins doing the install.  That's where PowerShell can help.  If you have a lot of Linux systems that need to have the client installed the first time, upgraded, or you are changing site code / management point you need a way to automate it.  I ran into these issues.  So I developed a PowerShell script that helped me so I thought I would share it.  It's not a script that is 100% universal.  It will most likely need to be customized but it's not difficult to customize.  The parts that will need to be modified are "shell.Read()".  Shell.Read() reads the output on the screen of the Linux system and in some places of the script it is looking for something in particular from the output.  This is where you will have to customize it for the output of your Linux system.  There is one catch with it, once you read the screen that portion of the screen essentially disappears and if you do another read you will get blank results.

First of all, the script uses Posh-SSH to to connect to the remote Linux system and send commands to the Linux system.  Instructions can be found here to install the Posh-SSH module.

The script can accept a text doc with a list of system names/ip addresses or a single system name / ip address.

I recommend testing this against a single system first before running against multiple systems.

Check it out and if you have questions please comment and I will respond.

 ##################################################################
# Microsoft provides programming examples for illustration only, 
# without warranty either expressed or implied, including, but not 
# limited to, the implied warranties of merchant-ability and/or 
# fitness for a particular purpose. 
#
# This sample assumes that you are familiar with the programming 
# language being demonstrated and the tools used to create and debug 
# procedures. Microsoft support professionals can help explain the 
# functionality of a particular procedure, but they will not modify 
# these examples to provide added functionality or construct 
# procedures to meet your specific needs. If you have limited 
# programming experience, you may want to contact a Microsoft 
# Certified Partner or the Microsoft fee-based consulting line at 
# (800) 936-5200. 
#
# For more information about Microsoft Certified Partners, please 
# visit the following Microsoft Web site:
# https://partner.microsoft.com/global/30000104
#
###################################################################
 Param(
[Parameter(Mandatory=$true)][string]$object
)

#This will load the PowerShell SSH module.
if (Import-Module -name posh-ssh -ErrorAction Ignore) {write-host "Module is loaded"}
else {
    write-host "Module is not loaded"
    write-host "Module is being loaded"
    #############################################################################
    #The Posh-SSH.zip file needs to be copied to the Modules directory prior to running.
    #DO NOT CHANGE THIS
    $targetondisk = "$($env:USERPROFILE)\Documents\WindowsPowerShell\Modules"
    ##############################################################################
    $directory = Get-Location
    $file = $directory.Path + "\Posh-SSH.zip"
    New-Item -ItemType Directory -Force -Path $targetondisk | out-null
    $shell_app=new-object -com shell.application
    $zip_file = $shell_app.namespace($file)
    Write-Host "Uncompressing the Zip file to $($targetondisk)" -ForegroundColor Cyan
    $destination = $shell_app.namespace($targetondisk)
    $destination.Copyhere($zip_file.items(), 0x10)
    Write-Host "Module has been installed" -ForegroundColor Green
    Import-Module -Name Posh-SSH
}



#This function will copy the tar file and install file to the target system and then install them.
Function InstallSCCM ($linuxsystem, $creds)
{
    #####################################################
    #Update these variables for your environment.  The Tar file and install file are to be local to the systme running the script.
    $CCMTarFile = "C:\temp\script\ccm-Universalx64.tar"
    $CCMInstallFile = "C:\temp\script\install.sh"
    $SiteCode = "STC"
    $MP = "MP-FQDN"
    #####################################################
    $tempdir = "/tmp/sccmInstall"
    [securestring]$passwd = $creds.Password.Copy()
    $session = New-SSHSession -ComputerName $linuxsystem -Credential $creds
    $shell = New-SSHShellStream -SessionId $session.SessionId

    If ($session.Connected) {

        Write-Host "Installing SCCM on " $linuxsystem
        $shell.Read()
        Start-Sleep -Seconds 2
        $shell.Read()
        Invoke-SSHStreamExpectSecureAction -ShellStream $shell -Command "sudo su -" -ExpectString "ssword" -SecureAction ($passwd) > $null
        $shell.Read()

        $shell.WriteLine("mkdir $($tempdir)")
        $shell.Read()
        $shell.WriteLine("chmod 777 $($tempdir)")
        $shell.Read()

        Set-SCPFile -ComputerName $linuxsystem -Credential $creds -LocalFile $CCMTarFile -RemotePath $tempdir
        Set-SCPFile -ComputerName $linuxsystem -Credential $creds -LocalFile $CCMInstallFile -RemotePath $tempdir

        $shell.writeline("ls $($tempdir)")
        $shell.Read()
        Start-Sleep -s 2
       

        $fileexist = $shell.Read()
    
        IF ($fileexist -match "ccm-Universalx64.tar" -and $fileexist -match "install.sh") {
    
            $shell.WriteLine("chmod +x $($tempdir)/install.sh")
            write-host "Starting Installation..."
            $shell.WriteLine("$($tempdir)/install.sh -mp " + $MP + " -sitecode " + $SiteCode + " -clean $($tempdir)/ccm-Universalx64.tar")
    
            Do {
                $output = $shell.Read()
               } until ($output -match "complete")
            
            $output
            write-host "Performing Clean-up"
            Start-Sleep -s 5
            $shell.WriteLine("rm -rf $($tempdir)")
            Start-Sleep -s 5
            $shell.Close()
            Remove-SSHSession -SessionId $session.SessionId > $null
        }
        Else {
            write-host "Files do not exist on system"
            $shell.WriteLine("rm -rf $($tempdir)")
            $shell.Close()
            Remove-SSHSession -SessionId $session.SessionId > $null
        }
    }
    Else {
        write-host "Failure to connect to system"
        get-sshsession | Remove-SSHSession > $null
    }
}

#Asks for Linux Credentials
$creds = Get-Credential

#tests if the parameter is a single system name or a file with a list of systems.
If (Test-Path $object) {
    foreach ($linuxsystem in Get-Content -Path $object){
        InstallSCCM $linuxsystem $creds
        }
    $creds.Password.Dispose()
    }
Else {
    $linuxsystem = $object
    InstallSCCM $linuxsystem $creds
    $creds.Password.Dispose()
    }