Simplified PowerShell script for repro:
Set-StrictMode -Version Latest
Invoke-WebRequest https://fly.io/install.ps1 -UseBasicParsing | Invoke-Expression
Set-StrictMode
basically enables some additional code safety checks. I executed that script in an elevated PowerShell command prompt (version: 5.1) on Windows 11. I don’t think the PowerShell version or the OS matter here, though.
Resulting error message:
Invoke-Expression : The variable '$v' cannot be retrieved because it has not been set.
I downloaded the contents of your install.ps1
script and noticed that you are using $v
even though it hasn’t been set yet. The call to “if ($v)
” is causing the error.
Your current code:
$Version = if ($v) {
$v
} elseif ($args.Length -eq 1) {
$args.Get(0)
} else {
"latest"
}
To make your $Version
parameter code less wonky, I’d recommend deleting that code entirely, and adding this to the top of your script instead:
[CmdletBinding()]
[OutputType([void])]
param
(
[Alias("v")]
[Parameter(Mandatory = $false)]
[string] $Version = "latest"
)
With that code, your script would now accept the version number in 3 ways:
install.ps1 3.0
install.ps1 -v 3.0
(For backwards compatibility. Judging from how you wrote your original code, I assume you meant for people to call your script that way, even though the script didn’t care about the name of that parameter at all.)install.ps1 -Version 3.0
(so you don’t have to update the rest of the script)
If no version number is passed to the script, it will default to “latest”.
Possibly breaking behavior if you implement my suggestion:
install.ps1
will fail if more than one command line argument is passed to it. Currently, it doesn’t care how many parameters you pass to it.install.ps1
will no longer check if the variable$v
has been set in the current environment. In your current script, if $v is set for some reason, that value will overwrite whatever value has explicitly been passed toinstall.ps1
as a command line argument. Which is a scary thought!- Some callers may currently be doing something like “
install.ps1 -GarbageParameterName 3.0
”, andinstall.ps1
dutifully sets the version number to 3.0. If you implement my suggestion, the script will fail, saying “A parameter cannot be found that matches parameter name 'GarbageParameterName'.
”
To prevent other people from hitting this issue in the future, please add this line towards the top of your script as well:
Set-StrictMode -Version Latest
I assume your script may contain additional lines of code that will fail with Set-StrictMode
enabled. I haven’t checked that yet.