Skip to content

Instantly share code, notes, and snippets.

@stevewithington
Last active March 5, 2026 14:57
Show Gist options
  • Select an option

  • Save stevewithington/024fc85709d6c5a9e82dffcb9dee17a2 to your computer and use it in GitHub Desktop.

Select an option

Save stevewithington/024fc85709d6c5a9e82dffcb9dee17a2 to your computer and use it in GitHub Desktop.
Installs pyenv-win, a couple versions of python, and sets the global version.
<#
.SYNOPSIS
Installs pyenv-win
.DESCRIPTION
Installs pyenv-win to $HOME\.pyenv
If pyenv-win is already installed, try to update to the latest version.
.PARAMETER Uninstall
Uninstall pyenv-win. Note that this uninstalls any Python versions that were installed with pyenv-win.
.PARAMETER Versions
(Optional) A list of Python versions to install after pyenv-win is set up. Example usage: `.\install-pyenv-win.ps1 -Versions 3.12.10, 3.13.11, 3.14.2`
Or, if you don't want to specify versions at install time, you can run `pyenv install <version>` after installation to install any version you want.
Example: `./install-pyenv-win.ps1 -Versions ""` to skip installing versions at install time.
.PARAMETER GlobalVersion
(Optional) Set the global Python version after installation. Example usage: `.\install-pyenv-win.ps1 -Versions 3.12.10, 3.13.11, 3.14.2 -GlobalVersion 3.14.2`
If not specified, the global version will not be set and will default to the system Python until you set it with `pyenv global <version>`.
.EXAMPLE
PS> install-pyenv-win.ps1
.LINK
Original online version: https://pyenv-win.github.io/pyenv-win/
.NOTES
To install or update pyenv-win, run this script in PowerShell. If you want to specify Python versions to install at the same time, use the -Versions parameter.
Example: `.\install-pyenv-win.ps1 -Versions 3.12.10, 3.13.11, 3.14.2`
To download this script, you can use the following command in PowerShell:
`irm "https://gist.githubusercontent.com/stevewithington/024fc85709d6c5a9e82dffcb9dee17a2/raw/281589d755f3fb46658c4df52ba88b9fd3efa609/install-pyenv-win.ps1" -OutFile install-pyenv-win.ps1`
To uninstall pyenv-win, run this script with the -Uninstall switch: `.\install-pyenv-win.ps1 -Uninstall`
To run in memory without downloading the script, you can use the following command:
`irm "https://gist.githubusercontent.com/stevewithington/024fc85709d6c5a9e82dffcb9dee17a2/raw/281589d755f3fb46658c4df52ba88b9fd3efa609/install-pyenv-win.ps1" | iex`
#>
param (
[Switch] $Uninstall,
[String[]] $Versions = @('3.12.10', '3.13.11', '3.14.2'),
[String] $GlobalVersion = '3.14.2'
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$PyEnvDir = Join-Path $env:USERPROFILE '.pyenv'
$PyEnvWinDir = Join-Path $PyEnvDir 'pyenv-win'
$BinPath = Join-Path $PyEnvWinDir 'bin'
$ShimsPath = Join-Path $PyEnvWinDir 'shims'
$VersionUrl = 'https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/.version'
$ArchiveUrl = 'https://github.com/pyenv-win/pyenv-win/archive/master.zip'
function Remove-PyEnvPaths {
$PathParts = [System.Environment]::GetEnvironmentVariable('PATH', 'User') -split ';'
$Cleaned = $PathParts.Where{ $_ -notin @($BinPath, $ShimsPath) }
[System.Environment]::SetEnvironmentVariable('PATH', ($Cleaned -join ';'), 'User')
}
function Remove-PyEnvVars {
Remove-PyEnvPaths
foreach ($Var in 'PYENV', 'PYENV_ROOT', 'PYENV_HOME') {
[System.Environment]::SetEnvironmentVariable($Var, $null, 'User')
}
}
function Get-CurrentVersion {
$VersionFile = Join-Path $PyEnvDir '.version'
if (Test-Path $VersionFile) { return (Get-Content $VersionFile -Raw).Trim() }
return $null
}
function Get-LatestVersion {
return (Invoke-RestMethod -Uri $VersionUrl -UseBasicParsing).Trim()
}
function Install-PyEnv {
$DownloadPath = Join-Path $PyEnvDir 'pyenv-win.zip'
try {
New-Item -Path $PyEnvDir -ItemType Directory -Force | Out-Null
Invoke-WebRequest -Uri $ArchiveUrl -OutFile $DownloadPath -UseBasicParsing
Expand-Archive -Path $DownloadPath -DestinationPath $PyEnvDir -Force
$ExtractedDir = Join-Path $PyEnvDir 'pyenv-win-master'
Get-ChildItem -Path $ExtractedDir | Move-Item -Destination $PyEnvDir -Force
Remove-Item $ExtractedDir, $DownloadPath -Recurse -Force
}
catch {
Write-Error "Download/extraction failed: $_"
return $false
}
# Set environment variables
$PyEnvWinTrailing = "$PyEnvWinDir\"
foreach ($Var in 'PYENV', 'PYENV_ROOT', 'PYENV_HOME') {
[System.Environment]::SetEnvironmentVariable($Var, $PyEnvWinTrailing, 'User')
}
# Update PATH — remove old entries first, then prepend
$PathParts = [System.Environment]::GetEnvironmentVariable('PATH', 'User') -split ';'
$Cleaned = $PathParts.Where{ $_ -notin @($BinPath, $ShimsPath) }
$NewPath = (@($BinPath, $ShimsPath) + $Cleaned) -join ';'
[System.Environment]::SetEnvironmentVariable('PATH', $NewPath, 'User')
return $true
}
Function Install-Versions {
foreach ($Version in $Versions) {
Write-Host "Installing Python $Version..." -ForegroundColor Cyan
& pyenv install $Version
if ($LASTEXITCODE -ne 0) {
Write-Host "Failed to install Python $Version. Please check the error message above and try installing manually with `pyenv install $Version`." -ForegroundColor Red
}
}
}
Function Set-GlobalVersion {
if ($GlobalVersion) {
Write-Host "Setting global Python version to $GlobalVersion..." -ForegroundColor Cyan
& pyenv global $GlobalVersion
if ($LASTEXITCODE -ne 0) {
Write-Host "Failed to set global Python version to $GlobalVersion. Please check the error message above and try setting it manually with `pyenv global $GlobalVersion`." -ForegroundColor Red
} else {
Write-Host "Global Python version set to $GlobalVersion." -ForegroundColor Green
$PythonVersion = & python --version
if ($LASTEXITCODE -ne 0) {
Write-Host "Failed to verify Python version after setting global version. Please ensure your terminal is restarted and try running `python --version`." -ForegroundColor Red
}
else {
Write-Host "Current Python version: $PythonVersion" -ForegroundColor Green
$SystemExe = python -c "import sys; print(sys.executable)"
Write-Host "Python executable path: $SystemExe" -ForegroundColor Green
}
}
}
}
# --- Main logic ---
if ($Uninstall) {
Write-Host 'Removing pyenv-win...' -ForegroundColor Yellow
if (Test-Path $PyEnvDir) { Remove-Item -Path $PyEnvDir -Recurse -Force }
Remove-PyEnvVars
Write-Host 'pyenv-win successfully uninstalled.' -ForegroundColor Green
exit 0
}
$BackupDir = Join-Path $env:TEMP 'pyenv-win-backup'
$FoldersToBackup = @('install_cache', 'versions', 'shims')
$CurrentVersion = Get-CurrentVersion
if ($CurrentVersion) {
Write-Host "pyenv-win $CurrentVersion installed." -ForegroundColor Green
$LatestVersion = Get-LatestVersion
if ($CurrentVersion -eq $LatestVersion) {
Write-Host 'No updates available.'
exit 0
}
Write-Host "New version available: $LatestVersion. Updating..." -ForegroundColor Cyan
# Backup existing data in one pass
New-Item -Path $BackupDir -ItemType Directory -Force | Out-Null
foreach ($Dir in $FoldersToBackup) {
$Source = Join-Path $PyEnvWinDir $Dir
if (Test-Path $Source) { Move-Item -Path $Source -Destination $BackupDir }
}
Remove-Item -Path $PyEnvDir -Recurse -Force
}
if (Install-PyEnv) {
# Restore backups if they exist
if (Test-Path $BackupDir) {
Write-Host 'Restoring Python installations...' -ForegroundColor Cyan
Get-ChildItem -Path $BackupDir | Move-Item -Destination $PyEnvWinDir -Force
Remove-Item -Path $BackupDir -Recurse -Force
}
Write-Host 'pyenv-win is successfully installed!' -ForegroundColor Green
Write-Host 'Running `pyenv --version` to verify installation...' -ForegroundColor Cyan
$pyenvVersion = & pyenv --version
if ($LASTEXITCODE -ne 0) {
Write-Host 'pyenv command failed to execute. Please ensure your terminal is restarted and try again.' -ForegroundColor Red
exit 1
}
else {
Write-Host "$pyenvVersion" -ForegroundColor Green
if ($Versions.Count -gt 0) {
Install-Versions
Set-GlobalVersion
}
}
Write-Host 'Installation complete! Visit https://pyenv-win.github.io/pyenv-win/#usage for usage instructions.' -ForegroundColor Cyan
}
else {
Write-Host 'pyenv-win was not installed successfully. If this issue persists, please open a ticket: https://github.com/pyenv-win/pyenv-win/issues.' -ForegroundColor Red
exit 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment