Skip to content

Instantly share code, notes, and snippets.

@TJM
Last active March 25, 2023 01:16
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save TJM/f67fade2cf1f2ab06b6094f1aae6bce6 to your computer and use it in GitHub Desktop.
Save TJM/f67fade2cf1f2ab06b6094f1aae6bce6 to your computer and use it in GitHub Desktop.
Puppet SCCM Client Install as a package

SCCM Install using Puppet "package"

This script was donated by a customer of ours. They have sent us a sanitized version of the script to share.

Please use this at your own risk, and fully understand what it is doing before using it!

The Problem:

SCCM Installation fires off in the background and you have no idea whether it worked or not. Also, if any other installs try to start while the SCCM setup is running, you will get an error.

The Workaround:

Run the SCCM Installation as a powershell script that watches the log file for the completion status.

This allows puppet to install SCCM Client as a "package" (not an exec), which uses built in providers to determine if it is installed, at the right version, or not.

Also, this "holds" the puppet agent's attention while the installation is in progress, so that it doesn't try to run another install.

~tommy

# Class: profile::windows::sccm
class profile::windows::sccm (
String $version = 'present',
Array $args = [],
String $tempdir = 'c:\windows\ccmsetup'
) {
$install_script = "${tempdir}\\SCCMInstall.ps1"
$package_args = concat([$install_script], $args)
file { $tempdir:
ensure => directory,
}
file { $install_script:
ensure => file,
source => 'puppet:///modules/profile/windows/sccm/SCCMInstall.ps1';
}
package { 'Configuration Manager Client':
ensure => $version,
source => 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe',
install_options => $package_args,
require => File[$install_script],
}
}
[CmdletBinding(SupportsShouldProcess=$true,
ConfirmImpact='Medium')]
[OutputType([int])]
Param (
$CCMArgs = '/ignoreskipupgrade SMSSITECODE=1IS RESETKEYINFORMATION=TRUE FSP=<SERVER.FQDN> SMSMP=<SERVER.FQDN> DNSSUFFIX=<ADDOMAIN.FQDN> SMSCACHESIZE=30720',
$CCMSource = '\\<SERVER.FQDN>\<SHARE>\CCMSetup.exe',
$CCMTarget = "$env:SystemRoot\ccmsetup"
)
Process {
if ($pscmdlet.ShouldProcess("$env:COMPUTERNAME", "Installing SCCM Client")) {
try {
if (!(Test-Path -Path $CCMTarget)) {
New-Item -ItemType directory -Path $CCMTarget -ErrorAction Stop -ErrorVariable 'SCCMErr' | Out-Null
Write-Verbose -Message "$env:SystemRoot\ccmsetup directory created"
}
$CCMFile = "$CCMTarget\ccmsetup.exe"
Copy-Item -Path $CCMSource -Destination $CCMTarget -ErrorAction Stop -ErrorVariable 'SCCMErr' | Out-Null
Write-Verbose -Message 'CCMSetup.exe copied locally'
Start-Process -FilePath $CCMFile -ArgumentList $CCMArgs -Wait -ErrorAction Stop -ErrorVariable 'SCCMErr' | Out-Null
Write-Verbose -Message 'SCCM Client Install initiated'
$CCMLogMatch = "<!\[LOG\[CcmSetup is exiting with return code "
do {
Start-Sleep -Seconds 10
$CCMLog = Get-Content -Path "$env:SystemRoot\ccmsetup\Logs\ccmsetup.log"
} until ($CCMLog[-1] -match $CCMLogMatch)
Write-Verbose -Message "CCMSetup completed with $($CCMLog[-1])"
$ReturnCode = ((($CCMLog[-1]) -Split($CCMLogMatch)).Split("]"))[1]
$ReturnCode
<#
SCCM Return codes:
- 0 Success
- 6 Error
- 7 Reboot Required
- 8 Setup already running
- 9 Prerequisite evaluation failure
- 10 Setup manifest hash validation failure
#>
Write-Verbose -Message "CCMSetup completed with return code $ReturnCode"
} catch {
Write-Verbose -Message "SCCM Client Install Failure $SCCMErr"
Throw "Error Initiaiting SCCM Client Install $SCCMErr"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment