Public/Invoke-CMBuild.ps1
#requires -RunAsAdministrator #requires -version 3 <# .SYNOPSIS SCCM site server installation script .DESCRIPTION Yeah, what he said. .PARAMETER XmlFile [string](optional) Path and Name of XML input file .PARAMETER NoCheck [switch](optional) Skip platform validation restrictions .PARAMETER NoReboot [switch](optional) Suppress reboots until very end .PARAMETER Detailed [switch](optional) Show verbose output .PARAMETER Override [switch](optional) Choose package items to execute directly from GUI menu .PARAMETER Resume [switch](optional) Indicates a resumed process request .NOTES 1.0.5 - 11/13/2017 - David Stein Read the associated XML to make sure the path and filename values all match up like you need them to. .EXAMPLE Invoke-CMBuild -XmlFile .\cmbuild.xml -Verbose Invoke-CMBuild -XmlFile .\cmbuild.xml -NoCheck -NoReboot -Detailed #> function Invoke-CMBuild { [CmdletBinding(SupportsShouldProcess=$True)] param ( [parameter(Mandatory=$True, HelpMessage="Path or URI of XML input file")] [ValidateNotNullOrEmpty()] [string] $XmlFile, [parameter(Mandatory=$False, HelpMessage="Skip platform validation checking")] [switch] $NoCheck, [parameter(Mandatory=$False, HelpMessage="Suppress reboots")] [switch] $NoReboot, [parameter(Mandatory=$False, HelpMessage="Display verbose output")] [switch] $Detailed, [parameter(Mandatory=$False, HelpMessage="Override control set from XML file")] [switch] $Override, [parameter(Mandatory=$False, HelpMessage="Resume from previous unfinished processing")] [switch] $Resume ) Write-Host "CMBuild $CMBuildVersion" -ForegroundColor Cyan $ScriptPath = Get-ScriptDirectory $RunTime1 = Get-Date $tsFile = "$LogsFolder\cm_build`_$HostName`_transaction.log" try {stop-transcript -ErrorAction SilentlyContinue} catch {} try {Start-Transcript -Path $tsFile -Force} catch {} if ($Resume) {$OpenKey = 'RESUME'} else {$OpenKey = 'BEGIN'} Write-Log -Category "info" -Message "******************* $OpenKey $(Get-Date) *******************" Write-Log -Category "info" -Message "script version = $CMBuildVersion" Install-CMBuildModules [xml]$xmldata = Get-CMxConfigData $XmlFile Write-Log -Category "info" -Message "----------------------------------------------------" if ($xmldata.configuration.schemaversion -ge $SchemaVersion) { Write-Log -Category "info" -Message "xml template schema version is valid" } else { Write-Log -Category "info" -Message "xml template schema version is invalid: $($xmldata.configuration.schemaversion)" Write-Warning "The specified XML file is not using a current schema version" break } Set-CMxTaskCompleted -KeyName 'START' -Value $(Get-Date) if ($Override) { $controlset = $xmldata.configuration.packages.package | Out-GridView -Title "Select Packages to Run" -PassThru } else { $controlset = $xmldata.configuration.packages.package | Where-Object {$_.use -eq '1'} } if ($controlset) { $project = $xmldata.configuration.project $AltSource = $xmldata.configuration.sources.source | Where-Object {$_.name -eq 'WIN10'} | Select-Object -ExpandProperty path Write-Log -Category "info" -Message "alternate windows source = $AltSource" Write-Log -Category "info" -Message "----------------------------------------------------" Write-Log -Category "info" -Message "project info....... $($project.comment)" if (-not (Import-CMxFolders -DataSet $xmldata)) { Write-Warning "error: failed to create folders (aborting)" break } if (-not (Import-CMxFiles -DataSet $xmldata)) { Write-Warning "error: failed to create files (aborting)" break } Write-Host "Executing project configuration" -ForegroundColor Green Disable-InternetExplorerESC | Out-Null Set-CMxRegKeys -DataSet $xmldata -Order "before" | Out-Null Write-Log -Category "info" -Message "beginning package execution" Write-Log -Category "info" -Message "----------------------------------------------------" $continue = $True $pkgcount = 0 foreach ($package in $controlset) { if ($continue) { $pkgName = $package.name $pkgType = $package.type $pkgComm = $package.comment $payload = $xmldata.configuration.payloads.payload | Where-Object {$_.name -eq $pkgName} $pkgSrcX = $xmldata.configuration.sources.source | Where-Object {$_.name -eq $pkgName} $pkgSrc = $pkgSrcX.path $pkgFile = $payload.file $pkgArgs = $payload.params $detRule = $xmldata.configuration.detections.detect | Where-Object {$_.name -eq $pkgName} $detPath = $detRule.path $detType = $detRule.type $depends = $package.dependson Write-Log -Category "info" -Message "package name.... $pkgName" Write-Log -Category "info" -Message "package type.... $pkgType" Write-Log -Category "info" -Message "package comment. $pkgComm" Write-Log -Category "info" -Message "payload source.. $pkgSrc" Write-Log -Category "info" -Message "payload file.... $pkgFile" Write-Log -Category "info" -Message "payload args.... $pkgArgs" Write-Log -Category "info" -Message "rule type....... $detType" if (!(Test-CMxPackage -PackageName $dependson)) { Write-Log -Category "error" -Message "dependency missing: $depends" $continue = $False break } if (($detType -eq "") -or ($detPath -eq "") -or (-not($detPath))) { Write-Log -Category "error" -Message "detection rule is missing for $pkgName (aborting)" $continue = $False break } $installed = $False $installed = Get-CMxInstallState -PackageName $pkgName -RuleType $detType -RuleData $detPath if ($installed) { Write-Log -Category "info" -Message "install state... $pkgName is INSTALLED" } else { Write-Log -Category "info" -Message "install state... $pkgName is NOT INSTALLED" $x = Invoke-CMxPackage -Name $pkgName -PackageType $pkgType -PayloadSource $pkgSrc -PayloadFile $pkgFile -PayloadArguments $pkgArgs if ($x -ne 0) {$continue = $False; break} } $pkgcount += 1 Write-Log -Category "info" -Message "----------------------------------------------------" if (Test-PendingReboot) { if ($NoReboot) { Write-Log -Category 'info' -Message 'a reboot is required - but NoReboot was requested.' Write-Warning "A reboot is required but has been suppressed." } else { Write-Log -Category 'info' -Message 'a reboot is requested.' Invoke-CMxRestart -XmlFile $XmlFile Write-Warning "A reboot is requested. Reboot now." Restart-Computer -Force break } } } else { Write-Warning "STOP! aborted at step [$pkgName] $(Get-Date)" break } } # foreach if (($pkgcount -gt 0) -and ($continue)) { Set-CMxRegKeys -DataSet $xmldata -Order "after" | Out-Null } } Write-Host "Processing finished at $(Get-Date)" -ForegroundColor Green $RunTime2 = Get-TimeOffset -StartTime $RunTime1 Write-Log -Category "info" -Message "finished at $(Get-Date) - total runtime = $RunTime2" if ((Test-PendingReboot) -and ($NoReboot)) { Write-Host "A REBOOT is REQUIRED" -ForegroundColor Cyan } Stop-Transcript } Export-ModuleMember -Function Invoke-CMBuild |