Public/Invoke-CMBuild.ps1
#requires -RunAsAdministrator #requires -version 5 function Invoke-CMBuild { <# .SYNOPSIS SCCM site server installation script .DESCRIPTION Yeah, what he said. .PARAMETER XmlFile Path and Name of XML input file .PARAMETER NoCheck Skip platform validation restrictions .PARAMETER NoReboot Suppress reboots until very end .PARAMETER Detailed Show verbose output .PARAMETER ShowMenu Choose package items to execute directly from GUI menu .PARAMETER Resume Indicates a resumed process request .EXAMPLE Invoke-CMBuild -XmlFile .\cmbuild.xml -Verbose .EXAMPLE Invoke-CMBuild -XmlFile .\cmbuild.xml -NoCheck -NoReboot -Detailed .EXAMPLE Invoke-CMBuild -XmlFile .\cmbuild.xml -ShowMenu -Verbose .LINK https://github.com/Skatterbrainz/CMBuild/blob/master/Docs/Invoke-CMBuild.md .NOTES Read the associated XML to make sure the path and filename values all match up like you need them to. #> [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] $ShowMenu, [parameter(Mandatory=$False, HelpMessage="Resume from previous unfinished processing")] [switch] $Resume ) Write-Host "CMBuild $CmBuildSettings['CMBuildVersion']" -ForegroundColor Cyan $ScriptPath = getScriptDirectory $RunTime1 = Get-Date $CmBuildSettings['tsFile'] = "$CmBuildSettings['LogsFolder']\cm_build`_$CmBuildSettings['ComputerName']`_transaction.log" try {stop-transcript -ErrorAction SilentlyContinue} catch {} try {Start-Transcript -Path $CmBuildSettings['tsFile'] -Force} catch {} if ($Resume) {$OpenKey = 'RESUME'} else {$OpenKey = 'BEGIN'} writeLogFile -Category "info" -Message "******************* $OpenKey $(Get-Date) *******************" writeLogFile -Category "info" -Message "script version = $CmBuildSettings['CMBuildVersion']" installCmxPSModules [xml]$xmldata = getCmxConfigData $XmlFile writeLogFile -Category "info" -Message "----------------------------------------------------" if ($xmldata.configuration.schemaversion -ge $CmBuildSettings['SchemaVersion']) { writeLogFile -Category "info" -Message "xml template schema version is valid" } else { writeLogFile -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 } setCmxTaskCompleted -KeyName 'START' -Value $(Get-Date) if ($ShowMenu) { $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 writeLogFile -Category "info" -Message "alternate windows source = $AltSource" writeLogFile -Category "info" -Message "----------------------------------------------------" writeLogFile -Category "info" -Message "project info....... $($project.comment)" if (-not (importCmxFolders -DataSet $xmldata)) { Write-Warning "error: failed to create folders (aborting)" break } if (-not (importCmxFiles -DataSet $xmldata)) { Write-Warning "error: failed to create files (aborting)" break } Write-Host "Executing project configuration" -ForegroundColor Green $null = disableIESC $null = setCmxRegKeys -DataSet $xmldata -Order "before" writeLogFile -Category "info" -Message "beginning package execution" writeLogFile -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 writeLogFile -Category "info" -Message "package name.... $pkgName" writeLogFile -Category "info" -Message "package type.... $pkgType" writeLogFile -Category "info" -Message "package comment. $pkgComm" writeLogFile -Category "info" -Message "payload source.. $pkgSrc" writeLogFile -Category "info" -Message "payload file.... $pkgFile" writeLogFile -Category "info" -Message "payload args.... $pkgArgs" writeLogFile -Category "info" -Message "rule type....... $detType" if (!(testCmxPackage -PackageName $dependson)) { writeLogFile -Category "error" -Message "dependency missing: $depends" $continue = $False break } if (($detType -eq "") -or ($detPath -eq "") -or (-not($detPath))) { writeLogFile -Category "error" -Message "detection rule is missing for $pkgName (aborting)" $continue = $False break } $installed = $False $installed = getCmxInstallState -PackageName $pkgName -RuleType $detType -RuleData $detPath if ($installed) { writeLogFile -Category "info" -Message "install state... $pkgName is INSTALLED" } else { writeLogFile -Category "info" -Message "install state... $pkgName is NOT INSTALLED" $x = invokeCmxPackage -Name $pkgName -PackageType $pkgType -PayloadSource $pkgSrc -PayloadFile $pkgFile -PayloadArguments $pkgArgs if ($x -ne 0) {$continue = $False; break} } $pkgcount += 1 writeLogFile -Category "info" -Message "----------------------------------------------------" if (testPendingReboot) { if ($NoReboot) { writeLogFile -Category 'info' -Message 'a reboot is required - but NoReboot was requested.' Write-Warning "A reboot is required but has been suppressed." } else { writeLogFile -Category 'info' -Message 'a reboot is requested.' invokeCmxRestart -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)) { $null = setCmxRegKeys -DataSet $xmldata -Order "after" } } Write-Host "Processing finished at $(Get-Date)" -ForegroundColor Green $RunTime2 = getTimeOffset -StartTime $RunTime1 writeLogFile -Category "info" -Message "finished at $(Get-Date) - total runtime = $RunTime2" if ((testPendingReboot) -and ($NoReboot)) { Write-Host "A REBOOT is REQUIRED" -ForegroundColor Cyan } Stop-Transcript } |