Skip to content

Instantly share code, notes, and snippets.

@YoraiLevi
Last active May 17, 2026 22:37
Show Gist options
  • Select an option

  • Save YoraiLevi/c19fa68ff740cdb7dfe8d2c3a0240680 to your computer and use it in GitHub Desktop.

Select an option

Save YoraiLevi/c19fa68ff740cdb7dfe8d2c3a0240680 to your computer and use it in GitHub Desktop.
Install Podman on Windows for current user only — step-by-step guide + PowerShell script

Install Podman on Windows — current user only

How to install Podman on Windows without admin rights (other than the one-time wsl --install, which Windows itself requires elevation for).

Sources:


TL;DR — run the script straight from this gist

Open a non-elevated PowerShell and:

$url  = 'https://gist.githubusercontent.com/YoraiLevi/c19fa68ff740cdb7dfe8d2c3a0240680/raw/install-podman-user.ps1'
$dest = "$env:TEMP\install-podman-user.ps1"
Invoke-WebRequest -UseBasicParsing $url -OutFile $dest
Unblock-File $dest                              # strip Mark-of-the-Web so PS doesn't block it
& $dest -IncludeDesktop                         # any script flags go here
What a successful run looks like (verified on Windows 11 Pro build 26200)
==> Checking Windows version
    Microsoft Windows 11 Pro (build 26200)
==> Checking hardware virtualization
[OK] Enabled.
==> Checking WSL2
[OK] Available.
==> Installing Podman CLI (per-user)
    Downloading podman-installer-windows-amd64.msi (v5.8.2)
[OK] Installed to C:\Users\devic\AppData\Local\Programs\Podman
==> Installing Podman Desktop (per-user)
    Downloading podman-desktop-1.27.1-setup-x64.exe (v1.27.1)
[OK] Installed.
    podman: C:\Users\devic\AppData\Local\Programs\Podman\podman.exe
podman version 5.8.2
==> Initializing podman machine (first run downloads ~1 GB Fedora image)
Looking up Podman Machine image at quay.io/podman/machine-os:5.8 to create VM
Getting image source signatures
Copying blob e2b6cbcadd8b done   |
Copying config 44136fa355 done   |
Writing manifest to image destination
e2b6cbcadd8b41b708fecb58a246a20d737dee0ef26872a3f75b575f77eba968
Extracting compressed file: podman-machine-default-amd64: done
Importing operating system into WSL (this may take a few minutes on a new WSL install)...
wsl: Sparse VHD support is currently disabled due to potential data corruption.
To force a distribution to use a sparse vhd, please run:
wsl.exe --manage <DistributionName> --set-sparse true --allow-unsafe
The operation completed successfully.
Configuring system...
Machine init complete
To start your machine run:

        podman machine start

==> Starting podman machine
==> Smoke test: hello-world
Resolved "hello-world" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull quay.io/podman/hello:latest...
Getting image source signatures
Copying blob sha256:81df7ff16254ed9756e27c8de9ceb02a9568228fccadbf080f41cc5eb5118a44
Copying config sha256:5dd467fce50b56951185da365b5feee75409968cbab5767b9b59e325fb2ecbc0
Writing manifest to image destination
!... Hello Podman World ...!

         .--"--.
       / -     - \
      / (O)   (O) \
   ~~~| -=(,Y,)=- |
    .---. /`  \   |~~
 ~/  o  o \~~~~.----. ~~
  | =(X)= |~  / (O (O) \
   ~~~~~~~  ~| =(Y_)=-  |
  ~~~~    ~~~|   U      |~~

Project:   https://github.com/containers/podman
Website:   https://podman.io
Desktop:   https://podman-desktop.io
Documents: https://docs.podman.io
YouTube:   https://youtube.com/@Podman
X/Twitter: @Podman_io
Mastodon:  @Podman_io@fosstodon.org
[OK] Podman is working.

Script flags: -IncludeDesktop, -SkipMachine, -Provider wsl|hyperv.


The same thing, manually (no script)

# Download the MSI from the latest GitHub release
$asset = (Invoke-RestMethod https://api.github.com/repos/containers/podman/releases/latest).assets |
         Where-Object name -like 'podman-installer-windows-amd64.msi' | Select-Object -First 1
$msi = Join-Path $env:TEMP $asset.name
Invoke-WebRequest -UseBasicParsing $asset.browser_download_url -OutFile $msi

# Per-user install. No admin, no UAC.
msiexec /i $msi /qn /norestart /l*v "$env:TEMP\podman-msi.log" `
        MSIINSTALLPERUSER=1 MACHINE_PROVIDER=wsl

# New PowerShell window so PATH picks up podman.exe
podman machine init
podman machine start
podman run --rm hello-world

Files land in %LOCALAPPDATA%\Programs\Podman, provider config in %APPDATA%\containers\containers.conf.d\, PATH updated for your user only.


Prerequisites

