About the sccm-ts-scripts repo
Table of contents
Purpose
The purpose of this repo is to host scripts that will be downloaded and used on the fly in SCCM Task Sequences (TSes).
Rules
- Don't keep scripts here which will not be used in SCCM TSes. If they are strictly SCCM/TS-related but won't be used in the TS, give them their own new project under the engrit-epm group, or contribute them to the Official EngrIT Script Repo.
- Name scripts in all lowercase, with dashes for word separators, preferably using the
verb-noun[-noun].ext
convention. - This repo is for version control of text-based scripts and configuration files. Don't upload non-text files such as images, or other dependencies such as executables. Keep those on \\engr-wintools, or package them in SCCM.
- Scripts which have associated text/config files should go in their own directory, named after the script if possible.
- This repo is public. DO NOT contribute scripts which have confidential information. See the Securing Credentials section below for info on how to use credentials in TSes and scripts.
- Powershell scripts are preferred. It's really quite easy to translate batch scripts to Powershell, and they will be much cleaner and more flexible.
Usage
Methodologies
There's two basic ways to use these scripts during a task sequence:
Method 1: Download a zip of the entire repo and run scripts locally
This is probably the preferred method. Advantages are that it will be faster, makes running each script much simpler, and reduces the number of connections to GitLab, thus reducing failure points. The disadvantge, if you want to call it one, is that you may end up with a bunch of unneccessary scripts downloaded locally, if you're only going to use one or two.
-
See the Dependencies section below
-
To download the repo zip locally Create a
Run PowerShell Script
step with the following code:
Click to expand.
# Get local directory paths
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$scriptDir = $tsenv.Value('EngrIT_ScriptsGoHere')
$logDir = $tsenv.Value('EngrIT_LogsGoHere')
# Logging
$log = "$logDir\download-scripts-from-repo.log"
function log($msg) {
$timestamp = Get-Date -UFormat "%Y-%m-%d %H:%M:%S"
"[$timestamp] $msg" | Out-File $log -Append
}
log "Downloading scripts from repo..."
# Full master branch zip file
$repo = $tsenv.Value('EngrIT_TSRepo')
$zipURL = "$repo/-/archive/master/sccm-ts-scripts-master.zip"
log "Zip URL: $zipURL"
$zipFilename = $zipURL.Substring($zipURL.LastIndexOf("/") + 1)
$zipDirname = $zipFilename -Replace ".zip",""
$zipDir = "$scriptDir\$zipDirname"
log "Zip filename: $zipFilename"
# Download zip and save to x:\engrit\scripts
$zipPath = "$scriptDir\$zipFilename"
log "Zip destination: $zipPath"
log "Downloading..."
Invoke-WebRequest -Uri $zipURL -OutFile $zipPath | Out-File $log -append
log " Done."
# Extract zip
log "Extracting..."
Expand-Archive -Path $zipPath -DestinationPath $scriptDir | Out-File $log -append
log " Done."
# Move scripts out of archive subdirectory into root x:\engrit\scripts directory
log "Moving scripts up a directory, out of the archive-named directory..."
Move-Item -Path "$zipDir\*" -Destination $scriptDir
Remove-Item $zipDir
log " Done."
log "EOF"
- Once the scripts are on the local system per the above script, you can use them as you see fit. Below is some tidy
Run PowerShell Script
step template code for running a local script. Don't forget to copy any files you need fromx:
toc:
after theApply OS
step, as demonstrated in the Dependencies section.
Click to expand.
# Specify script here
$scriptName = "build-software-string.ps1"
# Don't edit
# ---------------------------------------------------------------------------------------------------
# Get TS variables
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$scriptDir = $tsenv.Value('EngrIT_ScriptsGoHere')
$script = "$scriptDir\$scriptName"
$logDir = $tsenv.Value('EngrIT_LogsGoHere')
$log = "$logDir\$scriptName.log"
# ---------------------------------------------------------------------------------------------------
# Run script
# No need to edit unless you need to add parameters
Powershell -ExecutionPolicy ByPass -File "$script" > "$log" 2>&1
Method 2: Download individual script files and run them
This is also possible, but has the disadvantages of being slower, potentially relying on multiple connections to GitLab, thus increasing failure points, and complicating individual steps that run scripts.
- See the Dependencies section below
- To download and run one of the scripts, create a
Run PowerShell Script
step with the following code:
Click to expand.
# Name of script in repo
$scriptName = "script-name.ps1"
# Don't edit
# ------------------------------------------------------------------------
# Download file and save to x:\engrit\scripts
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$repo = $tsenv.Value('EngrIT_TSRepo')
$scriptURL = "$repo/raw/master/$scriptName"
$logDir = $tsenv.Value('EngrIT_LogsGoHere')
$scriptDir = $tsenv.Value('EngrIT_ScriptsGoHere')
$script = "$scriptDir\$scriptName"
Invoke-WebRequest -Uri $scriptURL -OutFile $script
$log = "$logDir\$scriptName.log"
# ------------------------------------------------------------------------
# Run script
# No need to edit unless you need to add parameters
Powershell -ExecutionPolicy ByPass -File "$script" > "$log" 2>&1
Dependencies
The examples above rely on the following custom task sequence variables and local directories. The variables aren't strictly necessary, and you can replace them in the above code with hard-coded paths... if you're a masochist.
- Before the Apply OS step
-
EngrIT_LogsGoHere
=x:\engrit\logs
-
EngrIT_ScriptsGoHere
=x:\engrit\logs
-
- After the Apply OS step
- Copy
x:\engrit
toc:\engrit
-
EngrIT_LogsGoHere
=c:\engrit\logs
-
EngrIT_ScriptsGoHere
=c:\engrit\scripts
- Copy
-
EngrIT_TSRepo
=https://gitlab.engr.illinois.edu/engrit-epm/sccm-ts-scripts
Example Task Sequence
There's a template TS demonstrating the usage described above located at UIUC-ENGR/UIUC-ENGR-Scripts from GitLab example
.
How to reference variables
Most text fields in a task sequence can simply reference task sequence variables using the %Variable_Name%
syntax. This is not the case in the script editing window of a Run PowerShell Script
step, as all text there is interpreted as Powershell code.
To reference a task sequence variable in powershell code, use the following syntax:
# Gain access to the TS environment variables
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
# To read a TS variable
$foo = $tsenv.Value('EngrIT_Foo')
# To set a TS variable
$tsenv.Value('EngrIT_Foo') = "bar"
Securing Credentials
Credentials should never be stored in plain text in scripts. If you need to use credentials in a script, such as service account credentials you should:
- Store the credentials in a TS variable, with the
Do not display this value
box checked. This will prevent the variable value from being exposed in the TS logs. - Pass the TS variable to the script as a parameter, or simply access the protected variable directly within the script, as shown above.
- Never write/output the credentials to the screen/pipeline/a file.