Linux

How to Install PowerShell 7 on Ubuntu (2026 Guide, with Cross-Platform Scripting)

13 min read

The Back Room Tech is reader-supported. We may earn a commission when you buy through links on our site. Learn more.

If you manage a mix of Windows Server and Ubuntu boxes, you know this problem: two versions of the same script, one in Bash, one in PowerShell. They drift apart every time you touch one and forget the other. Installing PowerShell 7 on Ubuntu fixes that. You get one script and one set of cmdlets that run the same way on both operating systems.

This guide installs PowerShell 7 via Microsoft’s official apt repository. You’ll verify the install worked, sort out which modules behave on Linux, and write a script that runs identically on Windows and Ubuntu. No if $OS -eq "Windows" hacks held together with duct tape.

What is PowerShell 7?

PowerShell 7 (still commonly called “PowerShell Core” from its early cross-platform days) is Microsoft’s open-source, cross-platform shell and scripting language. Windows PowerShell 5.1 is stuck on Windows, full stop. PowerShell 7 runs natively on Windows, macOS, and Linux distributions including Ubuntu. It uses the same pwsh executable and the same core cmdlet set everywhere.

That’s the real difference from 5.1, a legacy Windows-only edition stuck in maintenance mode. PowerShell 7 is the actively developed successor, built on .NET. It’s what Microsoft ships new features to now. It’s free and open-source under the MIT license, so there’s no licensing cost on Ubuntu, Windows, or macOS. Most modules on the PowerShell Gallery are free to install too, though some publisher-specific modules carry their own licensing or support terms, so check a module’s page before you build automation around it.

For sysadmins running mixed environments, this matters in a concrete way. Azure PowerShell modules like Az work fine on Linux — it’s REST-based with no Windows dependency. Not every Microsoft 365 admin module has the same Linux parity, so check a module’s compatibility notes before scripting against one you haven’t run on Ubuntu before. Still, for the modules that do work, you can manage cloud resources from an Ubuntu jump box instead of RDPing into a Windows management VM just to run a script. Homelab users get the same payoff at smaller scale: one scripting language across Windows and Linux VMs instead of two.

Before You Begin

Make sure you have:

  • Ubuntu 24.04 LTS (Noble) on an x64 PC for this walkthrough
  • sudo or root access on the machine
  • Internet access to reach packages.microsoft.com
  • A terminal session (local, SSH, or console)
  • Basic familiarity with apt package management
RequirementDetails
OS versionUbuntu 24.04 LTS on x64 hardware
Disk space~300 MB for PowerShell and dependencies
Privilegessudo access required for repo setup and install
NetworkOutbound HTTPS access to packages.microsoft.com

The walkthrough targets PowerShell 7.6 on Ubuntu 24.04 LTS, using the x64 (amd64) repository. Check Microsoft’s support matrix before choosing a different Ubuntu or PowerShell release.

Step-by-Step Guide

Step 1: Update Ubuntu and install prerequisites

Refresh your package lists and pull in the tools needed to add a signed third-party repository: wget, curl, gpg, and apt-transport-https.

if sudo apt update; then
  sudo apt upgrade -y
fi
sudo apt install -y wget apt-transport-https software-properties-common curl gpg

Expected output ends with something like:

0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

If packages were missing, apt shows them downloading and unpacking instead. That’s normal on a fresh install. Don’t panic about it.

Step 2: Add Microsoft’s GPG signing key

Ubuntu needs to verify that the PowerShell package actually came from Microsoft and wasn’t tampered with in transit. Download Microsoft’s public signing key and store it in the modern keyring format. Skip the deprecated apt-key method; Ubuntu has phased it out.

curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor -o /usr/share/keyrings/microsoft-archive-keyring.gpg

Note: Microsoft’s current Ubuntu install docs primarily recommend bootstrapping via the packages-microsoft-prod.deb package, which registers both the repository and the signing key automatically in one step. The manual curl/gpg –dearmor approach shown here is a valid, transparent alternative that produces the same signed-repository result, but it isn’t the method Microsoft’s official docs lead with.

There’s no output on success; the command just returns to a prompt. You can confirm the file exists:

ls -l /usr/share/keyrings/microsoft-archive-keyring.gpg

-rw-r–r– 1 root root 3122 Aug 26 09:14 /usr/share/keyrings/microsoft-archive-keyring.gpg

Step 3: Add the Microsoft APT repository

Register Microsoft’s package repository for your specific Ubuntu release. This example uses 24.04 (“noble”); swap the path for 22.04 if you’re on Jammy.

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/ubuntu/24.04/prod noble main" | sudo tee /etc/apt/sources.list.d/microsoft.list

deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/ubuntu/24.04/prod noble main

The signed-by= flag ties this repo entry to the specific key you just imported, instead of trusting every key in the system keyring. That’s current best practice. It’s also what saves you from the “apt-key deprecated” warnings you’ll still see in older tutorials.

Ubuntu GNOME Terminal teaching example. Only command: curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor -o /usr/share/keyrings/microsoft-archive-keyring.gpg
Then a fresh shell prompt with no output. No deb command or repository line. Use Ubuntu terminal styling with this supplied buffer text. If reference search cannot supply a suitable image, use the deployed detailed text-only fallback; the image still requires visual approval.

Step 4: Install PowerShell

Refresh the package index so apt picks up the new repository, then install the powershell package.

sudo apt update
sudo apt install -y powershell

Apt reads Microsoft’s repository and downloads powershell. The following output is illustrative; package size and patch version vary:

Get:1 https://packages.microsoft.com/ubuntu/24.04/prod noble/main amd64 powershell amd64 7.6.6-1.deb_amd64 [140 MB]

Setting up powershell (7.6.6-1.deb_amd64) …

Terminal output showing apt update followed by apt install -y powershell completing successfully with the Setting up powershell confirmation line

Step 5: Launch and verify

Start PowerShell with the pwsh command.

pwsh

Your prompt changes to indicate you’re now inside the PowerShell environment:

PowerShell 7.6.6
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type ‘help’ to get help.

PS /home/akishore>

Terminal showing the pwsh prompt (PS /home/username>) after launching PowerShell for the first time on Ubuntu

Step 6: Confirm the version and OS details

Inside the pwsh session, check $PSVersionTable to confirm the exact version and platform.

$PSVersionTable

Name Value
—- —–
PSVersion 7.6.6
PSEdition Core
GitCommitId 7.6.6
OS Linux 6.8.0-40-generic #40-Ubuntu SMP
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}

The OS and Platform fields are your quick check. They confirm you’re running the actual Linux build, not a Windows binary someone copied over by mistake. This is your verification step. If $PSVersionTable returns this table with PSEdition: Core, the install worked.

PowerShell terminal output showing $PSVersionTable results with PSVersion, PSEdition, OS, and Platform fields visible

Installing on Windows and macOS

Since you’re probably managing both platforms, here’s the short version for the other two.

Windows

Open an elevated terminal (PowerShell or Command Prompt as Administrator) and use winget:

winget install --id Microsoft.PowerShell --source winget

This installs alongside the built-in Windows PowerShell 5.1. You’ll see a separate PowerShell 7 shortcut in the Start menu. Launch it and confirm with $PSVersionTable.PSVersion, same as on Ubuntu. If you’d rather not use winget, grab the .msi installer directly from the PowerShell GitHub releases page. Run through the setup wizard with default options.

Windows Terminal showing winget install --id Microsoft.PowerShell command completing and the PowerShell 7 version output from $PSVersionTable.PSVersion

macOS

Install via Homebrew (assuming Homebrew is already set up):

brew install --cask powershell

Then launch and verify:

pwsh
$PSVersionTable.PSVersion
macOS Terminal showing brew install --cask powershell completing, followed by pwsh launching and $PSVersionTable.PSVersion output

Configuration: Modules and PSModulePath on Linux

This is where PowerShell on Ubuntu starts to diverge from the Windows experience. Understand this before you write scripts you’ll regret later.

Where modules live on Linux

PowerShell searches the $PSModulePath environment variable for installed modules. Same concept as Windows, different paths. Check yours:

$env:PSModulePath -split ':'

/home/akishore/.local/share/powershell/Modules
/usr/local/share/powershell/Modules
/opt/microsoft/powershell/7/Modules

  • ~/.local/share/powershell/Modules: user-scoped modules, no sudo needed
  • /usr/local/share/powershell/Modules: machine-wide, shared across all users
  • /opt/microsoft/powershell/7/Modules: built-in modules shipped with PowerShell itself; don’t touch this one

Installing modules

Use Install-Module with -Scope CurrentUser to avoid needing sudo for every module install:

Install-Module -Name PSScriptAnalyzer -Scope CurrentUser -Force

Untrusted repository
You are installing the modules from an untrusted repository…
Are you sure you want to install the modules from ‘PSGallery’?
[Y] Yes [A] Yes to All [N] No [L] No [S] Suspend [?] Help (default is “N”): A

An untrusted-repository confirmation can appear when the repository is not trusted and you omit -Force. The command above includes -Force, so it normally suppresses that confirmation. You can pre-trust it if you want a scripted, unattended install:

