CMD vs PowerShell vs Bash — Comandi equivalenti

La stessa operazione nel Prompt dei comandi, in PowerShell e in bash, fianco a fianco: file, grep, variabili d'ambiente, processi, rete, servizi e scripting.

CMD vs PowerShell vs Bash · freetoolsforweb.com/tools/cmd-vs-powershell-vs-bash · verificato il 2026-10-18

Ultima verifica: 2026-10-18 su il riferimento di Microsoft Learn per PowerShell 7.6 e Windows PowerShell 5.1, il riferimento dei comandi di Windows e il manuale di GNU Bash 5.2.

107 attività in 9 gruppi, più note su alias, virgolette e criteri

File e cartelle

AttivitàCMD (Prompt dei comandi)PowerShellBash (Linux/macOS)
Elencare i file #
Alias di PowerShell: gci, dir e, su Windows, ls.
dir
Get-ChildItem
ls -l
Elencare anche i file nascosti #
dir /a
Get-ChildItem -Force
ls -la
Elencare tutti i file in modo ricorsivo #
dir /s /b
Get-ChildItem -Recurse -File
find . -type f
Mostrare la directory corrente #
In CMD, cd senza argomenti stampa la directory corrente. Alias di PowerShell: pwd, gl; c'è anche la variabile $PWD.
cd
Get-Location
pwd
Cambiare directory #
In CMD serve /d per cambiare anche unità oltre alla cartella. Alias di PowerShell: cd, sl, chdir.
cd /d D:\work
Set-Location D:\work
cd /home/me/work
Andare alla directory home #
cd %USERPROFILE%
Set-Location ~
cd ~
Creare una cartella (con le cartelle padre) #
In CMD mkdir crea le cartelle intermedie quando le estensioni dei comandi sono attive (impostazione predefinita). In PowerShell, mkdir è una funzione che richiama New-Item -ItemType Directory.
mkdir a\b\c
New-Item -ItemType Directory -Path a\b\c
mkdir -p a/b/c
Creare un file vuoto #
type nul > file.txt
New-Item file.txt
touch file.txt
Copiare un file #
copy src.txt dst.txt
Copy-Item src.txt dst.txt
cp src.txt dst.txt
Copiare una cartella in modo ricorsivo #
Funziona anche xcopy src dst /E /I; robocopy è lo strumento supportato e può riprendere e ritentare.
robocopy src dst /E
Copy-Item src dst -Recurse
cp -r src dst
Creare una copia speculare esatta di una cartella Pericoloso #
Attenzione: Entrambi eliminano dalla destinazione i file che non sono nell'origine. Se inverti i due percorsi, cancelli la cartella che volevi conservare. robocopy /L e rsync -n fanno una prova a vuoto.
robocopy src dst /MIR
(no cmdlet; call robocopy)
rsync -a --delete src/ dst/
Spostare un file #
move a.txt archive\
Move-Item a.txt archive\
mv a.txt archive/
Rinominare un file #
ren old.txt new.txt
Rename-Item old.txt new.txt
mv old.txt new.txt
Eliminare un file #
del file.txt
Remove-Item file.txt
rm file.txt
Eliminare una cartella e il suo contenuto Pericoloso #
Attenzione: Niente Cestino e nessuna conferma con /q, -Force o -f. Controlla prima il percorso; in PowerShell aggiungi -WhatIf per vedere cosa verrebbe rimosso.
rmdir /s /q folder
Remove-Item folder -Recurse -Force
rm -rf folder
Modificare i permessi dei file #
Windows usa le ACL, non i bit rwx; icacls di solito è più semplice di Set-Acl.
icacls file.txt /grant alice:F
Get-Acl / Set-Acl
chmod 644 file.txt
Checksum di un file (SHA-256) #
Get-FileHash usa SHA256 per impostazione predefinita; -Algorithm MD5 o SHA1 per gli altri. macOS: shasum -a 256.
certutil -hashfile file.iso SHA256
Get-FileHash file.iso
sha256sum file.iso
Creare un file zip #
tar.exe (bsdtar) è incluso in Windows 10 1803 e successivi; -a sceglie il formato dall'estensione .zip.
tar -a -c -f out.zip folder
Compress-Archive -Path folder -DestinationPath out.zip
zip -r out.zip folder
Estrarre un file zip #
tar -xf out.zip
Expand-Archive out.zip -DestinationPath dest
unzip out.zip -d dest

Leggere e scrivere il contenuto dei file

