5050param (
5151 [Parameter (Mandatory = $false , ValueFromPipeline = $True )]
5252 [Alias (" v" )]
53- # The version of the Salt minion to install. Default is "latest" which will
54- # install the latest version of Salt minion available. Doesn't support
55- # versions prior to "YYYY.M.R-B"
53+ # The version of the Salt minion to install. Use "latest" for the most recent
54+ # GA (general availability) build at RepoUrl; prerelease directories (for
55+ # example names containing "rc") are ignored for "latest" and for major-series
56+ # selection. To install a prerelease build, pass the exact directory name
57+ # shown at RepoUrl (for example "3008.0rc1"). Alternatively, specify a major
58+ # version for the latest GA in that series (for example "3006"). Versions
59+ # older than 3006 are not supported.
5660 [String ]$Version = " latest" ,
5761
5862 [Parameter (Mandatory = $false , ValueFromPipeline = $True )]
@@ -108,7 +112,7 @@ if ($help) {
108112 exit 0
109113}
110114
111- $__ScriptVersion = " 2026.01.22 "
115+ $__ScriptVersion = " 2026.05.01 "
112116$ScriptName = $myInvocation.MyCommand.Name
113117
114118# We'll check for the Version next, because it also has no requirements
@@ -153,6 +157,40 @@ function Get-MajorVersion {
153157 return ( $Version -split " \." )[0 ]
154158}
155159
160+ function Test-SaltOnedirVersionIsGA {
161+ # True if the onedir directory name is a GA CalVer (digits and dots only).
162+ # Prerelease dirs (e.g. 3008.0rc1) are not GA; install those only via exact
163+ # -Version matching the directory name.
164+ [CmdletBinding ()]
165+ param (
166+ [Parameter (Mandatory = $true )]
167+ [String ] $Version
168+ )
169+ return [bool ]( $Version -match ' ^\d+\.\d+(\.\d+)*$' )
170+ }
171+
172+ function Compare-SaltCalVer {
173+ # Compare two GA numeric CalVer strings (e.g. 3006.24 vs 3007.0). Returns 1
174+ # if Left is greater than Right, -1 if less, 0 if equal.
175+ [CmdletBinding ()]
176+ param (
177+ [Parameter (Mandatory = $true )]
178+ [String ] $Left ,
179+ [Parameter (Mandatory = $true )]
180+ [String ] $Right
181+ )
182+ $left_parts = @ ( ($Left -split ' \.' ) | ForEach-Object { [int ]$_ } )
183+ $right_parts = @ ( ($Right -split ' \.' ) | ForEach-Object { [int ]$_ } )
184+ $max_len = [Math ]::Max($left_parts.Count , $right_parts.Count )
185+ for ( $i = 0 ; $i -lt $max_len ; $i ++ ) {
186+ $a = if ( $i -lt $left_parts.Count ) { $left_parts [$i ] } else { 0 }
187+ $b = if ( $i -lt $right_parts.Count ) { $right_parts [$i ] } else { 0 }
188+ if ( $a -gt $b ) { return 1 }
189+ if ( $a -lt $b ) { return -1 }
190+ }
191+ return 0
192+ }
193+
156194function Get-AvailableVersions {
157195 # Get available versions from a remote location specified in the Source
158196 # Parameter
@@ -163,7 +201,6 @@ function Get-AvailableVersions {
163201
164202 if ( $base_url.StartsWith (" http" ) -or $base_url.StartsWith (" ftp" ) ) {
165203 # We're dealing with HTTP, HTTPS, or FTP
166- $response = Invoke-WebRequest " $base_url " - UseBasicParsing
167204 try {
168205 $response = Invoke-WebRequest " $base_url " - UseBasicParsing
169206 } catch {
@@ -177,19 +214,15 @@ function Get-AvailableVersions {
177214 exit 1
178215 }
179216
180- $response.links | ForEach-Object {
181- if ( $_.href.Length -gt 8 ) {
182- Write-Host " The content at this location is unexpected" - ForegroundColor Red
183- Write-Host " Should be a list of directories where the name is a version of Salt" - ForegroundColor Red
184- exit 1
185- }
186- }
187-
188- # Getting available versions from response
217+ # Getting available versions from response (Salt dirs: 3006.24, 3008.0,
218+ # 3008.0rc1, etc.). Skip non-version links from the index page.
189219 Write-Verbose " Getting available versions from response"
190220 $filtered = $response.Links | Where-Object - Property href -NE " ../"
191- $filtered | Select-Object - Property href | ForEach-Object {
192- $available_versions.Add ($_.href.Trim (" /" )) | Out-Null
221+ $filtered | ForEach-Object {
222+ $name = $_.href.Trim (" /" )
223+ if ( $name -match ' ^\d+\.\d+' ) {
224+ $available_versions.Add ($name ) | Out-Null
225+ }
193226 }
194227 } elseif ( $base_url.StartsWith (" \\" ) -or $base_url -match " ^[A-Za-z]:\\" ) {
195228 # We're dealing with a local directory or SMB source
@@ -202,34 +235,42 @@ function Get-AvailableVersions {
202235 exit 1
203236 }
204237
238+ if ( $available_versions.Count -eq 0 ) {
239+ Write-Host " No version directories found at RepoUrl" - ForegroundColor Red
240+ Write-Host " base_url: $base_url " - ForegroundColor Red
241+ exit 1
242+ }
243+
205244 Write-Verbose " Available versions:"
206245 $available_versions | ForEach-Object {
207246 Write-Verbose " - $_ "
208247 }
209248
210249 # Create a versions table
211- # This will have the latest version available, the latest version available
212- # for each major version, and every version available. This makes the
213- # version lookup logic easier. The contents of the versions table can be
214- # found by running -Verbose
250+ # "latest" and each major-series key (3006, 3007, ...) use the newest GA
251+ # build only; prerelease dirs still appear under their exact names. Every
252+ # discovered directory name is also stored lowercased for lookup. The
253+ # contents of the versions table can be found by running -Verbose
215254 Write-Verbose " Populating the versions table"
216255 $versions_table = [ordered ]@ {}
217256 $available_versions | ForEach-Object {
218257 $major_version = $ (Get-MajorVersion $_ )
219- if ( $versions_table.Keys -contains $major_version ) {
220- if ( [System.Version ]$_ -gt [System.Version ]$versions_table [$major_version ] ) {
258+ if ( Test-SaltOnedirVersionIsGA $_ ) {
259+ if ( $versions_table.Keys -contains $major_version ) {
260+ if ( (Compare-SaltCalVer $_ $versions_table [$major_version ]) -gt 0 ) {
261+ $versions_table [$major_version ] = $_
262+ }
263+ } else {
221264 $versions_table [$major_version ] = $_
222265 }
223- } else {
224- $versions_table [$major_version ] = $_
225- }
226266
227- if ( $versions_table -contains " latest" ) {
228- if ( [System.Version ]$_ -gt [System.Version ]$versions_table [" latest" ] ) {
267+ if ( $versions_table.Keys -contains " latest" ) {
268+ if ( (Compare-SaltCalVer $_ $versions_table [" latest" ]) -gt 0 ) {
269+ $versions_table [" latest" ] = $_
270+ }
271+ } else {
229272 $versions_table [" latest" ] = $_
230273 }
231- } else {
232- $versions_table [" latest" ] = $_
233274 }
234275
235276 $versions_table [$_.ToLower ()] = $_.ToLower ()
0 commit comments