Requirement Why How to check
Windows 11, or Windows 10 build 19043+ Installer minimum winver
Hardware virtualization in BIOS/UEFI WSL2 needs it Task Manager → Performance → CPU → "Virtualization: Enabled"
WSL2 installed Default Podman backend wsl --status shows "Default Version: 2"

WSL2 install (one-time, needs admin):

wsl --install

Reboot, then continue as your normal user.


MSI properties

From the WiX source (podman-main.wxs):

Property Value Effect
MSIINSTALLPERUSER 1 Install for the current user only (no admin)
ALLUSERS 1 Install machine-wide (requires admin)
MACHINE_PROVIDER wsl (default) or hyperv Backend; writes the provider config file
SKIP_CONFIG_FILE_CREATION 1 Don't write that config file

Why not winget?

winget install RedHat.Podman cannot do a per-user install of Podman today, regardless of flags. Confirmed by testing:

  • --scope userAPPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER (-1978335216). The manifest declares no per-user variant.
  • Without --scope → UAC prompt, then installs to C:\Program Files\RedHat\Podman (machine-wide). winget runs the Burn bootstrapper which requests admin in its embedded manifest, so the underlying MSI runs elevated and ignores MSIINSTALLPERUSER.
  • The manifest also declares a Microsoft-Windows-Subsystem-Linux Windows-feature dependency that triggers UAC if WSL2 isn't already on the box (podman#22045, winget-pkgs#144380).

Use the MSI directly with MSIINSTALLPERUSER=1. That's the path Podman's own docs and the WiX source treat as the supported per-user install.


Optional: Podman Desktop (also per-user)

