2015-07-07 21:34:57 -06:00
|
|
|
<#
|
|
|
|
.SYNOPSIS
|
2022-05-18 09:49:12 -06:00
|
|
|
A simple Powershell script to download and install a Salt minion on Windows.
|
2016-04-13 12:46:36 -04:00
|
|
|
|
2015-07-07 21:34:57 -06:00
|
|
|
.DESCRIPTION
|
2022-05-18 09:49:12 -06:00
|
|
|
The script will download the official Salt package from SaltProject. It will
|
2016-06-17 16:03:01 -06:00
|
|
|
install a specific package version and accept parameters for the master and
|
2022-05-18 09:49:12 -06:00
|
|
|
minion ids. Finally, it can stop and set the Windows service to "manual" for
|
2016-06-17 16:03:01 -06:00
|
|
|
local testing.
|
2016-04-13 12:46:36 -04:00
|
|
|
|
2015-07-07 21:34:57 -06:00
|
|
|
.EXAMPLE
|
2016-06-17 16:03:01 -06:00
|
|
|
./bootstrap-salt.ps1
|
|
|
|
Runs without any parameters. Uses all the default values/settings.
|
2016-04-13 12:46:36 -04:00
|
|
|
|
2015-07-07 21:34:57 -06:00
|
|
|
.EXAMPLE
|
2017-08-08 10:22:20 -04:00
|
|
|
./bootstrap-salt.ps1 -version 2017.7.0
|
2016-06-17 16:03:01 -06:00
|
|
|
Specifies a particular version of the installer.
|
2016-04-13 12:46:36 -04:00
|
|
|
|
2017-08-08 10:22:20 -04:00
|
|
|
.EXAMPLE
|
|
|
|
./bootstrap-salt.ps1 -pythonVersion 3
|
2022-05-18 09:49:12 -06:00
|
|
|
Specifies the Python version of the installer. Can be "2" or "3". Defaults
|
|
|
|
to "2". Python 3 installers are only available for Salt 2017.7.0 and newer.
|
|
|
|
Starting with Python 3002 only Python 3 installers are available.
|
2017-08-08 10:22:20 -04:00
|
|
|
|
2015-07-07 21:34:57 -06:00
|
|
|
.EXAMPLE
|
2016-06-17 16:03:01 -06:00
|
|
|
./bootstrap-salt.ps1 -runservice false
|
|
|
|
Specifies the salt-minion service to stop and be set to manual. Useful for
|
|
|
|
testing locally from the command line with the --local switch
|
2016-04-13 12:46:36 -04:00
|
|
|
|
2015-07-07 21:34:57 -06:00
|
|
|
.EXAMPLE
|
2016-06-17 16:03:01 -06:00
|
|
|
./bootstrap-salt.ps1 -minion minion-box -master master-box
|
|
|
|
Specifies the minion and master ids in the minion config. Defaults to the
|
|
|
|
installer values of host name for the minion id and "salt" for the master.
|
2016-04-13 12:46:36 -04:00
|
|
|
|
2015-07-07 21:34:57 -06:00
|
|
|
.EXAMPLE
|
2017-08-08 10:22:20 -04:00
|
|
|
./bootstrap-salt.ps1 -minion minion-box -master master-box -version 2017.7.0 -runservice false
|
2016-06-17 16:03:01 -06:00
|
|
|
Specifies all the optional parameters in no particular order.
|
2016-04-13 12:46:36 -04:00
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
.PARAMETER version
|
2023-04-20 14:31:28 -06:00
|
|
|
The version of the Salt minion to install. Default is "latest" which will
|
|
|
|
install the latest version of Salt minion available.
|
2015-07-07 21:34:57 -06:00
|
|
|
|
2017-08-08 10:22:20 -04:00
|
|
|
.PARAMETER pythonVersion
|
|
|
|
The version of Python the installer should use. Specify either "2" or "3".
|
|
|
|
Beginning with Salt 2017.7.0, Salt will run on either Python 2 or Python 3.
|
|
|
|
The default is Python 2 if not specified. This parameter only works for Salt
|
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
.PARAMETER runservice
|
|
|
|
Boolean flag to start or stop the minion service. True will start the minion
|
|
|
|
service. False will stop the minion service and set it to "manual". The
|
|
|
|
installer starts it by default.
|
2015-07-07 21:34:57 -06:00
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
.PARAMETER minion
|
|
|
|
Name of the minion being installed on this host. Installer defaults to the
|
|
|
|
host name.
|
2015-07-07 21:34:57 -06:00
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
.PARAMETER master
|
|
|
|
Name or IP of the master server. Installer defaults to "salt".
|
|
|
|
|
|
|
|
.PARAMETER repourl
|
2021-01-21 22:44:46 +00:00
|
|
|
URL to the windows packages. Default is "https://repo.saltproject.io/windows"
|
2015-07-07 21:34:57 -06:00
|
|
|
|
|
|
|
.NOTES
|
2016-06-17 16:03:01 -06:00
|
|
|
All of the parameters are optional. The default should be the latest
|
|
|
|
version. The architecture is dynamically determined by the script.
|
2015-07-07 21:34:57 -06:00
|
|
|
|
|
|
|
.LINK
|
2023-02-02 15:17:33 +00:00
|
|
|
Salt Bootstrap GitHub Project (script home) - https://github.com/saltstack/salt-bootstrap
|
|
|
|
Original Vagrant Provisioner Project - https://github.com/saltstack/salty-vagrant
|
2016-06-17 16:03:01 -06:00
|
|
|
Vagrant Project (utilizes this script) - https://github.com/mitchellh/vagrant
|
2023-02-02 15:17:33 +00:00
|
|
|
Salt Download Location - https://repo.saltproject.io/windows/
|
2015-07-07 21:34:57 -06:00
|
|
|
#>
|
2016-05-25 16:02:03 -07:00
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
2022-05-18 09:49:12 -06:00
|
|
|
# Bind Parameters
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
2015-07-07 21:34:57 -06:00
|
|
|
[CmdletBinding()]
|
2022-05-18 09:49:12 -06:00
|
|
|
param(
|
|
|
|
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
2016-06-17 16:03:01 -06:00
|
|
|
# Doesn't support versions prior to "YYYY.M.R-B"
|
2020-02-13 17:07:17 -07:00
|
|
|
# Supports new version and latest
|
|
|
|
# Option 1 means case insensitive
|
|
|
|
[ValidatePattern('^(\d{4}(\.\d{1,2}){0,2}(\-\d{1})?)|(latest)$', Options=1)]
|
2023-04-20 14:31:28 -06:00
|
|
|
[Alias("v")]
|
|
|
|
[String]$Version = "latest",
|
2016-06-17 16:03:01 -06:00
|
|
|
|
2022-05-18 09:49:12 -06:00
|
|
|
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
2023-04-20 14:31:28 -06:00
|
|
|
# Python 3 support was added in 2017. Python 2 support was dropped in
|
|
|
|
# version 3001. This parameter is ignored for all versions before 2017 and
|
|
|
|
# after 3000.
|
2017-08-08 10:22:20 -04:00
|
|
|
[ValidateSet("2","3")]
|
2023-04-20 14:31:28 -06:00
|
|
|
[Alias("p")]
|
|
|
|
[String]$PythonVersion = "3",
|
2017-08-08 10:22:20 -04:00
|
|
|
|
2022-05-18 09:49:12 -06:00
|
|
|
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
2016-06-17 16:03:01 -06:00
|
|
|
[ValidateSet("true","false")]
|
2023-04-20 14:31:28 -06:00
|
|
|
[Alias("s")]
|
|
|
|
[String]$RunService = "true",
|
2016-06-17 16:03:01 -06:00
|
|
|
|
2022-05-18 09:49:12 -06:00
|
|
|
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
2023-04-20 14:31:28 -06:00
|
|
|
[Alias("m")]
|
|
|
|
[String]$Minion = "not-specified",
|
2016-06-17 16:03:01 -06:00
|
|
|
|
2022-05-18 09:49:12 -06:00
|
|
|
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
2023-04-20 14:31:28 -06:00
|
|
|
[Alias("a")]
|
|
|
|
[String]$Master = "not-specified",
|
2016-06-17 16:03:01 -06:00
|
|
|
|
2022-05-18 09:49:12 -06:00
|
|
|
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
2023-04-20 14:31:28 -06:00
|
|
|
[Alias("r")]
|
|
|
|
[String]$RepoUrl = "https://repo.saltproject.io/salt/py3/windows",
|
2021-01-19 20:15:09 +00:00
|
|
|
|
2022-05-18 09:49:12 -06:00
|
|
|
[Parameter(Mandatory=$false, ValueFromPipeline=$True)]
|
2023-04-20 14:31:28 -06:00
|
|
|
[Alias("c")]
|
|
|
|
[Switch]$ConfigureOnly
|
2015-07-07 21:34:57 -06:00
|
|
|
)
|
|
|
|
|
2023-04-20 14:31:28 -06:00
|
|
|
|
|
|
|
#===============================================================================
|
|
|
|
# Script Preferences
|
|
|
|
#===============================================================================
|
2020-02-13 17:07:17 -07:00
|
|
|
# Powershell supports only TLS 1.0 by default. Add support for TLS 1.2
|
|
|
|
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Tls12'
|
2023-04-20 14:31:28 -06:00
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$ProgressPreference = "SilentlyContinue"
|
2019-04-12 13:56:06 -06:00
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
2016-05-25 16:02:03 -07:00
|
|
|
# Script Functions
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
2016-05-25 16:02:03 -07:00
|
|
|
function Get-IsAdministrator
|
|
|
|
{
|
|
|
|
$Identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
|
|
|
|
$Principal = New-Object System.Security.Principal.WindowsPrincipal($Identity)
|
|
|
|
$Principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
|
|
}
|
|
|
|
|
|
|
|
function Get-IsUacEnabled
|
|
|
|
{
|
|
|
|
(Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System).EnableLua -ne 0
|
|
|
|
}
|
|
|
|
|
2023-04-20 14:31:28 -06:00
|
|
|
function Get-MajorVersion {
|
|
|
|
# Parses a version string and returns the major version
|
|
|
|
#
|
|
|
|
# Args:
|
|
|
|
# Version (string): The Version to parse
|
|
|
|
[CmdletBinding()]
|
|
|
|
param(
|
|
|
|
[Parameter(Mandatory=$true, Position=0)]
|
|
|
|
[String] $Version
|
|
|
|
)
|
|
|
|
return ( $Version -split "\." )[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
function Convert-PSObjectToHashtable {
|
|
|
|
param (
|
|
|
|
[Parameter(ValueFromPipeline)]
|
|
|
|
$InputObject
|
|
|
|
)
|
|
|
|
if ($null -eq $InputObject) { return $null }
|
|
|
|
|
|
|
|
$is_enum = $InputObject -is [System.Collections.IEnumerable]
|
|
|
|
$not_string = $InputObject -isnot [string]
|
|
|
|
if ($is_enum -and $not_string) {
|
|
|
|
$collection = @(
|
|
|
|
foreach ($object in $InputObject) {
|
|
|
|
Convert-PSObjectToHashtable $object
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
Write-Host -NoEnumerate $collection
|
|
|
|
} elseif ($InputObject -is [PSObject]) {
|
|
|
|
$hash = @{}
|
|
|
|
|
|
|
|
foreach ($property in $InputObject.PSObject.Properties) {
|
|
|
|
$hash[$property.Name] = Convert-PSObjectToHashtable $property.Value
|
|
|
|
}
|
|
|
|
|
|
|
|
$hash
|
|
|
|
} else {
|
|
|
|
$InputObject
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function Get-FileHash {
|
|
|
|
# Get-FileHash is a built-in cmdlet in powershell 5+ but we need to support
|
|
|
|
# powershell 3. This will overwrite the powershell 5 commandlet only for
|
|
|
|
# this script. But it will provide the missing cmdlet for powershell 3
|
|
|
|
[CmdletBinding()]
|
|
|
|
param(
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
|
|
[String] $Path,
|
|
|
|
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
|
|
[ValidateSet(
|
|
|
|
"SHA1",
|
|
|
|
"SHA256",
|
|
|
|
"SHA384",
|
|
|
|
"SHA512",
|
|
|
|
# https://serverfault.com/questions/820300/
|
|
|
|
# why-isnt-mactripledes-algorithm-output-in-powershell-stable
|
|
|
|
"MACTripleDES", # don't use
|
|
|
|
"MD5",
|
|
|
|
"RIPEMD160",
|
|
|
|
IgnoreCase=$true)]
|
|
|
|
[String] $Algorithm = "SHA256"
|
|
|
|
)
|
|
|
|
|
|
|
|
if ( !(Test-Path $Path) ) {
|
|
|
|
Write-Verbose "Invalid path for hashing: $Path"
|
|
|
|
return @{}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (Get-Item -Path $Path) -isnot [System.IO.FileInfo]) {
|
|
|
|
Write-Verbose "Not a file for hashing: $Path"
|
|
|
|
return @{}
|
|
|
|
}
|
|
|
|
|
|
|
|
$Path = Resolve-Path -Path $Path
|
|
|
|
|
|
|
|
Switch ($Algorithm) {
|
|
|
|
SHA1 {
|
|
|
|
$hasher = [System.Security.Cryptography.SHA1CryptoServiceProvider]::Create()
|
|
|
|
}
|
|
|
|
SHA256 {
|
|
|
|
$hasher = [System.Security.Cryptography.SHA256]::Create()
|
|
|
|
}
|
|
|
|
SHA384 {
|
|
|
|
$hasher = [System.Security.Cryptography.SHA384]::Create()
|
|
|
|
}
|
|
|
|
SHA512 {
|
|
|
|
$hasher = [System.Security.Cryptography.SHA512]::Create()
|
|
|
|
}
|
|
|
|
MACTripleDES {
|
|
|
|
$hasher = [System.Security.Cryptography.MACTripleDES]::Create()
|
|
|
|
}
|
|
|
|
MD5 {
|
|
|
|
$hasher = [System.Security.Cryptography.MD5]::Create()
|
|
|
|
}
|
|
|
|
RIPEMD160 {
|
|
|
|
$hasher = [System.Security.Cryptography.RIPEMD160]::Create()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Write-Verbose "Hashing using $Algorithm algorithm"
|
|
|
|
try {
|
|
|
|
$data = [System.IO.File]::OpenRead($Path)
|
|
|
|
$hash = $hasher.ComputeHash($data)
|
|
|
|
$hash = [System.BitConverter]::ToString($hash) -replace "-",""
|
|
|
|
return @{
|
|
|
|
Path = $Path;
|
|
|
|
Algorithm = $Algorithm.ToUpper();
|
|
|
|
Hash = $hash
|
|
|
|
}
|
|
|
|
} catch {
|
|
|
|
Write-Verbose "Error hashing: $Path"
|
|
|
|
return @{}
|
|
|
|
} finally {
|
|
|
|
if ($null -ne $data) {
|
|
|
|
$data.Close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
2016-05-25 16:02:03 -07:00
|
|
|
# Check for Elevated Privileges
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
2022-05-18 09:49:12 -06:00
|
|
|
if (!(Get-IsAdministrator)) {
|
|
|
|
if (Get-IsUacEnabled) {
|
2016-05-25 16:02:03 -07:00
|
|
|
# We are not running "as Administrator" - so relaunch as administrator
|
|
|
|
# Create a new process object that starts PowerShell
|
|
|
|
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
|
|
|
|
|
|
|
|
# Specify the current script path and name as a parameter`
|
|
|
|
$parameters = ""
|
2021-11-16 13:34:40 -05:00
|
|
|
foreach ($boundParam in $PSBoundParameters.GetEnumerator())
|
|
|
|
{
|
|
|
|
$parameters = "$parameters -{0} '{1}'" -f $boundParam.Key, $boundParam.Value
|
|
|
|
}
|
2016-05-25 16:02:03 -07:00
|
|
|
$newProcess.Arguments = $myInvocation.MyCommand.Definition, $parameters
|
2021-11-16 13:52:38 -05:00
|
|
|
|
2016-05-25 16:02:03 -07:00
|
|
|
# Specify the current working directory
|
|
|
|
$newProcess.WorkingDirectory = "$script_path"
|
|
|
|
|
|
|
|
# Indicate that the process should be elevated
|
|
|
|
$newProcess.Verb = "runas";
|
|
|
|
|
|
|
|
# Start the new process
|
|
|
|
[System.Diagnostics.Process]::Start($newProcess);
|
|
|
|
|
|
|
|
# Exit from the current, unelevated, process
|
2022-05-18 09:49:12 -06:00
|
|
|
exit
|
2016-06-17 16:03:01 -06:00
|
|
|
}
|
2022-05-18 09:49:12 -06:00
|
|
|
else {
|
|
|
|
throw "You must be administrator to run this script"
|
2016-05-25 16:02:03 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-20 14:31:28 -06:00
|
|
|
#===============================================================================
|
|
|
|
# Change RepoUrl for older versions
|
|
|
|
#===============================================================================
|
|
|
|
$defaultUrl = "https://repo.saltproject.io/salt/py3/windows"
|
|
|
|
$oldRepoUrl = "https://repo.saltproject.io/windows"
|
|
|
|
$majorVersion = Get-MajorVersion -Version $Version
|
|
|
|
$customUrl = $true
|
|
|
|
if ( $Version.ToLower() -ne "latest" ) {
|
|
|
|
# A specific version has been passed
|
|
|
|
# We only want to modify the URL if a custom URL was not passed
|
|
|
|
$uri = [Uri]($RepoUrl)
|
|
|
|
if ( $uri.AbsoluteUri -eq $defaultUrl ) {
|
|
|
|
# No customURL passed, let's check for a pre 3006 version
|
|
|
|
$customUrl = $false
|
|
|
|
if ( $majorVersion -lt "3006" ) {
|
|
|
|
# This is an older version, use the old URL
|
|
|
|
$RepoUrl = $oldRepoUrl
|
|
|
|
} else {
|
|
|
|
# This is a new URL, and a version was passed, let's look in minor
|
|
|
|
if ( $Version.ToLower() -ne $majorVersion.ToLower() ) {
|
|
|
|
$RepoUrl = "$RepoUrl/minor"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( $RepoUrl -eq $defaultUrl ) {
|
|
|
|
$customUrl = $false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
|
|
|
# Verify Parameters
|
|
|
|
#===============================================================================
|
2015-07-07 21:34:57 -06:00
|
|
|
Write-Verbose "Parameters passed in:"
|
2023-04-20 14:31:28 -06:00
|
|
|
Write-Verbose "version: $Version"
|
|
|
|
Write-Verbose "runservice: $RunService"
|
|
|
|
Write-Verbose "master: $Master"
|
|
|
|
Write-Verbose "minion: $Minion"
|
|
|
|
Write-Verbose "repourl: $RepoUrl"
|
2015-07-07 21:34:57 -06:00
|
|
|
|
2023-04-20 14:31:28 -06:00
|
|
|
if ($RunService.ToLower() -eq "true") {
|
2016-06-17 16:03:01 -06:00
|
|
|
Write-Verbose "Windows service will be set to run"
|
2023-04-20 14:31:28 -06:00
|
|
|
[bool]$RunService = $True
|
|
|
|
} elseif ($RunService.ToLower() -eq "false") {
|
2016-06-17 16:03:01 -06:00
|
|
|
Write-Verbose "Windows service will be stopped and set to manual"
|
2023-04-20 14:31:28 -06:00
|
|
|
[bool]$RunService = $False
|
|
|
|
} else {
|
2016-06-17 16:03:01 -06:00
|
|
|
# Param passed in wasn't clear so defaulting to true.
|
|
|
|
Write-Verbose "Windows service defaulting to run automatically"
|
2023-04-20 14:31:28 -06:00
|
|
|
[bool]$RunService = $True
|
2015-07-07 21:34:57 -06:00
|
|
|
}
|
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
|
|
|
# Ensure Directories are present, copy Vagrant Configs if found
|
|
|
|
#===============================================================================
|
2021-01-19 20:15:09 +00:00
|
|
|
|
|
|
|
$ConfiguredAnything = $False
|
|
|
|
|
2023-07-25 12:10:53 -06:00
|
|
|
# Detect older version of Salt to determing default RootDir
|
|
|
|
if ($majorVersion -lt 3004) {
|
|
|
|
$RootDir = "$env:SystemDrive`:\salt"
|
|
|
|
} else {
|
|
|
|
$RootDir = "$env:ProgramData\Salt Project\Salt"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Check for existing installation where RootDir is stored in the registry
|
2022-01-18 13:23:23 +00:00
|
|
|
$SaltRegKey = "HKLM:\SOFTWARE\Salt Project\Salt"
|
2022-05-18 09:49:12 -06:00
|
|
|
if (Test-Path -Path $SaltRegKey) {
|
|
|
|
if ($null -ne (Get-ItemProperty $SaltRegKey).root_dir) {
|
|
|
|
$RootDir = (Get-ItemProperty $SaltRegKey).root_dir
|
|
|
|
}
|
2022-01-18 13:23:23 +00:00
|
|
|
}
|
2022-05-18 09:49:12 -06:00
|
|
|
|
2022-01-18 13:23:23 +00:00
|
|
|
$ConfDir = "$RootDir\conf"
|
|
|
|
$PkiDir = "$ConfDir\pki\minion"
|
2022-05-18 09:49:12 -06:00
|
|
|
Write-Verbose "ConfDir: $ConfDir"
|
2022-01-18 13:23:23 +00:00
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
# Create C:\tmp\
|
2016-05-24 13:37:44 -06:00
|
|
|
New-Item C:\tmp\ -ItemType directory -Force | Out-Null
|
2015-07-07 21:34:57 -06:00
|
|
|
|
2022-05-18 09:49:12 -06:00
|
|
|
#===============================================================================
|
|
|
|
# Copy Vagrant Files to their proper location.
|
|
|
|
#===============================================================================
|
|
|
|
|
|
|
|
# Vagrant files will be placed in C:\tmp
|
2016-06-17 16:03:01 -06:00
|
|
|
# Check if minion keys have been uploaded, copy to correct location
|
2022-05-18 09:49:12 -06:00
|
|
|
if (Test-Path C:\tmp\minion.pem) {
|
2022-01-18 13:23:23 +00:00
|
|
|
New-Item $PkiDir -ItemType Directory -Force | Out-Null
|
|
|
|
Copy-Item -Path C:\tmp\minion.pem -Destination $PkiDir -Force | Out-Null
|
|
|
|
Copy-Item -Path C:\tmp\minion.pub -Destination $PkiDir -Force | Out-Null
|
2021-01-19 20:15:09 +00:00
|
|
|
$ConfiguredAnything = $True
|
2015-07-07 21:34:57 -06:00
|
|
|
}
|
|
|
|
|
2016-05-24 13:37:44 -06:00
|
|
|
# Check if minion config has been uploaded
|
|
|
|
# This should be done before the installer is run so that it can be updated with
|
|
|
|
# id: and master: settings when the installer runs
|
2022-05-18 09:49:12 -06:00
|
|
|
if (Test-Path C:\tmp\minion) {
|
2022-01-18 13:23:23 +00:00
|
|
|
New-Item $ConfDir -ItemType Directory -Force | Out-Null
|
|
|
|
Copy-Item -Path C:\tmp\minion -Destination $ConfDir -Force | Out-Null
|
2021-01-19 20:15:09 +00:00
|
|
|
$ConfiguredAnything = $True
|
|
|
|
}
|
|
|
|
|
2021-01-04 16:33:22 +00:00
|
|
|
# Check if grains config has been uploaded
|
2022-05-18 09:49:12 -06:00
|
|
|
if (Test-Path C:\tmp\grains) {
|
2022-01-18 13:23:23 +00:00
|
|
|
New-Item $ConfDir -ItemType Directory -Force | Out-Null
|
|
|
|
Copy-Item -Path C:\tmp\grains -Destination $ConfDir -Force | Out-Null
|
2021-01-04 16:33:22 +00:00
|
|
|
$ConfiguredAnything = $True
|
|
|
|
}
|
|
|
|
|
2023-04-20 14:31:28 -06:00
|
|
|
if ( $ConfigureOnly ) {
|
|
|
|
if ( !$ConfiguredAnything ) {
|
|
|
|
Write-Host "No configuration or keys were copied over." -ForegroundColor yes
|
|
|
|
Write-Host "No configuration was done!" -ForegroundColor Yellow
|
|
|
|
} else {
|
|
|
|
Write-Host "Salt minion successfully configured" -ForegroundColor Green
|
|
|
|
}
|
|
|
|
# If we're only configuring, we want to end here
|
2021-01-19 20:15:09 +00:00
|
|
|
exit 0
|
2016-05-24 13:37:44 -06:00
|
|
|
}
|
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
2015-07-07 21:34:57 -06:00
|
|
|
# Detect architecture
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
2022-05-18 09:49:12 -06:00
|
|
|
if ([IntPtr]::Size -eq 4) {
|
2016-06-17 16:03:01 -06:00
|
|
|
$arch = "x86"
|
2022-05-18 09:49:12 -06:00
|
|
|
} else {
|
2016-06-17 16:03:01 -06:00
|
|
|
$arch = "AMD64"
|
2015-07-07 21:34:57 -06:00
|
|
|
}
|
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
2023-04-20 14:31:28 -06:00
|
|
|
# Get file name to download
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
2023-04-20 14:31:28 -06:00
|
|
|
$saltFileName = ""
|
|
|
|
$saltVersion = ""
|
|
|
|
$saltSha512= ""
|
|
|
|
$saltFileUrl = ""
|
|
|
|
if ( ($customUrl) -or ($majorVersion -lt 3006) ) {
|
|
|
|
$saltFileName = "Salt-Minion-$Version-Py3-$arch-Setup.exe"
|
|
|
|
$saltVersion = $Version
|
|
|
|
$saltFileUrl = "$RepoUrl/$saltFileName"
|
2019-11-25 13:28:52 -07:00
|
|
|
} else {
|
2023-04-20 14:31:28 -06:00
|
|
|
if ( $majorVersion -ge 3006 ) {
|
|
|
|
$enc = [System.Text.Encoding]::UTF8
|
|
|
|
try {
|
|
|
|
$response = Invoke-WebRequest -Uri "$RepoUrl/repo.json" -UseBasicParsing
|
|
|
|
if ($response.Content.GetType().Name -eq "Byte[]") {
|
|
|
|
$psobj = $enc.GetString($response.Content) | ConvertFrom-Json
|
|
|
|
} else {
|
|
|
|
$psobj = $response.Content | ConvertFrom-Json
|
|
|
|
}
|
|
|
|
$hash = Convert-PSObjectToHashtable $psobj
|
|
|
|
} catch {
|
|
|
|
Write-Verbose "repo.json not found at: $RepoUrl"
|
|
|
|
$hash = @{}
|
|
|
|
}
|
|
|
|
|
|
|
|
$searchVersion = $Version.ToLower()
|
|
|
|
if ( $hash.Contains($searchVersion)) {
|
|
|
|
foreach ($item in $hash.($searchVersion).Keys) {
|
|
|
|
if ( $item.EndsWith(".exe") ) {
|
|
|
|
if ( $item.Contains($arch) ) {
|
|
|
|
$saltFileName = $hash.($searchVersion).($item).name
|
|
|
|
$saltVersion = $hash.($searchVersion).($item).version
|
|
|
|
$saltSha512 = $hash.($searchVersion).($item).SHA512
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( $saltFileName -and $saltVersion -and $saltSha512 ) {
|
|
|
|
if ( $RepoUrl.Contains("minor") ) {
|
|
|
|
$saltFileUrl = @($RepoUrl, $saltVersion, $saltFileName) -join "/"
|
|
|
|
} else {
|
|
|
|
$saltFileUrl = @($RepoUrl, "minor", $saltVersion, $saltFileName) -join "/"
|
|
|
|
}
|
2019-11-25 13:28:52 -07:00
|
|
|
}
|
2017-08-08 10:22:20 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-20 14:31:28 -06:00
|
|
|
#===============================================================================
|
|
|
|
# Download minion setup file
|
|
|
|
#===============================================================================
|
|
|
|
Write-Host "===============================================================================" -ForegroundColor Yellow
|
|
|
|
Write-Host " Bootstrapping Salt Minion" -ForegroundColor Green
|
|
|
|
Write-Host " - version: $Version"
|
|
|
|
Write-Host " - file name: $saltFileName"
|
|
|
|
Write-Host " - file url: $saltFileUrl"
|
|
|
|
Write-Host "-------------------------------------------------------------------------------" -ForegroundColor Yellow
|
|
|
|
Write-Host "Downloading Installer: " -NoNewline
|
|
|
|
$webclient = New-Object System.Net.WebClient
|
|
|
|
$localFile = "C:\Windows\Temp\$saltFileName"
|
|
|
|
$webclient.DownloadFile($saltFileUrl, $localFile)
|
|
|
|
|
|
|
|
if ( Test-Path -Path $localFile ) {
|
|
|
|
Write-Host "Success" -ForegroundColor Green
|
|
|
|
} else {
|
|
|
|
Write-Host "Failed" -ForegroundColor Red
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $saltSha512 ) {
|
|
|
|
$localSha512 = (Get-FileHash -Path $localFile -Algorithm SHA512).Hash
|
|
|
|
Write-Host "Comparing Hash: " -NoNewline
|
|
|
|
if ( $localSha512 -eq $saltSha512 ) {
|
|
|
|
Write-Host "Success" -ForegroundColor Green
|
|
|
|
} else {
|
|
|
|
Write-Host "Failed" -ForegroundColor Red
|
|
|
|
exit 1
|
2021-01-19 20:15:09 +00:00
|
|
|
}
|
2023-04-20 14:31:28 -06:00
|
|
|
}
|
2015-07-07 21:34:57 -06:00
|
|
|
|
2023-04-20 14:31:28 -06:00
|
|
|
#===============================================================================
|
|
|
|
# Set the parameters for the installer
|
|
|
|
#===============================================================================
|
|
|
|
# Unless specified, use the installer defaults
|
|
|
|
# - id: <hostname>
|
|
|
|
# - master: salt
|
|
|
|
# - Start the service
|
|
|
|
$parameters = ""
|
|
|
|
if($Minion -ne "not-specified") {$parameters = "/minion-name=$Minion"}
|
|
|
|
if($Master -ne "not-specified") {$parameters = "$parameters /master=$Master"}
|
|
|
|
if($RunService -eq $false) {$parameters = "$parameters /start-service=0"}
|
|
|
|
|
|
|
|
#===============================================================================
|
|
|
|
# Install minion silently
|
|
|
|
#===============================================================================
|
|
|
|
#Wait for process to exit before continuing.
|
|
|
|
Write-Host "Installing Salt Minion: " -NoNewline
|
|
|
|
Start-Process $localFile -ArgumentList "/S $parameters" -Wait -NoNewWindow -PassThru | Out-Null
|
|
|
|
|
|
|
|
#===============================================================================
|
|
|
|
# Configure the minion service
|
|
|
|
#===============================================================================
|
|
|
|
# Wait for salt-minion service to be registered before trying to start it
|
|
|
|
$service = Get-Service salt-minion -ErrorAction SilentlyContinue
|
|
|
|
while (!$service) {
|
|
|
|
Start-Sleep -s 2
|
|
|
|
$service = Get-Service salt-minion -ErrorAction SilentlyContinue
|
|
|
|
}
|
|
|
|
if ( $service ) {
|
|
|
|
Write-Host "Success" -ForegroundColor Green
|
|
|
|
} else {
|
|
|
|
Write-Host "Failed" -ForegroundColor Red
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if($RunService) {
|
|
|
|
# Start service
|
|
|
|
Write-Host "Starting Service: " -NoNewline
|
|
|
|
Start-Service -Name "salt-minion" -ErrorAction SilentlyContinue
|
|
|
|
|
|
|
|
# Check if service is started, otherwise retry starting the
|
|
|
|
# service 4 times.
|
|
|
|
$try = 0
|
|
|
|
while (($service.Status -ne "Running") -and ($try -ne 4)) {
|
2021-01-19 20:15:09 +00:00
|
|
|
Start-Service -Name "salt-minion" -ErrorAction SilentlyContinue
|
2023-04-20 14:31:28 -06:00
|
|
|
$service = Get-Service salt-minion -ErrorAction SilentlyContinue
|
|
|
|
Start-Sleep -s 2
|
|
|
|
$try += 1
|
|
|
|
}
|
2015-07-07 21:34:57 -06:00
|
|
|
|
2023-04-20 14:31:28 -06:00
|
|
|
# If the salt-minion service is still not running, something probably
|
|
|
|
# went wrong and user intervention is required - report failure.
|
|
|
|
if ($service.Status -eq "Running") {
|
|
|
|
Write-Host "Success" -ForegroundColor Green
|
|
|
|
} else {
|
|
|
|
Write-Host "Failed" -ForegroundColor Red
|
|
|
|
exit 1
|
|
|
|
}
|
2016-06-17 16:03:01 -06:00
|
|
|
|
2023-04-20 14:31:28 -06:00
|
|
|
} else {
|
|
|
|
Write-Host "Setting Service to 'Manual': " -NoNewline
|
|
|
|
Set-Service "salt-minion" -StartupType "Manual"
|
|
|
|
if ( (Get-Service "salt-minion").StartType -eq "Manual" ) {
|
|
|
|
Write-Host "Success" -ForegroundColor Green
|
|
|
|
} else {
|
|
|
|
Write-Host "Failed" -ForegroundColor Red
|
|
|
|
exit 1
|
2016-06-17 16:03:01 -06:00
|
|
|
}
|
2023-04-20 14:31:28 -06:00
|
|
|
|
|
|
|
Write-Host "Stopping Service: " -NoNewline
|
|
|
|
Stop-Service "salt-minion"
|
|
|
|
if ( (Get-Service "salt-minion").Status -eq "Stopped" ) {
|
|
|
|
Write-Host "Success" -ForegroundColor Green
|
|
|
|
} else {
|
|
|
|
Write-Host "Failed" -ForegroundColor Red
|
|
|
|
exit 1
|
2016-06-17 16:03:01 -06:00
|
|
|
}
|
2015-07-07 21:34:57 -06:00
|
|
|
}
|
|
|
|
|
2016-06-17 16:03:01 -06:00
|
|
|
#===============================================================================
|
|
|
|
# Script Complete
|
|
|
|
#===============================================================================
|
2023-04-20 14:31:28 -06:00
|
|
|
Write-Host "-------------------------------------------------------------------------------" -ForegroundColor Yellow
|
|
|
|
Write-Host "Salt Minion Installed Successfully" -ForegroundColor Green
|
|
|
|
Write-Host "===============================================================================" -ForegroundColor Yellow
|
|
|
|
exit 0
|