1- function Convert-PSObjectToHashtable {
2- param (
3- [Parameter (ValueFromPipeline )]
4- $InputObject
5- )
6- if ($null -eq $InputObject ) { return $null }
7-
8- $is_enum = $InputObject -is [System.Collections.IEnumerable ]
9- $not_string = $InputObject -isnot [string ]
10- if ($is_enum -and $not_string ) {
11- $collection = @ (
12- foreach ($object in $InputObject ) {
13- Convert-PSObjectToHashtable $object
14- }
15- )
1+ <#
2+ . SYNOPSIS
3+ A simple Powershell script to quickly start using Salt.
164
17- Write-Host - NoEnumerate $collection
18- } elseif ($InputObject -is [PSObject ]) {
19- $hash = @ {}
5+ . DESCRIPTION
6+ This script will download the latest onedir version of Salt and extract it
7+ into the same directory where the script is run. The script sets up an
8+ environment that will allow you to run salt-call commands. To remove, just
9+ delete the `salt` directory. The environment variables will only be set for
10+ the current powershell session.
2011
21- foreach ($property in $InputObject.PSObject.Properties ) {
22- $hash [$property.Name ] = Convert-PSObjectToHashtable $property.Value
23- }
12+ . EXAMPLE
13+ ./salt-quick-start.ps1
2414
25- $hash
26- } else {
27- $InputObject
28- }
29- }
15+ . LINK
16+ Salt Bootstrap GitHub Project (script home) - https://github.com/saltstack/salt-bootstrap
17+ Original Vagrant Provisioner Project - https://github.com/saltstack/salty-vagrant
18+ Vagrant Project (utilizes this script) - https://github.com/mitchellh/vagrant
19+ Salt Download Location - https://packages.broadcom.com/artifactory/saltproject-generic/windows/
20+ Salt Manual Install Directions (Windows) - https://docs.saltproject.io/salt/install-guide/en/latest/topics/install-by-operating-system/windows.html
21+ #>
22+
23+ # This is so the -Verbose parameter will work
24+ [CmdletBinding ()] param ()
3025
3126function Expand-ZipFile {
3227 # Extract a zip file
3328 #
34- # Used by:
35- # - Install-SaltMinion
36- #
3729 # Args:
3830 # ZipFile (string): The file to extract
3931 # Destination (string): The location to extract to
@@ -81,60 +73,151 @@ function Expand-ZipFile {
8173 Write-Debug " Finished unzipping '$ZipFile ' to '$Destination '"
8274}
8375
76+ function Get-FileHash {
77+ # Get-FileHash is a built-in cmdlet in powershell 5+ but we need to support
78+ # powershell 3. This will overwrite the powershell 5 commandlet only for
79+ # this script. But it will provide the missing cmdlet for powershell 3
80+ [CmdletBinding ()]
81+ param (
82+ [Parameter (Mandatory = $true )]
83+ [String ] $Path ,
8484
85- [System.Net.ServicePointManager ]::SecurityProtocol = [System.Net.SecurityProtocolType ]' Tls12'
85+ [Parameter (Mandatory = $false )]
86+ [ValidateSet (
87+ " SHA1" ,
88+ " SHA256" ,
89+ " SHA384" ,
90+ " SHA512" ,
91+ # https://serverfault.com/questions/820300/
92+ # why-isnt-mactripledes-algorithm-output-in-powershell-stable
93+ " MACTripleDES" , # don't use
94+ " MD5" ,
95+ " RIPEMD160" ,
96+ IgnoreCase= $true )]
97+ [String ] $Algorithm = " SHA256"
98+ )
8699
87- $global :ProgressPreference = ' SilentlyContinue'
100+ if ( ! (Test-Path $Path ) ) {
101+ Write-Verbose " Invalid path for hashing: $Path "
102+ return @ {}
103+ }
88104
89- $RepoUrl = " https://repo.saltproject.io/salt/py3/onedir"
105+ if ( (Get-Item - Path $Path ) -isnot [System.IO.FileInfo ]) {
106+ Write-Verbose " Not a file for hashing: $Path "
107+ return @ {}
108+ }
90109
91- if ([IntPtr ]::Size -eq 4 ) {
92- $arch = " x86"
93- } else {
94- $arch = " amd64"
95- }
96- $enc = [System.Text.Encoding ]::UTF8
97- try {
98- $response = Invoke-WebRequest - Uri " $RepoUrl /repo.json" - UseBasicParsing
99- if ($response.Content.GetType ().Name -eq " Byte[]" ) {
100- $psobj = $enc.GetString ($response.Content ) | ConvertFrom-Json
110+ $Path = Resolve-Path - Path $Path
101111
102- } else {
103- $psobj = $response.Content | ConvertFrom-Json
104- }
105- $hash = Convert-PSObjectToHashtable $psobj
106- } catch {
107- Write-Host " repo.json not found at: $RepoUrl "
108- $hash = @ {}
109- }
110- $searchVersion = " latest"
111- if ( $hash.Contains ($searchVersion )) {
112- foreach ($item in $hash .($searchVersion ).Keys) {
113- if ( $item.EndsWith (" .zip" ) ) {
114- if ( $item.Contains ($arch ) ) {
115- $saltFileName = $hash .($searchVersion ).($item ).name
116- $saltVersion = $hash .($searchVersion ).($item ).version
117- $saltSha512 = $hash .($searchVersion ).($item ).SHA512
118- }
112+ Switch ($Algorithm ) {
113+ SHA1 {
114+ $hasher = [System.Security.Cryptography.SHA1CryptoServiceProvider ]::Create()
115+ }
116+ SHA256 {
117+ $hasher = [System.Security.Cryptography.SHA256 ]::Create()
118+ }
119+ SHA384 {
120+ $hasher = [System.Security.Cryptography.SHA384 ]::Create()
121+ }
122+ SHA512 {
123+ $hasher = [System.Security.Cryptography.SHA512 ]::Create()
124+ }
125+ MACTripleDES {
126+ $hasher = [System.Security.Cryptography.MACTripleDES ]::Create()
127+ }
128+ MD5 {
129+ $hasher = [System.Security.Cryptography.MD5 ]::Create()
130+ }
131+ RIPEMD160 {
132+ $hasher = [System.Security.Cryptography.RIPEMD160 ]::Create()
119133 }
120134 }
121- }
122- if ( $saltFileName -and $saltVersion -and $saltSha512 ) {
123- if ( $RepoUrl.Contains (" minor" ) ) {
124- $saltFileUrl = @ ($RepoUrl , $saltVersion , $saltFileName ) -join " /"
125- } else {
126- $saltFileUrl = @ ($RepoUrl , " minor" , $saltVersion , $saltFileName ) -join " /"
135+
136+ Write-Verbose " Hashing using $Algorithm algorithm"
137+ try {
138+ $data = [System.IO.File ]::OpenRead($Path )
139+ $hash = $hasher.ComputeHash ($data )
140+ $hash = [System.BitConverter ]::ToString($hash ) -replace " -" , " "
141+ return @ {
142+ Path = $Path ;
143+ Algorithm = $Algorithm.ToUpper ();
144+ Hash = $hash
145+ }
146+ } catch {
147+ Write-Verbose " Error hashing: $Path "
148+ Write-Verbose " ERROR: $_ "
149+ return @ {}
150+ } finally {
151+ if ($null -ne $data ) {
152+ $data.Close ()
153+ }
127154 }
128155}
129156
130- Write-Host " * INFO: Downloading Salt"
157+ # ===============================================================================
158+ # Script settings
159+ # ===============================================================================
160+ [System.Net.ServicePointManager ]::SecurityProtocol = [System.Net.SecurityProtocolType ]' Tls12'
161+ $global :ProgressPreference = ' SilentlyContinue'
162+
163+ # ===============================================================================
164+ # Declare Variables
165+ # ===============================================================================
166+ $ApiUrl = " https://packages.broadcom.com/artifactory/api/storage/saltproject-generic/onedir"
167+ # Detect architecture ($arch)
168+ if ([IntPtr ]::Size -eq 4 ) { $arch = " x86" } else { $arch = " amd64" }
169+
170+ # ===============================================================================
171+ # Setting up quickstart environment
172+ # ===============================================================================
173+ Write-Host " "
174+ Write-Host " Setting up quickstart environment for Salt" - ForegroundColor Cyan
175+
176+ Write-Verbose " Getting version information from Artifactory"
177+ $response = Invoke-WebRequest $ApiUrl - UseBasicParsing
178+ # Convert the output to a powershell object
179+ $psobj = $response.ToString () | ConvertFrom-Json
180+ $Version = $psobj.children [-1 ].uri.Trim(" /" )
181+
182+ Write-Verbose " Getting sha256 hash and download url from Artifactory"
183+ $saltFileName = " salt-$Version -onedir-windows-$arch .zip"
184+ $response = Invoke-WebRequest " $ApiUrl /$Version /$saltFileName " - UseBasicParsing
185+ $psobj = $response.ToString () | ConvertFrom-Json
186+ $saltFileUrl = $psobj.downloadUri
187+ $saltSha256 = $psobj.checksums.sha256
188+
189+ Write-Verbose " URL: $saltFileUrl "
190+ Write-Host " * INFO: Downloading Salt: " - NoNewline
131191Invoke-WebRequest - Uri $saltFileUrl - OutFile .\salt.zip
192+ if ( Test-Path - Path .\salt.zip ) {
193+ Write-Host " Success" - ForegroundColor Green
194+ } else {
195+ Write-Host " Failed" - ForegroundColor Red
196+ exit 1
197+ }
198+ $localSha256 = (Get-FileHash - Path .\salt.zip - Algorithm SHA256).Hash
199+ Write-Verbose " Local Hash: $localSha256 "
200+ Write-Verbose " Remote Hash: $saltSha256 "
201+
202+ Write-Host " * INFO: Comparing Hash: " - NoNewline
203+ if ( $localSha256 -eq $saltSha256 ) {
204+ Write-Host " Success" - ForegroundColor Green
205+ } else {
206+ Write-Host " Failed" - ForegroundColor Red
207+ exit 1
208+ }
132209
133- Write-Host " * INFO: Extracting Salt"
210+ Write-Host " * INFO: Extracting Salt: " - NoNewline
134211Expand-ZipFile - ZipFile .\salt.zip - Destination .
212+ if ( Test-Path - Path .\salt\Scripts\python.exe ) {
213+ Write-Host " Success" - ForegroundColor Green
214+ } else {
215+ Write-Host " Failed" - ForegroundColor Red
216+ exit 1
217+ }
135218
219+ Write-Host " * INFO: Creating Saltfile: " - NoNewline
136220$PATH = $ (Get-Location ).Path
137-
138221$saltfile_contents = @"
139222salt-call:
140223 local: True
@@ -143,20 +226,42 @@ salt-call:
143226 cachedir: $PATH \salt\var\cache\salt
144227 file_root: $PATH \salt\srv\salt
145228"@
146-
147229Set-Content - Path .\salt\Saltfile - Value $saltfile_contents
230+ if ( Test-Path - Path .\salt\Saltfile ) {
231+ Write-Host " Success" - ForegroundColor Green
232+ } else {
233+ Write-Host " Failed" - ForegroundColor Red
234+ exit 1
235+ }
148236
149237New-Item - Path " $PATH \salt\var\log\salt" - Type Directory - Force | Out-Null
150238New-Item - Path " $PATH \salt\conf" - Type Directory - Force | Out-Null
151239New-Item - Path " $PATH \salt\var\cache\salt" - Type Directory - Force | Out-Null
152240New-Item - Path " $PATH \salt\srv\salt" - Type Directory - Force | Out-Null
153241
154- Write-Host " * INFO: Adding Salt to current path"
155- Write-Host " * INFO: $PATH \salt"
242+ Write-Host " * INFO: Adding Salt to current path: " - NoNewline
156243$env: Path = " $PATH \salt;$env: PATH "
244+ Write-Verbose $env: Path
245+ if ( $env: PATH -Like " *$PATH \salt*" ) {
246+ Write-Host " Success" - ForegroundColor Green
247+ } else {
248+ Write-Host " Failed" - ForegroundColor Red
249+ exit 1
250+ }
251+ Write-Host " * INFO: $PATH \salt"
157252
158- Write-Host " * INFO: Setting the SALT_SALTFILE environment variable"
159- Write-Host " * INFO: $PATH \salt\Saltfile"
253+ Write-Host " * INFO: Setting the SALT_SALTFILE environment variable: " - NoNewline
160254$env: SALT_SALTFILE = " $PATH \salt\Saltfile"
255+ if ( Test-Path - Path $env: SALT_SALTFILE ) {
256+ Write-Host " Success" - ForegroundColor Green
257+ } else {
258+ Write-Host " Failed" - ForegroundColor Red
259+ exit 1
260+ }
261+ Write-Host " * INFO: $PATH \salt\Saltfile"
161262
263+ Write-Host " "
264+ Write-Host " You can now run simple salt-call commands" - ForegroundColor Cyan
162265Write-Host " * INFO: Create Salt states in $PATH \salt\srv\salt"
266+ Write-Host " * INFO: Try running salt-call test.ping"
267+ Write-Host " "
0 commit comments