AttivitàCMD (Prompt dei comandi)PowerShellBash (Linux/macOS)
Stampare un file #
Alias di PowerShell: gc, type e, su Windows, cat.
type file.txt
Get-Content file.txt
cat file.txt
Scorrere un file pagina per pagina #
more file.txt
Get-Content file.txt | Out-Host -Paging
less file.txt
Ultime 10 righe #Nessun comando integrato
Get-Content file.txt -Tail 10
tail -n 10 file.txt
Seguire un file di log #Nessun comando integrato
Get-Content app.log -Tail 10 -Wait
tail -f app.log
Scrivere testo in un file (sovrascrivendo) #
In CMD, uno spazio prima di > finisce nel file. In Windows PowerShell 5.1, > scrive in UTF-16 LE; PowerShell 7 scrive in UTF-8 senza BOM. Set-Content -Encoding utf8 è esplicito in entrambi.
echo hello> file.txt
'hello' | Set-Content file.txt
echo hello > file.txt
Aggiungere testo in fondo a un file #
echo hello>> file.txt
Add-Content file.txt 'hello'
echo hello >> file.txt
Contare le righe #
find /c /v "" file.txt
(Get-Content file.txt).Count
wc -l file.txt
Confrontare due file #
In PowerShell su Windows, diff è un alias di Compare-Object, non un diff testuale.
fc a.txt b.txt
Compare-Object (Get-Content a.txt) (Get-Content b.txt)
diff a.txt b.txt
Ordinare le righe #
sort file.txt
Get-Content file.txt | Sort-Object
sort file.txt
Righe univoche #Nessun comando integrato
Get-Content file.txt | Sort-Object -Unique
sort -u file.txt
Sostituire testo in un file #
-replace usa le espressioni regolari; le parentesi leggono l'intero file prima che Set-Content lo riapra. Su macOS sed richiede -i ''.
Nessun comando integrato
(Get-Content f.txt) -replace 'old','new' | Set-Content f.txt
sed -i 's/old/new/g' f.txt

Variabili d'ambiente

AttivitàCMD (Prompt dei comandi)PowerShellBash (Linux/macOS)
Elencare tutte le variabili #
set
Get-ChildItem Env:
env
Leggere una variabile #
echo %PATH%
$env:PATH
echo "$PATH"
Impostare per questa sessione #
CMD: niente spazi attorno a =, altrimenti diventano parte del nome e del valore.
set MY_VAR=hello
$env:MY_VAR = 'hello'
export MY_VAR=hello
Impostare in modo permanente (per il tuo utente) #
setx e SetEnvironmentVariable valgono solo per le nuove finestre, non per quella corrente. setx tronca i valori più lunghi di 1024 caratteri, quindi non usarlo per modificare PATH.
setx MY_VAR hello
[Environment]::SetEnvironmentVariable('MY_VAR','hello','User')
echo 'export MY_VAR=hello' >> ~/.bashrc
Rimuovere una variabile #
set MY_VAR=
Remove-Item Env:MY_VAR
unset MY_VAR
Aggiungere una cartella al PATH (sessione) #
PowerShell 7 su Linux/macOS separa il PATH con : invece di ;. [IO.Path]::PathSeparator restituisce quello giusto.
set PATH=%PATH%;C:\tools
$env:PATH += ';C:\tools'
export PATH="$PATH:/opt/tools"
Impostare solo per un comando #Nessun comando integrato
$env:DEBUG = '1'; ./app; Remove-Item Env:DEBUG
DEBUG=1 ./app

Processi

AttivitàCMD (Prompt dei comandi)PowerShellBash (Linux/macOS)
Elencare i processi #
tasklist
Get-Process
ps aux
Trovare un processo per nome #
tasklist /FI "IMAGENAME eq chrome.exe"
Get-Process chrome
pgrep -a chrome
Terminare per ID di processo #
Senza /F o -Force, Windows chiede al processo di chiudersi. kill invia SIGTERM; kill -9 forza la chiusura.
taskkill /PID 1234 /F
Stop-Process -Id 1234 -Force
kill 1234
Terminare per nome #
taskkill /IM notepad.exe /F
Stop-Process -Name notepad
pkill notepad
Avviare un programma #
Le virgolette vuote "" in start sono il titolo della finestra; senza di esse, il percorso di un programma tra virgolette viene preso come titolo.
start "" notepad.exe
Start-Process notepad
gedit &
Eseguire con privilegi elevati (come admin/root) #
Usa powershell invece di pwsh per Windows PowerShell 5.1. Windows 11 24H2 e successivi possono anche abilitare un comando sudo integrato nelle Impostazioni.
runas /user:Administrator cmd
Start-Process pwsh -Verb RunAs
sudo command
I 10 processi che usano più CPU #
La CPU in Get-Process è il totale dei secondi di processore dall'avvio, non la % attuale.
Nessun comando integrato
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
ps aux --sort=-%cpu | head
Cosa sta usando una porta #
Get-NetTCPConnection è solo per Windows. L'ultima colonna di netstat -ano è il PID: cercalo con tasklist /FI "PID eq 1234".
netstat -ano | findstr :8080
Get-NetTCPConnection -LocalPort 8080
sudo ss -ltnp | grep :8080

Rete

AttivitàCMD (Prompt dei comandi)PowerShellBash (Linux/macOS)
Mostrare gli indirizzi IP #
Get-NetIPAddress e gli altri cmdlet Net* sono solo per Windows (modulo NetTCPIP).
ipconfig /all
Get-NetIPAddress
ip addr
Fare il ping di un host #
Su Windows ping si ferma dopo 4 tentativi per impostazione predefinita; su Linux continua finché non premi Ctrl+C.
ping -n 4 example.com
Test-Connection example.com -Count 4
ping -c 4 example.com
Testare una porta TCP #
Test-NetConnection è solo per Windows. In PowerShell 7: Test-Connection example.com -TcpPort 443.
Nessun comando integrato
Test-NetConnection example.com -Port 443
nc -zv example.com 443
Ricerca DNS #
Resolve-DnsName è solo per Windows; nslookup esiste su tutti e tre.
nslookup example.com
Resolve-DnsName example.com
dig example.com
Tracciare il percorso #
tracert example.com
Test-NetConnection example.com -TraceRoute
traceroute example.com
Svuotare la cache DNS #
La riga bash vale per i sistemi con systemd-resolved.
ipconfig /flushdns
Clear-DnsClientCache
sudo resolvectl flush-caches
HTTP GET (chiamata API) #
Invoke-RestMethod converte il JSON in oggetti; Invoke-WebRequest restituisce stato, intestazioni e contenuto grezzo.
curl.exe https://api.example.com/items
Invoke-RestMethod https://api.example.com/items
curl https://api.example.com/items
Scaricare un file #
curl.exe è incluso in Windows 10 1803 e successivi. In Windows PowerShell 5.1, aggiungi -UseBasicParsing a Invoke-WebRequest sui computer in cui Internet Explorer non è configurato.
curl.exe -L -o file.zip https://example.com/file.zip
Invoke-WebRequest https://example.com/file.zip -OutFile file.zip
curl -LO https://example.com/file.zip
POST di JSON #
CMD non ha le virgolette singole, quindi per curl.exe le virgolette doppie interne vanno precedute da una barra rovesciata.
curl.exe -X POST -H "Content-Type: application/json" -d "{\"a\":1}" https://api.example.com
Invoke-RestMethod https://api.example.com -Method Post -ContentType 'application/json' -Body (@{a=1} | ConvertTo-Json)
curl -X POST -H 'Content-Type: application/json' -d '{"a":1}' https://api.example.com
Connettersi a un server via SSH #
Il client OpenSSH è installato per impostazione predefinita su Windows 10 1809+ e Windows 11.
ssh user@host
ssh user@host
ssh user@host

Servizi e sistema

