Categories
PowerShell Tanium

PowerShell Deployment Automation Toolkit 0.5.1

Hello Again All,

It has been a while since I updated the toolkit so I wanted to make this a good one. 0.0.1 was a decent start but it was more of a proof-of-concept than anything else; I wanted to demonstrate what is possible with TanREST and the Tanium platform but I knew that my implementation was lacking despite it being the best that I could do at the time.

Update 0.5.1 is what I consider to be a beta-level release. There are a lot of improvements still to be made but I have successfully refactored the code to be more legible, reliable, and extensible. I have implemented class validations to deployment data objects derived from the jobs to reduce the likelihood that a malformed job will actually get pushed to the API. Each permutation of Single and Ongoing deployments has two sample catalog entries (Each with two subordinate rings) to assist in the construction of your own catalog entries. Rings within a job do not need to be of identical classes; each ring is validated independently of the others so one could conceivably have, say, a silent deployment to a test ring with subsequent rings to actual users featuring pre/post notifications.

Patch deployments are still on the way. Redesigning the tool to be extensible and implementing the class validations felt substantial enough to warrant an individual release; I will be exploring the topic of integrating Patch deployments into the tool soon.

PowerShell Deployment Automation Toolkit

  • Author: Brent Henderson
  • Release Date: 06/10/2021
  • Version: 0.5.1

Introduction

Toolkit Overview

The PowerShell Deployment Automation Toolkit provides a way to deliver automated deployments through the Tanium Endpoint Management platform.

Features

This script manages the import and deployment of Software Gallery packages for the Tanium Endpoint Management platform. The tool currently provides the following functionality:

  • Automated API session creation mechanism with manual fallback
  • Catalog-driven for ease of customization
  • Support for multiple environments with minimal administrative overhead
  • Automated Tanium Package Gallery package imports
  • Automated deployment creation to deployment rings designated in catalog items
  • PowerShell classes to validate deployment data structures prior to API submission
  • Support for Pre/Post Notification options with Single and Ongoing deployments
  • Independently configurable rings (Eg, one ring can be a silent, Single deployment whereas the next could be an Ongoing deployment with prompts
  • Patch Tuesday offset configuration for deployments
  • CMTrace/OneTrace-compatible logging

Dependencies

The TanREST PowerShell module is required and cannot currently be distributed by anyone other than Tanium. Please contact your Technical Account Manager to acquire and install the latest version of TanREST.

License

PowerShell Deployment Automation Framework – Provides a way to deliver automated deployments through the Tanium Endpoint Management platform.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Usage

powershell.exe -File '\\pathToFile\DeploymentAutomationToolkit.ps1'

powershell.exe -File '\\pathToFile\DeploymentAutomationToolkit.ps1' -Environment [[Alt],[Dev],[Prod],[QA]]

powershell.exe -File 'c:\pathToFile\DeploymentAutomationToolkit.ps1' -Environment 'Alt' -QuickTest $true -StartToday $true

$credentialObject = Get-Credential

powershell.exe -File 'c:\pathToFile\DeploymentAutomationToolkit.ps1' -Environment 'Alt' -QuickTest $true -StartToday $true -CredentialObject $credentialObject

Quick Start

  1. Configure reference file(s) for environment(s) under scriptRoot\core\config
  2. Encrypted credentials may be stored in scriptRoot\core\config as tanium__ENV__Cred.txt (Not Recommended or Required for Production; $credentialObject = Get-Credential can be leveraged instead prior to execution as shown above)
  3. Configure json catalog files under scriptRoot\core\catalog\repo (Examples of each potential configuration are provided)
  4. Promote configured json catalog items to scriptRoot\core\catalog (Only the catalog items at the root of this directory will be processed)
  5. Call script with desired environmental target

Example 1: The ConvertFrom-SecureString cmdlet converts a secure string into an encrypted standard string.

(Get-Credential).password | ConvertFrom-SecureString | Out-File "$scriptDirectory\core\config\tanium[[Alt],[Dev],[Prod],[QA]]Cred.txt"

Script Parameters

ParametersDescription
CredentialObject (Optional)Allows the user to establish a SecureString credential object prior to invocation of the tool. By default, the Deployment Automation Toolkit will attempt to build credentials from a saved SecureString object if this is not provided.
DecommOnCompletion (Optional)Designates whether or not jobs should be decommissioned once all rings are deployed; defaults to $true. If set to $false, jobs will remain in the root/jobqueue/ directory and no subsequent jobs for that software will proceed until the job is manually copied to the root/jobqueue/decommissioned/ directory.
Environment (Optional)Designates the operating environment for the script to execute upon. Jobs from multiple environments can coexist so back-to-back executions from multiple environments will function appropriately. The default value is ‘Alt’.
QuickTest (Optional)Designates whether or not an abbreviated run should be facilitated; defaults to $false as a precaution.
StartTodayDesignates whether or not the startDateOffsetInDays value in catalog items will offset relative to the runtime date or the next Patch Tuesday; defaults to $false.

JSON Catalog Keys | Tanium Package Deployments

Note: Any null values in the example files under /core/catalog/repo denote values that will be established at runtime by the toolkit itself. Users should not modify null values.

KeysDescription
allRingsDeployedIndicates whether or not all defined rings within the job have been deployed.
architectureArchitecture of the package to be deployed. Valid entries are [x64],[x86],[any].
contentAcquiredIndicates whether or not the content for the package has been cached.
currentVersionReflects current software version for a given package that is available.
currentSoftwarePackageEditIdThe current software package object version.
deployedObjectEditIdFunctionally identical to currentSoftwarePackageEditId (current is used in package metadata; deployedObjectEditId is used to create deployments).
frameworkCatalogNameThe name of the source catalog item that the job was created to address. Must be the exact name; see examples.
guidThe unique GUID assigned to the job at runtime.
holdReasonThe reason, if any, why a package was placed in a hold state.
jobFileLocationThe current location of the job file.
jobStatusThe current status of the job.
lastModifiedIndicates the last time the Toolkit modified a given job file.
packageCacheLoopAn integer value indicating how many loops the package cache logic should take. Each loop is 10 seconds so a value of 30 would allow for a maximum of 5 minutes before the job was placed in a hold state.
platformThe platform that the job is targeted toward. Valid values are [windows] or [macos].
previousSoftwarePackageIdThe previous package ID of the software that is being deployed by a given job. This property was previously named previousPackageID but amended to align more closely with Tanium object properties.
productNameThe product name of the software being deployed by a given job.
productVendorThe product vendor of the software being deployed by a given job.
ring#Deployment rings (ring1, ring2, etc.) are objects with their own subkeys that define the pertinent details of a deployment. The subkeys are detailed below.
softwarePackageIdThe current package ID of the package being deployed by a given job. This property was previously named packageId but amended to align with Tanium object properties.
sourceThe source property denotes the source from which the package content will be acquired; the only recognized value currently is deployGallery.
typeThe type key denotes what is being deployed by the job; the only recognized value currently is package.

JSON Catalog – Subkeys of ring# | Tanium Package Deployments

KeysDescription
classDenotes the class of the ring that is being deployed. Valid values are [OngoingPackageDeploymentSilent],[OngoingPackageWithPostAndPre],[OngoingPackageWithPostNoPre],[OngoingPackageWithPreNoPost],[SinglePackageSilent],[SinglePackageWithPostAndPre],[SinglePackageWithPostNoPre],[SinglePackageWithPreNoPost].
classValidatedDenotes whether or not the ring successfully passed the class validation of the deployment data.
deploymentLengthInDaysRing designation indicating the length of time that the deployment should run.
deploymentStartTimeThe 24-hour value of the intended start time. Example: 00:00 is the default value and representative of midnight.
deploymentEndTimeThe 24-hour value of the intended stop time. Example: 00:00 is the default value and representative of midnight. null is an acceptable value for Ongoing deployment classes.
downloadImmediatelyIndicates whether or not endpoints should begin downloading content as soon as the deployment is created. Consider the size of the audience you are targeting carefully.
deploymentIDThe deployment ID of the deployment created by the Toolkit.
deployedOnThe datetime value of the deployment created by the Toolkit.
eussAvailableBeforeStartIndicates whether or not users should be able to interact with the deployment prior to start time.
operationThe deployment operation that should be leveraged in the deployment. Default value is ‘update’.
overrideMaintenanceWindowsIndicates whether or not maintenance windows should be respected by the deployment. Default value is ‘true’.
postNotificationAn object describing the notification, if any, an end user will see after a deployment
preNotificationAn object describing the notification, if any, an end user will see before a deployment
startDateOffsetInDaysAn integer value denoting how much of an offset should be configured from the start time. For example, one would use the $StartToday switch and a startDateOffsetInDays offset of 0 to start a deployment for the same day.
restartIndicates whether or not the deployment should restart devices. Default value is [false].
targetTypeIndicates the target apparatus for a deployment. [computerGroup] is currently the only valid value.
targetCriteriaThe Computer Group to be targeted by a given deployment ring. Default value is [No Computers].
targetCriteriaIdThe associated ID of the targetCriteria object.
typeIndicates the type of deployment to be created. ‘single’ is the only valid value and indicates a deployment with defined beginning and end dates.
useTaniumClientTimeZoneIndicates whether or not the deployment should use the client local time. Default value is ‘true’.

JSON Catalog – Subkeys of [postNotification],[preNotification] | Tanium Package Deployments

KeysDescription
allowPostponeIf true, the end user will be notified before the deployment begins
body(Required if notifyUser is true) The body text of the end user notification
countdownToDeadlineInMinutes(Required if notifyUser is true) The time in minutes before the end of the postponement period when an end user will be shown a countdown to the forced deployment
notifyUserIf true, the end user will be notified after the deployment completes
postponeDurationInMinutes(Required if allowPostone is true) The amount of time in minutes the deployment can be postponed
title(Required if notifyUser is true) The title of the end user notification
userPostponementPeriodInMinutesOne(Required if allowPostpone is true) Postponement period in minutes that will be available to the end user
userPostponementPeriodInMinutesTwo(Required if allowPostpone is true) Postponement period in minutes that will be available to the end user
userPostponementPeriodInMinutesThree(Required if allowPostpone is true) Postponement period in minutes that will be available to the end user

Reference

Directory Overview

root/
├─ core/
│  ├─ catalog/
│  │  ├─ repo/
│  │  │  ├─	ex-OngoingPackageDeploymentSilent/
│  │  │  │	├─ googlellc-chrome-x64.json 
│  │  │  │	├─ igorpavlov-7-zip-x64.json
│  │  │  ├─	ex-OngoingPackageWithPostAndPre/
│  │  │  │	├─ googlellc-chrome-x64.json 
│  │  │  │	├─ igorpavlov-7-zip-x64.json
│  │  │  ├─	ex-OngoingPackageWithPostNoPre/
│  │  │  │	├─ googlellc-chrome-x64.json 
│  │  │  │	├─ igorpavlov-7-zip-x64.json
│  │  │  ├─	ex-OngoingPackageWithPreNoPost/
│  │  │  │	├─ googlellc-chrome-x64.json 
│  │  │  │	├─ igorpavlov-7-zip-x64.json
│  │  │  ├─	ex-SinglePackageSilent/
│  │  │  │	├─ googlellc-chrome-x64.json 
│  │  │  │	├─ igorpavlov-7-zip-x64.json
│  │  │  ├─	ex-SinglePackageWithPostAndPre/
│  │  │  │	├─ googlellc-chrome-x64.json 
│  │  │  │	├─ igorpavlov-7-zip-x64.json
│  │  │  ├─	ex-SinglePackageWithPostNoPre/
│  │  │  │	├─ googlellc-chrome-x64.json 
│  │  │  │	├─ igorpavlov-7-zip-x64.json
│  │  │  ├─	ex-SinglePackageWithPreNoPost/
│  │  │  	├─ googlellc-chrome-x64.json 
│  │  │  	├─ igorpavlov-7-zip-x64.json
│  ├─ config/
│  │  │  ├─ exampleConfig.json
│  ├─ functions/
│  │  ├─ Confirm-DeploymentData.ps1
│  │  ├─ Get-LatestTaniumDeployPackage.ps1
│  │  ├─ Get-PatchTuesday.ps1
│  │  ├─ Get-StartAndEndDates.ps1
│  │  ├─ Get-TaniumDeployPackageCacheStatus.ps1
│  │  ├─ New-CredentialObject.ps1
│  │  ├─ New-Session.ps1
│  │  ├─ Send-HTMLEmail.ps1
│  │  ├─ Set-JSONProperty.ps1
│  │  ├─ Submit-TaniumDeployPackageDeployment
│  │  ├─ Write-Log.ps1
├─ jobqueue/
│  ├─ decommissioned/
│  ├─ hold/
├─ logs/
│  ├─ deploymentautomation.log
│  ├─ deploymentautomation.lo
│  ├─ jobfailures.csv
├─ .gitignore
├─ readme.md


Directory Structure

FolderDescription
coreContains the Toolkit core dependencies.
catalogContains JSON-based catalog entries for deployment.
repoContains JSON-based catalog entries that have not been deployed.
configContains JSON-based reference file for environmental targeting configurations.
functionsContains the Toolkit function dependencies.
jobqueueContains JSON-based jobs.
decommissionedContains completed JSON-based jobs.
holdContains JSON-based jobs that encountered an issue during execution.

Included Files

FileDescription
Confirm-DeploymentData.ps1Constructs a deployment data object from the job object and performs a class validation.
DeploymentAutomationToolkit.ps1The controller script that drives the toolkit.
exampleConfig.jsonReference item to be configured for targeting different environments. Rename to config.json once configured appropriately.
Get-LatestTaniumDeployPackage.ps1Identifies the highest version of a given piece of software in the Gallery and the highest two versions of the same software that have already been imported into Tanium Deploy.
Get-PatchTuesday.ps1Function that determines the date of Patch Tuesday for a given month/year.
Get-StartAndEndDates.ps1Calculates Start and End dates for a given deployment.
Get-TaniumDeployPackageCacheStatus.ps1
googlellc-chrome-x64.jsonExample catalog item for the Google LLC Chrome product preconfigured to the class of the folder within which it resides.
igorpavlov-7-zip-x64.jsonExample catalog item for the Igor Pavlov 7-zip product preconfigured to the class of the folder within which it resides.
New-CredentialObject.ps1Function that creates a credential object from locally stored credentials.
New-Session.ps1Function that creates a session with the desired Tanium environment.
Set-JSONProperty.ps1Function that updates JSON files.
Write-Log.ps1Function that creates CMTrace/OneTrace-formatted logs.

Screenshots

CMTrace/OneTrace-compatible logging
Distinct deployment identifiers with GUID reference to associated jobs

Change History

0.5.1

* Integrated class-based validation for deployment data prior to making commits via TanREST
* Added support for Pre/Post Notification options for both single and ongoing deployments
* Unified configuration settings into a single configuration file 
* Introduced consideration for multi-platform packages in controller script and mandatory catalog item properties.
* Split off code from controller script into subfunctions to improve readability and assist debugging
* Reduced unnecessary logic trees that would always evaluate to $true due to location
* Miscellaneous readability improvements to controller and subfunctions
* Aligned most runtime variable object properties to align with Tanium object properties where possible. Some still vary for sake of clarity
* Reduced utilization of one-off variables for clarity; integrated most of these details in the jobs themselves for posterity/troubleshooting

0.0.1

* Implement automatic config-driven Tanium session creation
* Implement basic job processing engine
* Implement automatic package import
* Implement verbose, CMtrace-compatible logging
* Establish predictable tooling structure for relational references to dependencies

Disclaimer: Any code made available on this site is free to use at your own discretion but it is provided without any explicit or implied guarantees of support, reliability, or functionality. I accept no responsibility in the event that the code, in its original form or any derivative versions thereafter, malfunctions or causes problems . Anything from this site that you decide to work with should be tested thoroughly in development environments in collaboration with your Technical Account Manager (TAM) until such time that you, the responsible party, decides that you are satisfied with its outcomes.