Set-PSRepository -Name PSGallery -InstallationPolicy Trusted

To see what’s already installed:

Get-Module -ListAvailable

Directory: /home/akishore/.local/share/powershell/Modules

ModuleType Version Name ExportedCommands
———- ——- —- —————-
Script 1.22.0 PSScriptAnalyzer {Get-Setting, Invoke-Formatter…}
Manifest 7.0.0 Microsoft.PowerShell.Management {Add-Content…}

Ubuntu GNOME Terminal with PowerShell prompt PS /home/user> and typed command Install-Module -Name ThreadJob -Scope CurrentUser -Force
Show no confirmation prompt because Force suppresses it. This is supplied illustrative buffer text in a real Ubuntu terminal layout. If reference search cannot supply a suitable image, use the deployed detailed text-only fallback; the image still requires visual approval.

Modules that actually work on Linux

ModuleWorks on Ubuntu?Notes
PSScriptAnalyzerYesLinting/static analysis, fully cross-platform
Az (Azure PowerShell)YesREST-based, no Windows dependency
PesterYesTesting framework, cross-platform by design
Microsoft.PowerShell.SecretManagementYesCross-platform credential storage
PowerShellGetYesBuilt in, manages other modules
ActiveDirectoryNoDepends on Windows-only LDAP/AD binaries
PSReadLinePartialShips and works, but some Windows key-binding defaults differ
WebAdministration (IIS)NoIIS doesn’t exist on Linux

Before adding a module to a shared script, check its documentation page on the PowerShell Gallery for a “Linux compatible” note, or just test it. If it depends on the Windows registry, WMI, or COM, it’ll either fail to import or throw errors the moment you call a cmdlet.

What Doesn’t Work: Windows-Only Cmdlets on Ubuntu

This is the part that trips up people coming from a Windows-only background. PowerShell 7 ships the same engine everywhere. But plenty of cmdlets are thin wrappers around Windows-specific subsystems that simply don’t exist on Linux:

  • Registry cmdlets (Get-ItemProperty -Path HKLM:\...): there’s no Windows registry on Ubuntu, so registry-drive paths fail
  • Active Directory module (Get-ADUser, New-ADGroup): depends on Windows AD DS binaries
  • Windows management commands: Get-WmiObject belongs to Windows PowerShell 5.1 and is absent from PowerShell 7 on every platform. Do not assume Windows CIM classes or management modules are available on Linux.
  • COM automation (New-Object -ComObject Excel.Application): COM is a Windows-only technology
  • IIS management (WebAdministration module): IIS is Windows-only
  • Classic GUI-dependent modules: anything that pops a Windows Forms dialog

If you run one of these on Ubuntu, you’ll typically get an error like:

New-Object: Cannot find type [System.__ComObject]: verify that the assembly containing this type is loaded.

or, for registry access:

Get-ItemProperty: Cannot find drive. A drive with the name ‘HKLM’ does not exist.

Don’t waste time hunting for a Linux equivalent cmdlet; there usually isn’t one. Branch your script logic instead, so Windows-only code only runs on Windows.

Practical Example: A Script That Runs on Both Windows and Ubuntu

Here’s a script that checks disk space and writes a log entry, using the same logic on both platforms. PowerShell exposes three built-in boolean variables, $IsWindows, $IsLinux, $IsMacOS, made for exactly this purpose.

# disk-check.ps1
# Runs identically on Windows PowerShell 7+ and PowerShell 7 on Ubuntu

$logDir = if ($IsWindows) {
    "C:\Logs\DiskChecks"
} else {
    Join-Path $HOME "logs/disk-checks"
}

# Join-Path builds the correct separator for whichever OS runs this script
if (-not (Test-Path $logDir)) {
    New-Item -ItemType Directory -Path $logDir -Force | Out-Null
}

$logFile = Join-Path $logDir "disk-check-$(Get-Date -Format 'yyyy-MM-dd').log"

if ($IsWindows) {
    $volumes = Get-Volume | Where-Object { $_.DriveLetter } |
        Select-Object DriveLetter, @{N='FreeGB';E={[math]::Round($_.SizeRemaining/1GB,2)}}
} else {
    # Linux: parse df output instead of relying on Get-Volume, which is Windows-only
    $dfOutput = df -B1 --output=target,avail | Select-Object -Skip 1
    $volumes = $dfOutput | ForEach-Object {
        $parts = ($_ -split '\s+').Where({ $_ -ne '' })
        [PSCustomObject]@{
            Mount  = $parts[0]
            FreeGB = [math]::Round([long]$parts[1] / 1GB, 2)
        }
    }
}

$volumes | ForEach-Object {
    "$(Get-Date -Format o)  $_" | Add-Content -Path $logFile
}

Write-Output "Checked $($volumes.Count) volume(s). Log written to $logFile"

Run it the same way on both systems:

pwsh ./disk-check.ps1

Checked 4 volume(s). Log written to /home/akishore/logs/disk-checks/disk-check-2026-08-26.log

Notice the pattern: $IsWindows/$IsLinux handle branching, Join-Path handles path separators, and the Windows-only cmdlet (Get-Volume) only runs inside the if ($IsWindows) block. The script never even attempts to call it on Ubuntu, so there’s nothing to crash.

Terminal showing execution of the disk-check.ps1 script on Ubuntu via pwsh, with the final Write-Output confirmation line visible

Updating and Uninstalling PowerShell on Ubuntu

Updating

Because you installed through Microsoft’s apt repository, updates flow through normal apt commands. No separate updater, no manual download.

sudo apt update
sudo apt upgrade powershell -y

To check your current version without launching a full session:

pwsh --version

PowerShell 7.6.6

Uninstalling

Warning: This removes the powershell package and its files. Any scripts stored elsewhere on disk are untouched. Locally installed modules under ~/.local/share/powershell/Modules will remain. Remove that directory separately if you want a completely clean slate.

sudo apt remove powershell -y

To also remove Microsoft’s repository entry and signing key:

sudo rm /etc/apt/sources.list.d/microsoft.list
sudo rm /usr/share/keyrings/microsoft-archive-keyring.gpg
sudo apt update

Tips and Troubleshooting

sudo apt install powershell fails or can’t find the package

Why it happens: Either the Microsoft repository wasn’t added correctly, or you followed an older guide that used the deprecated apt-key add method instead of the current keyring + signed-by approach.

Fix: Re-run Steps 2 and 3 exactly. Re-import the key with gpg --dearmor into /usr/share/keyrings/. Make sure the signed-by= path in /etc/apt/sources.list.d/microsoft.list matches the keyring file. Then run sudo apt update again before retrying the install.

pwsh: command not found after installation

Why it happens: The install didn’t finish successfully. Or PowerShell was installed manually (for example, from a tarball) without a symlink into your PATH.

Fix: Check with which pwsh. If nothing returns, reinstall with sudo apt install -y powershell, or manually symlink it if you used the /opt tarball method:

sudo ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh

A script that works on Windows breaks on Ubuntu with file path errors

Why it happens: Hardcoded Windows-style paths like C:\logs\output.txt don’t translate. The backslash gets treated as a literal filename character on Linux, not a path separator.

Fix: Replace hardcoded paths with Join-Path or [IO.Path]::Combine(), as shown in the example script above. PowerShell then builds the correct separator for whichever OS runs the script.

A .ps1 script fails on Ubuntu with “No such file or directory” even though the file exists

Why it happens: The script has Windows-style CRLF line endings. This breaks the shebang line (#!/usr/bin/env pwsh) because the interpreter path ends up with a trailing carriage-return character the shell can’t resolve.

Fix: Convert to Unix LF line endings before running on Linux:

sed -i 's/\r//' script.ps1

Or configure your editor (VS Code, for example) to save PowerShell files with LF line endings by default.

Dependency errors when installing a downloaded .deb package directly

Why it happens: dpkg -i doesn’t resolve dependencies automatically the way apt does.

Fix: After sudo dpkg -i powershell_*.deb, run:

sudo apt-get install -f

This pulls in any missing dependencies and finishes the install cleanly.

Wrapping Up

You’ve got PowerShell 7 running natively on Ubuntu, verified with $PSVersionTable. Regular apt upgrade cycles keep it patched. The real payoff is the $IsWindows/$IsLinux branching habit and the module discipline that comes with it. Build that once, and most of your automation scripts stop caring which OS they land on.

PowerShell on Ubuntu earns its keep on mixed-environment admin work: Azure and M365 scripting, cross-platform CI pipelines, shared tooling between Windows Server and Linux fleets. For a pure Linux job, native Bash is still faster to write and lighter to run. Don’t reach for PowerShell to replace a five-line shell script just because you can.

StepActionApplies To
1-3Add Microsoft’s GPG key and apt repositoryUbuntu 22.04/24.04
4-6Install via apt, launch pwsh, verify with $PSVersionTableUbuntu
Install via wingetWindows
Install via Homebrew caskmacOS
ConfigSet PSModulePath, install modules with -Scope CurrentUserUbuntu
Ongoingsudo apt upgrade powershellUbuntu

Resources