AttivitàCMD (Prompt dei comandi)PowerShellBash (Linux/macOS)
Elencare i servizi #
In Windows PowerShell 5.1, sc è un alias di Set-Content: lì digita sc.exe. PowerShell 6+ ha rimosso quell'alias.
sc query
Get-Service
systemctl list-units --type=service
Stato di un servizio #
sc query Spooler
Get-Service Spooler
systemctl status nginx
Avviare / arrestare un servizio #
net start Spooler net stop Spooler
Start-Service Spooler Stop-Service Spooler
sudo systemctl start nginx sudo systemctl stop nginx
Riavviare un servizio #
net stop Spooler && net start Spooler
Restart-Service Spooler
sudo systemctl restart nginx
Avvio automatico all'accensione #
sc.exe richiede lo spazio dopo start= e nessuno spazio prima.
sc config Spooler start= auto
Set-Service Spooler -StartupType Automatic
sudo systemctl enable nginx
Informazioni su sistema operativo e hardware #
systeminfo
Get-ComputerInfo
uname -a; cat /etc/os-release
Nome del computer #
hostname
$env:COMPUTERNAME
hostname
Utente corrente #
In PowerShell su Windows c'è anche $env:USERNAME.
whoami
whoami
whoami
Spazio libero su disco #
Le versioni meno recenti di Windows richiedono un prompt con privilegi elevati per fsutil. Get-Volume (solo Windows) mostra anche dimensione e spazio libero.
fsutil volume diskfree C:
Get-PSDrive -PSProvider FileSystem
df -h
Tempo di attività #
Get-Uptime è disponibile da PowerShell 6+. Nella 5.1: (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime.
systeminfo | find "Boot Time"
Get-Uptime
uptime
Riavviare subito #
shutdown /r /t 0
Restart-Computer
sudo reboot
Pulire lo schermo #
In PowerShell su Windows funzionano sia cls sia clear.
cls
Clear-Host
clear
Cronologia dei comandi #
Get-History copre solo questa sessione. PSReadLine conserva la cronologia precedente nel file indicato da (Get-PSReadLineOption).HistorySavePath; Ctrl+R la cerca in tutte e tre le shell.
doskey /history
Get-History
history
Guida di un comando #
Esegui Update-Help una volta (con privilegi elevati nella 5.1) per scaricare la guida completa di PowerShell.
dir /?
Get-Help Get-ChildItem -Examples
man ls
Data corrente #
%date% segue il formato regionale del computer, quindi gli script che lo analizzano non funzionano con impostazioni internazionali diverse.
echo %date%
Get-Date -Format 'yyyy-MM-dd'
date +%F
Attendere 5 secondi #
timeout /t 5
Start-Sleep -Seconds 5
sleep 5
Copiare l'output negli appunti #
macOS: pbcopy. Wayland: wl-copy. In PowerShell Get-Clipboard lo rilegge.
dir | clip
Get-ChildItem -Name | Set-Clipboard
ls | xclip -selection clipboard

Pipe di oggetti e pipe di testo

AttivitàCMD (Prompt dei comandi)PowerShellBash (Linux/macOS)
Scegliere colonne / proprietà #
PowerShell passa oggetti .NET nella pipe, quindi scegli le proprietà per nome invece di analizzare le colonne.
Nessun comando integrato
Get-Process | Select-Object Name, Id, WS
ps -eo comm,pid,rss
Filtrare le righe per valore #
PowerShell capisce letterali come 500MB e 1GB. awk confronta la colonna 6 (RSS in KB).
tasklist | findstr chrome
Get-Process | Where-Object WS -gt 500MB
ps aux | awk '$6 > 500000'
Fare qualcosa per ogni elemento #
$_ (o $PSItem) è l'oggetto corrente. In un file .bat scrivi %%f invece di %f.
for %f in (*.txt) do echo %f
Get-ChildItem *.txt | ForEach-Object { $_.Name }
for f in *.txt; do echo "$f"; done
Vedere quali proprietà ha un oggetto #
Il comando di esplorazione più utile di PowerShell; prova anche | Format-List *.
Nessun comando integrato
Get-Process | Get-Member
Nessun comando integrato
Analizzare JSON #
Usa -Raw in modo che il file arrivi come un'unica stringa; ConvertTo-Json -Depth 10 per l'output (la profondità predefinita è 2).
Nessun comando integrato
Get-Content data.json -Raw | ConvertFrom-Json
jq . data.json
Leggere e filtrare un CSV #
I valori di Import-Csv sono stringhe; converti con [int] per i confronti numerici.
Nessun comando integrato
Import-Csv users.csv | Where-Object { [int]$_.Age -gt 30 }
awk -F, 'NR>1 && $3 > 30' users.csv
Esportare in CSV #
-NoTypeInformation è predefinito in PowerShell 6+ ma necessario nella 5.1.
Nessun comando integrato
Get-Process | Export-Csv procs.csv -NoTypeInformation
ps -eo pid,comm --no-headers | awk '{print $1","$2}' > procs.csv
Conteggio, somma, media #
find /c /v "" file.txt
Get-ChildItem -File | Measure-Object Length -Sum -Average
ls -l | awk '{s+=$5} END {print s}'

Scripting: variabili, condizioni, cicli, funzioni

AttivitàCMD (Prompt dei comandi)PowerShellBash (Linux/macOS)
Impostare una variabile #
bash: niente spazi attorno a = (name = Ada esegue un comando chiamato name).
set name=Ada
$name = 'Ada'
name=Ada
Usare una variabile in una stringa #
echo Hello %name%
"Hello $name"
echo "Hello $name"
Aritmetica #
CMD e bash fanno solo calcoli con numeri interi; PowerShell usa i numeri .NET.
set /a n=5*3
$n = 5 * 3
n=$((5 * 3))
Leggere l'input dell'utente #
set /p name=Name:
$name = Read-Host 'Name'
read -rp 'Name: ' name
Argomenti dello script #
Nei file .bat %~1 rimuove le virgolette esterne. Un blocco param() dà agli script PowerShell parametri con nome e tipo.
%1 %2 … %*
$args[0] or param($Path)
$1 $2 … "$@"
If / else su una stringa #
Gli operatori di confronto di PowerShell sono parole: -eq -ne -gt -lt -like -match. = e > sono assegnazione e reindirizzamento.
if "%a%"=="yes" (echo on) else (echo off)
if ($a -eq 'yes') { 'on' } else { 'off' }
if [ "$a" = "yes" ]; then echo on; else echo off; fi
Confrontare numeri #
CMD: EQU NEQ LSS LEQ GTR GEQ.
if %n% GTR 5 echo big
if ($n -gt 5) { 'big' }
if (( n > 5 )); then echo big; fi
Se un file esiste #
if exist file.txt echo yes
if (Test-Path file.txt) { 'yes' }
if [ -f file.txt ]; then echo yes; fi
Codice di uscita dell'ultimo programma #
In PowerShell, $? è $true/$false per l'ultimo comando; $LASTEXITCODE è il codice numerico dell'ultimo programma nativo.
echo %ERRORLEVEL%
$LASTEXITCODE
echo $?
Eseguire il comando successivo solo in caso di successo / errore #
Gli operatori di concatenazione && e || sono arrivati in PowerShell 7.0; Windows PowerShell 5.1 li rifiuta.
build && deploy build || echo failed
build && deploy (PowerShell 7+) build; if ($?) { deploy } (5.1)
build && deploy build || echo failed
Ciclo su un elenco #
for %i in (a b c) do echo %i
foreach ($x in 'a','b','c') { $x }
for x in a b c; do echo "$x"; done
Ciclo da 1 a 5 #
for /l %i in (1,1,5) do echo %i
foreach ($i in 1..5) { $i }
for i in {1..5}; do echo "$i"; done
Ciclo sulle righe di un file #
for /f "usebackq delims=" %l in ("file.txt") do echo %l
foreach ($line in Get-Content file.txt) { $line }
while IFS= read -r line; do echo "$line"; done < file.txt
Ciclo while #
CMD non ha while; in un file .bat usa goto con un'etichetta.
:loop set /a i+=1 if %i% lss 5 goto loop
while ($i -lt 5) { $i++ }
while [ "$i" -lt 5 ]; do i=$((i+1)); done
Definire e chiamare una funzione #
Le funzioni PowerShell si chiamano come comandi: Greet Ada, non Greet("Ada").
call :greet Ada goto :eof :greet echo Hello %~1 exit /b
function Greet($Name) { "Hello $Name" } Greet Ada
greet() { echo "Hello $1"; } greet Ada
Salvare l'output di un comando in una variabile #
for /f "delims=" %i in ('hostname') do set h=%i
$h = hostname
h=$(hostname)
Scartare l'output #
command >nul 2>&1
command *> $null
command >/dev/null 2>&1
Commento #
rem comment :: comment
# comment <# block #>
# comment
File di script e come eseguirlo #
PowerShell non esegue script dalla cartella corrente senza .\ e potrebbe bloccarli del tutto: vedi i criteri di esecuzione più sotto.
script.bat
.\script.ps1
chmod +x script.sh && ./script.sh

Insidie degli alias di PowerShell: ls, curl, wget, sc, where

PowerShell include alias che sembrano comandi Unix o CMD ma eseguono cmdlet con parametri diversi. Quali esistano dipende dall'edizione e dal sistema operativo. Get-Alias name mostra a cosa punta un nome nella tua sessione.

DigitiWindows PowerShell 5.1PowerShell 7 su WindowsPowerShell 7 su Linux/macOS
curl
Nella 5.1 digita curl.exe per usare il vero curl. I suoi flag (-X, -H, -d) non significano nulla per Invoke-WebRequest.
Invoke-WebRequestnon è un alias: esegue curl.execurl nativo
wget
Usa Invoke-WebRequest url -OutFile nome, oppure curl.exe -LO url.
Invoke-WebRequestnon è un alias (wget non è presente su Windows per impostazione predefinita)wget nativo, se installato
ls, dir
Flag come ls -la non funzionano su Windows: usa Get-ChildItem -Force.
Get-ChildItemGet-ChildItemls = ls nativo; dir = Get-ChildItem
cat, typeGet-ContentGet-Contentcat = cat nativo; type = Get-Content
cp, mv, rm, rmdir
rm -rf non è PowerShell valido: usa Remove-Item -Recurse -Force.
Copy-Item, Move-Item, Remove-Itemstessi cmdletcomandi nativi
ps, killGet-Process, Stop-Processstessi cmdletcomandi nativi
sort, tee, diff
In PowerShell su Windows, diff a b confronta oggetti, non le righe di due file.
Sort-Object, Tee-Object, Compare-Objectstessi cmdletcomandi nativi
sc
Nella 5.1, sc query scrive un file chiamato query. Usa sc.exe.
Set-Contentnon è un alias: esegue sc.exen/d
where
Usa where.exe per trovare un programma, oppure Get-Command.
Where-ObjectWhere-ObjectWhere-Object
echo
echo -n non elimina il ritorno a capo; usa Write-Host -NoNewline.
Write-OutputWrite-OutputWrite-Output
manhelphelpman nativo

Virgolette ed escape

La maggior parte dei bug del tipo “funziona in una shell, non in un'altra” dipende dalle virgolette. Il carattere di escape è diverso in ogni shell.

CosaCMDPowerShellBash
Stringa letterale (senza espansione)Nessuna virgoletta letterale: %VAR% viene espansa anche dentro "…"'Cost: $5''Cost: $5'
Stringa con variabili"Hello %name%""Hello $name, it is $(Get-Date -Format t)""Hello $name, it is $(date +%R)"
Carattere di escape^ (es. ^& ^| ^>)` backtick (es. `n a capo, `t tabulazione, `$ $ letterale)\ barra rovesciata
Virgolette dentro una stringa tra virgolette"" dentro "…" per molti programmi; dipende dal programma'It''s' or "Say `"hi`""'It'\''s' or "Say \"hi\""
Continuazione di riga^ a fine riga` a fine riga (oppure termina la riga con | )\ a fine riga
% o $ letterale in uno script%% in un file .bat'$' tra virgolette singole oppure `$'$' tra virgolette singole oppure \$
Passare argomenti intatti a un programma nativo(non necessario)--% impedisce a PowerShell di analizzare il resto della riga(non necessario)

Il passaggio delle virgolette ai programmi nativi (curl.exe, git, node) è cambiato in PowerShell 7.3: gli argomenti con virgolette doppie al loro interno ora vengono passati così come sono scritti, comportamento controllato da $PSNativeCommandArgumentPassing. In Windows PowerShell 5.1 lo stesso corpo JSON spesso richiede un doppio escape delle virgolette interne, ed è per questo che molti passano a Invoke-RestMethod con ConvertTo-Json.

Criteri di esecuzione: “l'esecuzione di script è disabilitata nel sistema”

PowerShell si rifiuta di eseguire file .ps1 quando il criterio di esecuzione è Restricted, che è di fatto il valore predefinito di Windows PowerShell nelle edizioni client di Windows (Windows 10 e 11). Windows Server usa per impostazione predefinita RemoteSigned: gli script locali vengono eseguiti, quelli scaricati devono essere firmati o sbloccati. Su Linux e macOS il criterio è Unrestricted e non può essere modificato.

  • Get-ExecutionPolicy -List mostra il criterio per ogni ambito; vince l'ambito definito più specifico (i Criteri di gruppo prevalgono su tutto).
  • Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser consente di eseguire i tuoi script senza diritti di amministratore.
  • Unblock-File .\script.ps1 rimuove il contrassegno “scaricato da Internet” da uno script di cui ti fidi.
  • pwsh -ExecutionPolicy Bypass -File script.ps1 (o powershell per la 5.1) applica un criterio a una sola sessione.

Il criterio di esecuzione è una sicura contro l'esecuzione accidentale di script, non un confine di sicurezza: chiunque può incollare il contenuto dello script nella console.

Windows PowerShell 5.1 e PowerShell 7 a confronto

  • Due programmi: powershell.exe è Windows PowerShell 5.1, integrato in Windows e non più aggiornato con nuove funzionalità. pwsh è PowerShell 7, da installare a parte, multipiattaforma; i due possono convivere.
  • Operatori aggiunti nella 7.0: && e || tra comandi, l'operatore ternario $a ? 'yes' : 'no' e gli operatori di null-coalescing ?? / ??=.
  • Codifica dei file: nella 5.1 > e Out-File scrivono in UTF-16 LE, e Set-Content usa la code page ANSI. PowerShell 7 scrive ovunque in UTF-8 senza BOM, che è ciò che si aspettano Git, gli strumenti Linux e la maggior parte degli editor.
  • Alias: la 7 ha eliminato curl, wget e sc su Windows, e su Linux/macOS lascia ls, cp, rm, cat, ps e altri ai comandi nativi (tabella sopra).
  • Moduli mancanti: i cmdlet solo per Windows come Get-NetIPAddress, Test-NetConnection e Resolve-DnsName funzionano in PowerShell 7 su Windows ma non esistono su Linux o macOS.

Usare bash su Windows: WSL

Il Sottosistema Windows per Linux esegue una vera distribuzione Linux accanto a Windows, quindi ogni comando bash nella colonna di destra funziona così com'è scritto. wsl --install da un prompt con privilegi elevati lo installa con Ubuntu per impostazione predefinita (Windows 10 versione 2004 e successive, e Windows 11); wsl -l -v elenca le distribuzioni installate.

  • Esegui un singolo comando Linux da CMD o PowerShell: wsl ls -la, oppure usa una pipe tra i due: dir | wsl grep txt.
  • Le unità Windows compaiono in Linux sotto /mnt/c; i file Linux sono raggiungibili da Esplora file in \\wsl.localhost\Ubuntu (build meno recenti: \\wsl$\Ubuntu).
  • Tieni i progetti nel file system Linux (~/), non in /mnt/c: l'accesso ai file attraverso il confine è molto più lento.

Per approfondire il lato Linux, consulta la guida rapida ai comandi Linux.

Un riferimento statico che funziona nel browser; le tue ricerche non vengono inviate da nessuna parte. Sfoglia tutti gli strumenti gratuiti.

Hai trovato un problema o qualcosa che potrebbe andare meglio? Leggiamo ogni messaggio e sistemiamo le cose in fretta.

Questa tabella CMD vs PowerShell vs Bash mostra la stessa operazione nel Prompt dei comandi di Windows, in PowerShell e in bash sulla stessa riga: elencare e copiare file, cercare testo nei file (l'equivalente PowerShell di grep è Select-String), variabili d'ambiente, processi, rete, servizi, lettura e scrittura del contenuto dei file e scripting con variabili, condizioni, cicli e funzioni. Cerca un comando di una qualsiasi delle tre shell e ottieni i suoi equivalenti, ciascuno con un pulsante per copiarlo.

La guida copre anche ciò che di solito va storto passando da una shell all'altra: alias di PowerShell che sembrano comandi Unix ma non lo sono (curl e wget in Windows PowerShell 5.1, ls e rm ovunque su Windows), virgolette e caratteri di escape diversi, l'errore della execution policy che blocca gli script .ps1 e le differenze tra Windows PowerShell 5.1 e PowerShell 7. I comandi PowerShell funzionano in entrambe le versioni salvo diversa indicazione in una nota; quando un equivalente CMD non esiste, la tabella lo dice invece di inventarne uno.

Come si usa

  1. Cerca il comando che conosci, in qualsiasi shell (ad esempio “grep”, “findstr” o “Select-String”), oppure l'operazione (“terminare un processo”, “variabile d'ambiente”).
  2. Leggi la riga per trovare l'equivalente nelle altre due shell e fai clic su Copia accanto a quello che ti serve.
  3. Controlla la nota sotto il nome dell'operazione: segnala le differenze di versione (PowerShell 5.1 e 7) e i cmdlet solo per Windows.
  4. Scorri fino alle sezioni su alias, virgolette ed execution policy se un comando si comporta diversamente da come ti aspettavi.
  5. Usa Stampa / Salva come PDF per averne una copia sulla scrivania; la pagina funziona anche su telefono, dove ogni riga diventa una scheda.

Domande frequenti

Qual è l'equivalente PowerShell di grep?

Select-String. Cerca in un file con Select-String -Path app.log -Pattern error, oppure filtra l'output di un comando con ipconfig | Select-String IPv4. Per impostazione predefinita non distingue tra maiuscole e minuscole (aggiungi -CaseSensitive), usa le espressioni regolari .NET e -NotMatch equivale a grep -v. Per le ricerche ricorsive passa Get-ChildItem -Recurse -Filter *.log a Select-String tramite pipe. Il suo alias breve è sls.

Perché curl si comporta in modo strano in PowerShell?

In Windows PowerShell 5.1, curl e wget sono alias di Invoke-WebRequest, quindi opzioni di curl come -X, -H e -d vengono rifiutate o significano altro. Digita curl.exe per eseguire il vero curl incluso in Windows 10 1803 e versioni successive. PowerShell 7 ha rimosso quegli alias, quindi lì curl esegue curl.exe. Su Linux e macOS, curl non è mai stato un alias.

PowerShell è meglio di CMD?

Per qualsiasi cosa che vada oltre l'avvio di un programma o un breve file batch, sì. PowerShell passa tramite pipe oggetti strutturati invece di testo, quindi filtri e ordini per nome di proprietà (Where-Object, Sort-Object) invece di analizzare colonne, e ha vere funzioni, gestione degli errori, supporto per JSON e CSV e accesso remoto. CMD va ancora bene per i vecchi file .bat e alcuni programmi di installazione, e ogni strumento CMD (ipconfig, robocopy, netstat) si può eseguire anche da PowerShell.

Come si risolve “l'esecuzione di script è disabilitata nel sistema”?

È la execution policy, che per impostazione predefinita è Restricted nelle edizioni client di Windows 10 e 11. Esegui Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser in PowerShell (non servono privilegi di amministratore). A quel punto i tuoi script vengono eseguiti, mentre quelli scaricati da internet devono essere firmati o sbloccati con Unblock-File. Get-ExecutionPolicy -List mostra cosa è impostato e dove; un'impostazione di Criteri di gruppo prevale su qualsiasi cosa imposti tu.

Posso eseguire comandi bash su Windows?

Sì, con il Sottosistema Windows per Linux (WSL). Esegui wsl --install da un prompt con privilegi elevati (Windows 10 versione 2004 o successiva, oppure Windows 11) per installare Ubuntu, poi aprilo dal menu Start o esegui singoli comandi da CMD o PowerShell con wsl seguito dal comando, ad esempio wsl grep -rn TODO. Git for Windows include anche Git Bash, una bash più leggera con i comuni strumenti Unix.

Che differenza c'è tra Windows PowerShell e PowerShell 7?

Windows PowerShell 5.1 (powershell.exe) è integrato in Windows e riceve solo correzioni. PowerShell 7 (pwsh) è la versione attuale e multipiattaforma, che gira su Windows, Linux e macOS e si installa a parte; le due possono essere installate insieme. La versione 7 aggiunge && e || tra i comandi, l'operatore ternario e ??, scrive file UTF-8 per impostazione predefinita ed elimina alcuni alias fuorvianti come curl e wget.

Oggetti contro testo: l'idea che ti fa capire PowerShell

In CMD e bash una pipe trasporta testo. Per trovare in bash il processo che usa più memoria devi estrarre la colonna giusta dall'output di ps con sort -k o awk, e il comando si rompe se il layout delle colonne cambia. In PowerShell la pipe trasporta oggetti con proprietà denominate, quindi la stessa operazione è Get-Process | Sort-Object WS -Descending | Select-Object -First 1. Non si analizza nulla, e i nomi delle proprietà sono gli stessi su ogni macchina.

La conseguenza pratica è un modo diverso di esplorare. In bash leggi una pagina man per conoscere il formato dell'output; in PowerShell passi qualsiasi comando a Get-Member per vedere quali proprietà e metodi hanno i suoi oggetti, poi filtri con Where-Object e scegli i campi con Select-Object. Solo quando l'output arriva allo schermo o a un file PowerShell lo trasforma in testo.

I programmi nativi come ipconfig, git o curl.exe producono comunque testo in PowerShell, quindi Select-String e -match funzionano su di essi come farebbe grep. Il loro codice di uscita si trova in $LASTEXITCODE, non in $?.

Tradurre uno script tra le tre shell

La traduzione riga per riga funziona per gli script semplici, ma alcune differenze fregano quasi tutti:

• Operatori di confronto: CMD usa == per le stringhe ed EQU, GTR, LSS per i numeri; PowerShell usa -eq, -gt, -lt, -like e -match (un > da solo è un reindirizzamento); bash usa = dentro [ ] per le stringhe e -gt o (( )) per i numeri.

• Variabili: %name% in CMD (e !name! nei cicli dopo setlocal EnableDelayedExpansion), $name in PowerShell, $name in bash senza spazi attorno a = nell'assegnazione.

• Nei file .bat i cicli raddoppiano il segno di percentuale: for %%f in (*.txt) dentro un file, for %f al prompt.

• Percorsi: su Windows PowerShell accetta sia / sia \; bash su Linux richiede /. Le variabili d'ambiente non distinguono maiuscole e minuscole su Windows, mentre le distinguono su Linux.

• Errori: CMD prosegue dopo un errore a meno che tu non controlli %ERRORLEVEL%; bash prosegue a meno di set -e; PowerShell prosegue dopo gli errori non terminanti a meno di $ErrorActionPreference = 'Stop'.

Quando uno script deve girare su Windows e Linux, PowerShell 7 o bash sotto WSL evitano di dover mantenere due copie.

Strumenti gratuiti correlati

  • Guida rapida ai comandi Linux — Comandi Linux per attività, da file e permessi a rete, systemd ed elaborazione del testo. Ogni voce ha opzioni, esempi da copiare e note per macOS.
  • Scorciatoie da tastiera di Windows — Tutte le scorciatoie di Windows 11 in un unico elenco consultabile e stampabile: tasto Win, Snap, desktop, screenshot, Esplora file.
  • Scorciatoie da tastiera Mac — Tutte le scorciatoie di macOS con i simboli ⌘ ⌥ ⌃ ⇧ spiegati: screenshot, affiancamento delle finestre, Finder, Safari e caratteri speciali.
  • Da curl a codice — Incolla un comando curl, anche da "Copia come cURL" di Chrome, e ottieni la stessa richiesta in Python, JavaScript, Node, Go, PHP, Ruby, Java, C#, wget o HTTPie.
  • Guida rapida Git — Comandi Git organizzati per ciò che vuoi fare: annullare l'ultimo commit, rinominare un branch, eliminare un branch remoto. I moderni switch/restore con gli equivalenti classici e badge di pericolo.