$asset = (Invoke-RestMethod https://api.github.com/repos/podman-desktop/podman-desktop/releases/latest).assets |
         Where-Object name -like 'podman-desktop-*-setup-x64.exe' | Select-Object -First 1
$exe = Join-Path $env:TEMP $asset.name
Invoke-WebRequest -UseBasicParsing $asset.browser_download_url -OutFile $exe
& $exe /S /CURRENTUSER

Or via the GUI: download from https://podman-desktop.io/downloads/windows, double-click, choose "Only for me (Username)".


Common issues

Symptom Fix
wsl --install says "Access denied" Run PowerShell as Administrator for this one step
podman not on PATH after install Open a new PowerShell window, or refresh PATH: $env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [Environment]::GetEnvironmentVariable('Path','User')
Install ended up in C:\Program Files\... You used winget or ran the Burn .exe. Uninstall, then use the MSI with MSIINSTALLPERUSER=1
podman machine init errors about virtualization Enable VT-x/AMD-V in BIOS, reboot
Can't bind port 80 in a container Rootless can't use ports <1024. Map to a high port, or podman machine stop; podman machine set --rootful; podman machine start
Docker Desktop also installed and clashes setx DOCKER_HOST "npipe:////./pipe/podman-machine-default"
Want to start over podman machine stop; podman machine rm -f; podman machine init

Uninstall

podman machine stop
podman machine rm -f
$msi = (Invoke-RestMethod https://api.github.com/repos/containers/podman/releases/latest).assets |
       Where-Object name -like 'podman-installer-windows-amd64.msi' | Select-Object -First 1
msiexec /x $msi.browser_download_url /qn   # or: Settings → Apps → Podman → Uninstall

Script flags

.\install-podman-user.ps1                  # CLI only, per-user, WSL provider
.\install-podman-user.ps1 -IncludeDesktop  # also install Podman Desktop
.\install-podman-user.ps1 -SkipMachine     # install only; don't init/start machine
.\install-podman-user.ps1 -Provider hyperv # Hyper-V backend (Pro/Enterprise)
#Requires -Version 5.1
<#
.SYNOPSIS
Install Podman CLI (and optionally Podman Desktop) for the current user only.
.PARAMETER IncludeDesktop
Also install Podman Desktop.
.PARAMETER SkipMachine
Install only; don't init/start the podman machine.
.PARAMETER Provider
Backend for podman machine: 'wsl' (default) or 'hyperv'.
.PARAMETER MachineName
Name of the machine to check for / create.
.EXAMPLE
.\install-podman-user.ps1
.\install-podman-user.ps1 -IncludeDesktop
.\install-podman-user.ps1 -SkipMachine
#>
[CmdletBinding()]
param(
[switch]$IncludeDesktop,
[switch]$SkipMachine,
[ValidateSet('wsl','hyperv')]
[string]$Provider = 'wsl',
[string]$MachineName = 'podman-machine-default'
)
$ErrorActionPreference = 'Stop'
function Write-Step($msg) { Write-Host "==> $msg" -ForegroundColor Cyan }
function Write-Info($msg) { Write-Host " $msg" -ForegroundColor DarkGray }
function Write-Ok ($msg) { Write-Host "[OK] $msg" -ForegroundColor Green }
function Write-Warn2($msg){ Write-Host "[!] $msg" -ForegroundColor Yellow }
function Get-LatestAsset {
param([string]$Repo, [string]$Pattern)
$rel = Invoke-RestMethod -UseBasicParsing `
-Uri "https://api.github.com/repos/$Repo/releases/latest" `
-Headers @{ 'User-Agent' = 'install-podman-user' }
$asset = $rel.assets | Where-Object { $_.name -like $Pattern } | Select-Object -First 1
if (-not $asset) { throw "No asset matching '$Pattern' in $Repo latest release." }
[pscustomobject]@{ Name = $asset.name; Url = $asset.browser_download_url; Tag = $rel.tag_name }
}
function Save-Asset {
param([string]$Repo, [string]$Pattern)
$asset = Get-LatestAsset -Repo $Repo -Pattern $Pattern
$dest = Join-Path $env:TEMP $asset.Name
Write-Info "Downloading $($asset.Name) ($($asset.Tag))"
Invoke-WebRequest -UseBasicParsing -Uri $asset.Url -OutFile $dest
$dest
}
# --- Preflight ---------------------------------------------------------------
Write-Step 'Checking Windows version'
$os = Get-CimInstance Win32_OperatingSystem
Write-Info "$($os.Caption) (build $($os.BuildNumber))"
if ([int]$os.BuildNumber -lt 19043) {
throw "Windows 10 build 19043+ or Windows 11 required."
}
Write-Step 'Checking hardware virtualization'
try {
$ci = Get-ComputerInfo -Property 'HyperV*' -ErrorAction Stop
if ($ci.HyperVRequirementVirtualizationFirmwareEnabled -eq $false) {
Write-Warn2 'Firmware reports virtualization DISABLED. Enable VT-x/AMD-V in BIOS.'
} else {
Write-Ok 'Enabled.'
}
} catch {
Write-Warn2 "Couldn't query; continuing."
}
Write-Step 'Checking WSL2'
$null = & wsl.exe --status 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Warn2 'WSL2 not detected. Run "wsl --install" in an ADMIN PowerShell, reboot, then re-run this script.'
exit 1
}
Write-Ok 'Available.'
$machineWide = Join-Path $env:ProgramFiles 'RedHat\Podman\podman.exe'
if (Test-Path $machineWide) {
Write-Warn2 "Existing machine-wide Podman at $machineWide will shadow this per-user install on PATH."
Write-Warn2 'Uninstall it first (Settings -> Apps -> Podman) for a clean per-user setup.'
}
# --- Install Podman CLI ------------------------------------------------------
Write-Step 'Installing Podman CLI (per-user)'
$msi = Save-Asset -Repo 'containers/podman' -Pattern 'podman-installer-windows-amd64.msi'
$log = Join-Path $env:TEMP 'podman-msi.log'
$msiArgs = @('/i', "`"$msi`"", '/qn', '/norestart', '/l*v', "`"$log`"",
'MSIINSTALLPERUSER=1', "MACHINE_PROVIDER=$Provider")
$p = Start-Process -FilePath 'msiexec.exe' -ArgumentList $msiArgs -Wait -PassThru -NoNewWindow
if ($p.ExitCode -ne 0) { throw "msiexec exited $($p.ExitCode); see $log" }
Write-Ok "Installed to $env:LOCALAPPDATA\Programs\Podman"
# --- Optional Podman Desktop -------------------------------------------------
if ($IncludeDesktop) {
Write-Step 'Installing Podman Desktop (per-user)'
$exe = Save-Asset -Repo 'podman-desktop/podman-desktop' -Pattern 'podman-desktop-*-setup-x64.exe'
$p = Start-Process -FilePath $exe -ArgumentList @('/S','/CURRENTUSER') -Wait -PassThru -NoNewWindow
if ($p.ExitCode -ne 0) {
Write-Warn2 "Podman Desktop installer exited $($p.ExitCode); continuing."
} else {
Write-Ok 'Installed.'
}
}
# --- Refresh PATH ------------------------------------------------------------
$env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' +
[Environment]::GetEnvironmentVariable('Path','User')
$podman = Get-Command podman -ErrorAction SilentlyContinue
if (-not $podman) {
throw "podman.exe not on PATH after install. Open a new terminal and run 'podman machine init; podman machine start'."
}
Write-Info "podman: $($podman.Source)"
& podman --version
if ($SkipMachine) { return }
# --- Machine init / start / smoke test ---------------------------------------
$existing = (& podman machine list --format '{{.Name}}' 2>$null) -split "`n" |
ForEach-Object { $_.Trim().TrimEnd('*') }
if ($existing -contains $MachineName) {
Write-Info "Machine '$MachineName' already exists."
} else {
Write-Step 'Initializing podman machine (first run downloads ~1 GB Fedora image)'
& podman machine init
if ($LASTEXITCODE -ne 0) { throw 'podman machine init failed.' }
}
Write-Step 'Starting podman machine'
$startOut = & podman machine start 2>&1 | Out-String
& podman info > $null 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host $startOut
throw 'podman is not responding after machine start.'
}
Write-Step 'Smoke test: hello-world'
& podman run --rm hello-world
if ($LASTEXITCODE -ne 0) { throw 'hello-world failed; run "podman info" to diagnose.' }
Write-Ok 'Podman is working.'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment