CMD vs PowerShell vs Bash: equivalencias de comandos

La misma tarea en el Símbolo del sistema, PowerShell y bash, lado a lado: archivos, grep, variables de entorno, procesos, red, servicios y scripting.

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

Última verificación: 2026-10-18, verificado con la referencia de PowerShell 7.6 y Windows PowerShell 5.1 de Microsoft Learn, la referencia de comandos de Windows y el manual de GNU Bash 5.2.

107 tareas en 9 grupos, más notas sobre alias, comillas y directivas

Archivos y carpetas

TareaCMD (Símbolo del sistema)PowerShellBash (Linux/macOS)
Listar archivos #
Alias de PowerShell: gci, dir y, en Windows, ls.
dir
Get-ChildItem
ls -l
Listar incluidos los archivos ocultos #
dir /a
Get-ChildItem -Force
ls -la
Listar todos los archivos de forma recursiva #
dir /s /b
Get-ChildItem -Recurse -File
find . -type f
Mostrar el directorio actual #
En CMD, cd sin argumento muestra el directorio actual. Alias de PowerShell: pwd, gl; también la variable $PWD.
cd
Get-Location
pwd
Cambiar de directorio #
CMD necesita /d para cambiar de unidad además de carpeta. Alias de PowerShell: cd, sl, chdir.
cd /d D:\work
Set-Location D:\work
cd /home/me/work
Ir al directorio personal #
cd %USERPROFILE%
Set-Location ~
cd ~
Crear una carpeta (con sus carpetas padre) #
mkdir de CMD crea las carpetas intermedias cuando las extensiones de comandos están activadas (lo predeterminado). En PowerShell, mkdir es una función que envuelve New-Item -ItemType Directory.
mkdir a\b\c
New-Item -ItemType Directory -Path a\b\c
mkdir -p a/b/c
Crear un archivo vacío #
type nul > file.txt
New-Item file.txt
touch file.txt
Copiar un archivo #
copy src.txt dst.txt
Copy-Item src.txt dst.txt
cp src.txt dst.txt
Copiar una carpeta de forma recursiva #
xcopy src dst /E /I también funciona; robocopy es la herramienta con soporte y puede reanudar y reintentar.
robocopy src dst /E
Copy-Item src dst -Recurse
cp -r src dst
Reflejar una carpeta exactamente Peligroso #
Peligro: Ambos eliminan en el destino los archivos que no están en el origen. Si intercambias las dos rutas, borras la carpeta que querías conservar. robocopy /L y rsync -n hacen una simulación.
robocopy src dst /MIR
(no cmdlet; call robocopy)
rsync -a --delete src/ dst/
Mover un archivo #
move a.txt archive\
Move-Item a.txt archive\
mv a.txt archive/
Cambiar el nombre de un archivo #
ren old.txt new.txt
Rename-Item old.txt new.txt
mv old.txt new.txt
Eliminar un archivo #
del file.txt
Remove-Item file.txt
rm file.txt
Eliminar una carpeta y su contenido Peligroso #
Peligro: Sin Papelera de reciclaje ni confirmación con /q, -Force o -f. Comprueba antes la ruta; en PowerShell añade -WhatIf para ver qué se eliminaría.
rmdir /s /q folder
Remove-Item folder -Recurse -Force
rm -rf folder
Cambiar permisos de archivo #
Windows usa ACL, no bits rwx; icacls suele ser más fácil que Set-Acl.
icacls file.txt /grant alice:F
Get-Acl / Set-Acl
chmod 644 file.txt
Suma de comprobación de un archivo (SHA-256) #
Get-FileHash usa SHA256 de forma predeterminada; -Algorithm MD5 o SHA1 para otros. macOS: shasum -a 256.
certutil -hashfile file.iso SHA256
Get-FileHash file.iso
sha256sum file.iso
Crear un archivo zip #
tar.exe (bsdtar) viene con Windows 10 1803 y posteriores; -a elige el formato a partir de la extensión .zip.
tar -a -c -f out.zip folder
Compress-Archive -Path folder -DestinationPath out.zip
zip -r out.zip folder
Extraer un archivo zip #
tar -xf out.zip
Expand-Archive out.zip -DestinationPath dest
unzip out.zip -d dest

Leer y escribir el contenido de archivos

TareaCMD (Símbolo del sistema)PowerShellBash (Linux/macOS)
Mostrar un archivo #
Alias de PowerShell: gc, type y, en Windows, cat.
type file.txt
Get-Content file.txt
cat file.txt
Ver un archivo página a página #
more file.txt
Get-Content file.txt | Out-Host -Paging
less file.txt
Últimas 10 líneas #Sin comando integrado
Get-Content file.txt -Tail 10
tail -n 10 file.txt
Seguir un archivo de registro #Sin comando integrado
Get-Content app.log -Tail 10 -Wait
tail -f app.log
Escribir texto en un archivo (sobrescribir) #
En CMD, un espacio antes de > acaba en el archivo. En Windows PowerShell 5.1, > escribe UTF-16 LE; PowerShell 7 escribe UTF-8 sin BOM. Set-Content -Encoding utf8 es explícito en ambos.
echo hello> file.txt
'hello' | Set-Content file.txt
echo hello > file.txt
Añadir texto al final de un archivo #
echo hello>> file.txt
Add-Content file.txt 'hello'
echo hello >> file.txt
Contar líneas #
find /c /v "" file.txt
(Get-Content file.txt).Count
wc -l file.txt
Comparar dos archivos #
En PowerShell en Windows, diff es un alias de Compare-Object, no un diff de texto.
fc a.txt b.txt
Compare-Object (Get-Content a.txt) (Get-Content b.txt)
diff a.txt b.txt
Ordenar líneas #
sort file.txt
Get-Content file.txt | Sort-Object
sort file.txt
Líneas únicas #Sin comando integrado
Get-Content file.txt | Sort-Object -Unique
sort -u file.txt
Reemplazar texto en un archivo #
-replace usa expresiones regulares; los paréntesis leen todo el archivo antes de que Set-Content lo vuelva a abrir. sed en macOS necesita -i ''.
Sin comando integrado
(Get-Content f.txt) -replace 'old','new' | Set-Content f.txt
sed -i 's/old/new/g' f.txt

Variables de entorno

TareaCMD (Símbolo del sistema)PowerShellBash (Linux/macOS)
Listar todas las variables #
set
Get-ChildItem Env:
env
Leer una variable #
echo %PATH%
$env:PATH
echo "$PATH"
Definir para esta sesión #
CMD: sin espacios alrededor de =, o pasarán a formar parte del nombre y del valor.
set MY_VAR=hello
$env:MY_VAR = 'hello'
export MY_VAR=hello
Definir de forma permanente (para tu usuario) #
setx y SetEnvironmentVariable solo afectan a las ventanas nuevas, no a la actual. setx trunca los valores de más de 1024 caracteres, así que no lo uses para editar PATH.
setx MY_VAR hello
[Environment]::SetEnvironmentVariable('MY_VAR','hello','User')
echo 'export MY_VAR=hello' >> ~/.bashrc
Eliminar una variable #
set MY_VAR=
Remove-Item Env:MY_VAR
unset MY_VAR
Añadir una carpeta a PATH (sesión) #
PowerShell 7 en Linux/macOS separa PATH con : en lugar de ;. [IO.Path]::PathSeparator devuelve el correcto.
set PATH=%PATH%;C:\tools
$env:PATH += ';C:\tools'
export PATH="$PATH:/opt/tools"
Definir solo para un comando #Sin comando integrado
$env:DEBUG = '1'; ./app; Remove-Item Env:DEBUG
DEBUG=1 ./app

Procesos

TareaCMD (Símbolo del sistema)PowerShellBash (Linux/macOS)
Listar procesos #
tasklist
Get-Process
ps aux
Buscar un proceso por nombre #
tasklist /FI "IMAGENAME eq chrome.exe"
Get-Process chrome
pgrep -a chrome
Matar por ID de proceso #
Sin /F ni -Force, Windows pide al proceso que se cierre. kill envía SIGTERM; kill -9 fuerza el cierre.
taskkill /PID 1234 /F
Stop-Process -Id 1234 -Force
kill 1234
Matar por nombre #
taskkill /IM notepad.exe /F
Stop-Process -Name notepad
pkill notepad
Iniciar un programa #
Las comillas vacías "" en start son el título de la ventana; sin ellas, una ruta de programa entre comillas se toma como título.
start "" notepad.exe
Start-Process notepad
gedit &
Ejecutar con privilegios elevados (como admin/root) #
Usa powershell en lugar de pwsh para Windows PowerShell 5.1. Windows 11 24H2 y posteriores también pueden activar un comando sudo integrado en Configuración.
runas /user:Administrator cmd
Start-Process pwsh -Verb RunAs
sudo command
Los 10 procesos que más CPU usan #
CPU en Get-Process es el total de segundos de procesador desde el inicio, no el % actual.
Sin comando integrado
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
ps aux --sort=-%cpu | head
Qué está usando un puerto #
Get-NetTCPConnection es exclusivo de Windows. La última columna de netstat -ano es el PID: búscalo con tasklist /FI "PID eq 1234".
netstat -ano | findstr :8080
Get-NetTCPConnection -LocalPort 8080
sudo ss -ltnp | grep :8080

Red

TareaCMD (Símbolo del sistema)PowerShellBash (Linux/macOS)
Mostrar direcciones IP #
Get-NetIPAddress y los demás cmdlets Net* son exclusivos de Windows (módulo NetTCPIP).
ipconfig /all
Get-NetIPAddress
ip addr
Hacer ping a un host #
El ping de Windows se detiene tras 4 de forma predeterminada; el de Linux sigue hasta Ctrl+C.
ping -n 4 example.com
Test-Connection example.com -Count 4
ping -c 4 example.com
Probar un puerto TCP #
Test-NetConnection es exclusivo de Windows. En PowerShell 7: Test-Connection example.com -TcpPort 443.
Sin comando integrado
Test-NetConnection example.com -Port 443
nc -zv example.com 443
Consulta DNS #
Resolve-DnsName es exclusivo de Windows; nslookup existe en los tres.
nslookup example.com
Resolve-DnsName example.com
dig example.com
Trazar la ruta #
tracert example.com
Test-NetConnection example.com -TraceRoute
traceroute example.com
Vaciar la caché DNS #
La línea de bash se aplica a sistemas con systemd-resolved.
ipconfig /flushdns
Clear-DnsClientCache
sudo resolvectl flush-caches
HTTP GET (llamada a una API) #
Invoke-RestMethod convierte el JSON en objetos; Invoke-WebRequest devuelve el estado, los encabezados y el contenido sin procesar.
curl.exe https://api.example.com/items
Invoke-RestMethod https://api.example.com/items
curl https://api.example.com/items
Descargar un archivo #
curl.exe viene con Windows 10 1803 y posteriores. En Windows PowerShell 5.1, añade -UseBasicParsing a Invoke-WebRequest en equipos sin Internet Explorer configurado.
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
Enviar JSON con POST #
CMD no tiene comillas simples, así que las comillas dobles internas se escapan con barras invertidas para curl.exe.
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
Conectarse por SSH a un servidor #
El cliente OpenSSH viene instalado de forma predeterminada en Windows 10 1809+ y Windows 11.
ssh user@host
ssh user@host
ssh user@host

Servicios y sistema

TareaCMD (Símbolo del sistema)PowerShellBash (Linux/macOS)
Listar servicios #
En Windows PowerShell 5.1, sc es un alias de Set-Content: escribe sc.exe. PowerShell 6+ eliminó ese alias.
sc query
Get-Service
systemctl list-units --type=service
Estado de un servicio #
sc query Spooler
Get-Service Spooler
systemctl status nginx
Iniciar / detener un servicio #
net start Spooler net stop Spooler
Start-Service Spooler Stop-Service Spooler
sudo systemctl start nginx sudo systemctl stop nginx
Reiniciar un servicio #
net stop Spooler && net start Spooler
Restart-Service Spooler
sudo systemctl restart nginx
Iniciar con el sistema #
sc.exe necesita el espacio después de start= y ninguno antes.
sc config Spooler start= auto
Set-Service Spooler -StartupType Automatic
sudo systemctl enable nginx
Información del sistema operativo y del hardware #
systeminfo
Get-ComputerInfo
uname -a; cat /etc/os-release
Nombre del equipo #
hostname
$env:COMPUTERNAME
hostname
Usuario actual #
También $env:USERNAME en PowerShell en Windows.
whoami
whoami
whoami
Espacio libre en disco #
Las versiones antiguas de Windows requieren privilegios elevados para fsutil. Get-Volume (exclusivo de Windows) también muestra el tamaño y el espacio libre.
fsutil volume diskfree C:
Get-PSDrive -PSProvider FileSystem
df -h
Tiempo en funcionamiento #
Get-Uptime es de PowerShell 6+. En 5.1: (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime.
systeminfo | find "Boot Time"
Get-Uptime
uptime
Reiniciar ahora #
shutdown /r /t 0
Restart-Computer
sudo reboot
Borrar la pantalla #
cls y clear funcionan ambos en PowerShell en Windows.
cls
Clear-Host
clear
Historial de comandos #
Get-History solo cubre esta sesión. PSReadLine guarda el historial anterior en el archivo de (Get-PSReadLineOption).HistorySavePath; Ctrl+R lo busca en los tres shells.
doskey /history
Get-History
history
Ayuda de un comando #
Ejecuta Update-Help una vez (con privilegios elevados en 5.1) para descargar la ayuda completa de PowerShell.
dir /?
Get-Help Get-ChildItem -Examples
man ls
Fecha actual #
%date% sigue el formato regional del equipo, así que los scripts que lo analizan fallan con otras configuraciones regionales.
echo %date%
Get-Date -Format 'yyyy-MM-dd'
date +%F
Esperar 5 segundos #
timeout /t 5
Start-Sleep -Seconds 5
sleep 5
Copiar la salida al portapapeles #
macOS: pbcopy. Wayland: wl-copy. Get-Clipboard lo vuelve a leer en PowerShell.
dir | clip
Get-ChildItem -Name | Set-Clipboard
ls | xclip -selection clipboard

Canalizar objetos frente a texto

TareaCMD (Símbolo del sistema)PowerShellBash (Linux/macOS)
Elegir columnas / propiedades #
PowerShell canaliza objetos .NET, así que eliges las propiedades por nombre en lugar de analizar columnas.
Sin comando integrado
Get-Process | Select-Object Name, Id, WS
ps -eo comm,pid,rss
Filtrar filas por un valor #
PowerShell entiende literales como 500MB y 1GB. awk compara la columna 6 (RSS en KB).
tasklist | findstr chrome
Get-Process | Where-Object WS -gt 500MB
ps aux | awk '$6 > 500000'
Hacer algo con cada elemento #
$_ (o $PSItem) es el objeto actual. En un archivo .bat escribe %%f en lugar de %f.
for %f in (*.txt) do echo %f
Get-ChildItem *.txt | ForEach-Object { $_.Name }
for f in *.txt; do echo "$f"; done
Ver qué propiedades tiene un objeto #
El comando de descubrimiento más útil de PowerShell; prueba también | Format-List *.
Sin comando integrado
Get-Process | Get-Member
Sin comando integrado
Analizar JSON #
Usa -Raw para que el archivo llegue como una sola cadena; ConvertTo-Json -Depth 10 para la salida (la profundidad predeterminada es 2).
Sin comando integrado
Get-Content data.json -Raw | ConvertFrom-Json
jq . data.json
Leer y filtrar un CSV #
Los valores de Import-Csv son cadenas; conviértelos con [int] para comparaciones numéricas.
Sin comando integrado
Import-Csv users.csv | Where-Object { [int]$_.Age -gt 30 }
awk -F, 'NR>1 && $3 > 30' users.csv
Exportar a CSV #
-NoTypeInformation es el valor predeterminado en PowerShell 6+, pero en 5.1 es necesario.
Sin comando integrado
Get-Process | Export-Csv procs.csv -NoTypeInformation
ps -eo pid,comm --no-headers | awk '{print $1","$2}' > procs.csv
Contar, sumar, promediar #
find /c /v "" file.txt
Get-ChildItem -File | Measure-Object Length -Sum -Average
ls -l | awk '{s+=$5} END {print s}'

Scripts: variables, condicionales, bucles, funciones

TareaCMD (Símbolo del sistema)PowerShellBash (Linux/macOS)
Asignar una variable #
bash: sin espacios alrededor de = (name = Ada ejecuta un comando llamado name).
set name=Ada
$name = 'Ada'
name=Ada
Usar una variable en una cadena #
echo Hello %name%
"Hello $name"
echo "Hello $name"
Aritmética #
CMD y bash solo hacen cálculos con enteros; PowerShell usa números de .NET.
set /a n=5*3
$n = 5 * 3
n=$((5 * 3))
Leer la entrada del usuario #
set /p name=Name:
$name = Read-Host 'Name'
read -rp 'Name: ' name
Argumentos del script #
En archivos .bat, %~1 quita las comillas que lo rodean. Un bloque param() da a los scripts de PowerShell parámetros con nombre y tipo.
%1 %2 … %*
$args[0] or param($Path)
$1 $2 … "$@"
If / else con una cadena #
Los operadores de comparación de PowerShell son palabras: -eq -ne -gt -lt -like -match. = y > son asignación y redirección.
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
Comparar números #
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
Si existe un archivo #
if exist file.txt echo yes
if (Test-Path file.txt) { 'yes' }
if [ -f file.txt ]; then echo yes; fi
Código de salida del último programa #
En PowerShell, $? es $true/$false para el último comando; $LASTEXITCODE es el código numérico del último programa nativo.
echo %ERRORLEVEL%
$LASTEXITCODE
echo $?
Ejecutar el siguiente comando solo si hay éxito / error #
Los operadores de cadena de canalización && y || llegaron en PowerShell 7.0; Windows PowerShell 5.1 los rechaza.
build && deploy build || echo failed
build && deploy (PowerShell 7+) build; if ($?) { deploy } (5.1)
build && deploy build || echo failed
Recorrer una lista #
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
Bucle del 1 al 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
Recorrer las líneas de un archivo #
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
Bucle while #
CMD no tiene while; usa goto con una etiqueta en un archivo .bat.
: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
Definir y llamar a una función #
Las funciones de PowerShell se llaman como comandos: Greet Ada, no 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
Guardar la salida de un comando en una variable #
for /f "delims=" %i in ('hostname') do set h=%i
$h = hostname
h=$(hostname)
Descartar la salida #
command >nul 2>&1
command *> $null
command >/dev/null 2>&1
Comentario #
rem comment :: comment
# comment <# block #>
# comment
Archivo de script y cómo ejecutarlo #
PowerShell no ejecuta scripts de la carpeta actual sin .\ y puede bloquearlos por completo: consulta la directiva de ejecución más abajo.
script.bat
.\script.ps1
chmod +x script.sh && ./script.sh

Trampas de los alias de PowerShell: ls, curl, wget, sc, where

PowerShell incluye alias que parecen comandos de Unix o CMD pero ejecutan cmdlets con otros parámetros. Cuáles existen depende de la edición y del sistema operativo. Get-Alias name muestra a qué apunta un nombre en tu sesión.

EscribesWindows PowerShell 5.1PowerShell 7 en WindowsPowerShell 7 en Linux/macOS
curl
Escribe curl.exe en 5.1 para usar el curl real. Sus opciones (-X, -H, -d) no significan nada para Invoke-WebRequest.
Invoke-WebRequestno es alias: ejecuta curl.execurl nativo
wget
Usa Invoke-WebRequest url -OutFile name, o curl.exe -LO url.
Invoke-WebRequestno es alias (Windows no trae wget de serie)wget nativo, si está instalado
ls, dir
Opciones como ls -la fallan en 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 no es PowerShell válido: usa Remove-Item -Recurse -Force.
Copy-Item, Move-Item, Remove-Itemlos mismos cmdletscomandos nativos
ps, killGet-Process, Stop-Processlos mismos cmdletscomandos nativos
sort, tee, diff
diff a b en PowerShell en Windows compara objetos, no las líneas de dos archivos.
Sort-Object, Tee-Object, Compare-Objectlos mismos cmdletscomandos nativos
sc
En 5.1, sc query escribe un archivo llamado query. Usa sc.exe.
Set-Contentno es alias: ejecuta sc.exen/d
where
Usa where.exe para encontrar un programa, o Get-Command.
Where-ObjectWhere-ObjectWhere-Object
echo
echo -n no suprime el salto de línea; usa Write-Host -NoNewline.
Write-OutputWrite-OutputWrite-Output
manhelphelpman nativo

Comillas y escape

La mayoría de los errores de tipo “funciona en un shell y falla en otro” son de comillas. El carácter de escape es distinto en cada shell.

QuéCMDPowerShellBash
Cadena literal (sin expansión)Sin comillas literales: %VAR% se expande incluso dentro de "…"'Cost: $5''Cost: $5'
Cadena con variables"Hello %name%""Hello $name, it is $(Get-Date -Format t)""Hello $name, it is $(date +%R)"
Carácter de escape^ (p. ej. ^& ^| ^>)` acento grave (p. ej. `n salto de línea, `t tabulación, `$ $ literal)\ barra invertida
Comillas dentro de una cadena entre comillas"" dentro de "…" en muchos programas; depende del programa'It''s' or "Say `"hi`""'It'\''s' or "Say \"hi\""
Continuación de línea^ al final de la línea` al final de la línea (o termina la línea con | )\ al final de la línea
% o $ literal en un script%% en un archivo .bat'$' entre comillas simples o `$'$' entre comillas simples o \$
Pasar argumentos sin modificar a un programa nativo(no hace falta)--% hace que PowerShell deje de analizar el resto de la línea(no hace falta)

El paso de comillas a programas nativos (curl.exe, git, node) cambió en PowerShell 7.3: los argumentos con comillas dobles incrustadas ahora se pasan tal cual, según $PSNativeCommandArgumentPassing. En Windows PowerShell 5.1 el mismo cuerpo JSON suele necesitar las comillas internas escapadas dos veces, por eso muchos pasan a Invoke-RestMethod con ConvertTo-Json.

Directiva de ejecución: “la ejecución de scripts está deshabilitada en este sistema”

PowerShell se niega a ejecutar archivos .ps1 cuando la directiva de ejecución es Restricted, que es el valor predeterminado efectivo de Windows PowerShell en las ediciones cliente de Windows (Windows 10 y 11). Windows Server usa RemoteSigned de forma predeterminada: los scripts locales se ejecutan y los descargados deben estar firmados o desbloqueados. En Linux y macOS la directiva es Unrestricted y no se puede cambiar.

  • Get-ExecutionPolicy -List muestra la directiva en cada ámbito; gana el ámbito definido más específico (la directiva de grupo prevalece sobre todo).
  • Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser permite ejecutar tus propios scripts sin derechos de administrador.
  • Unblock-File .\script.ps1 quita la marca de “descargado de internet” de un script de confianza.
  • pwsh -ExecutionPolicy Bypass -File script.ps1 (o powershell en 5.1) aplica una directiva solo a una sesión.

La directiva de ejecución es un seguro contra ejecutar scripts por accidente, no una barrera de seguridad: cualquiera puede pegar el contenido del script en la consola.

Windows PowerShell 5.1 vs PowerShell 7

  • Dos programas: powershell.exe es Windows PowerShell 5.1, integrado en Windows y que ya no recibe funciones nuevas. pwsh es PowerShell 7, que se instala aparte, es multiplataforma y puede convivir con el anterior.
  • Operadores añadidos en 7.0: && y || entre comandos, el ternario $a ? 'yes' : 'no' y los de fusión de nulos ?? / ??=.
  • Codificación de archivos: En 5.1, > y Out-File escriben UTF-16 LE, y Set-Content usa la página de códigos ANSI. PowerShell 7 escribe UTF-8 sin BOM en todas partes, que es lo que esperan Git, las herramientas de Linux y la mayoría de los editores.
  • Alias: La 7 eliminó curl, wget y sc en Windows, y en Linux/macOS deja ls, cp, rm, cat, ps y otros a los comandos nativos (tabla de arriba).
  • Módulos que faltan: Los cmdlets exclusivos de Windows, como Get-NetIPAddress, Test-NetConnection y Resolve-DnsName, funcionan en PowerShell 7 en Windows, pero no existen en Linux ni en macOS.

Ejecutar bash en Windows: WSL

El Subsistema de Windows para Linux ejecuta una distribución Linux real junto a Windows, así que todos los comandos bash de la columna derecha funcionan tal cual. wsl --install desde un símbolo del sistema con privilegios elevados lo instala con Ubuntu de forma predeterminada (Windows 10 versión 2004 y posteriores, y Windows 11); wsl -l -v lista las distribuciones instaladas.

  • Ejecuta un comando de Linux desde CMD o PowerShell: wsl ls -la, o canaliza entre ambos: dir | wsl grep txt.
  • Las unidades de Windows aparecen dentro de Linux en /mnt/c; los archivos de Linux son accesibles desde el Explorador en \\wsl.localhost\Ubuntu (compilaciones anteriores: \\wsl$\Ubuntu).
  • Mantén los proyectos dentro del sistema de archivos de Linux (~/), no en /mnt/c: acceder a archivos a través de la frontera es mucho más lento.

Para profundizar en el lado de Linux, consulta la guía de comandos de Linux.

Una referencia estática que se ejecuta en tu navegador; tus búsquedas no se envían a ningún sitio. Ver todas las herramientas gratis.

¿Encontraste un problema o algo que podría mejorar? Leemos todos los mensajes y lo arreglamos rápido.

Esta tabla de CMD vs PowerShell vs Bash muestra la misma tarea en el Símbolo del sistema de Windows, PowerShell y bash en una sola fila: listar y copiar archivos, buscar texto en archivos (el equivalente de grep en PowerShell es Select-String), variables de entorno, procesos, red, servicios, leer y escribir contenido de archivos, y scripting con variables, condicionales, bucles y funciones. Busca con un comando de cualquiera de las tres shells y obtendrás sus equivalentes, cada uno con un botón de copiar.

La tabla también cubre lo que suele fallar al pasar de una a otra: alias de PowerShell que parecen comandos de Unix pero no lo son (curl y wget en Windows PowerShell 5.1, ls y rm en cualquier Windows), caracteres de comillas y de escape distintos, el error de directiva de ejecución que bloquea los scripts .ps1 y las diferencias entre Windows PowerShell 5.1 y PowerShell 7. Los comandos de PowerShell funcionan en ambas versiones salvo que una nota diga lo contrario; cuando no existe un equivalente en CMD, la tabla lo indica en lugar de inventarse uno.

Cómo usarla

  1. Busca el comando que conoces, en cualquier shell (por ejemplo, “grep”, “findstr” o “Select-String”), o la tarea (“matar proceso”, “variable de entorno”).
  2. Recorre la fila para ver el equivalente en las otras dos shells y haz clic en Copiar junto al que necesites.
  3. Revisa la nota bajo el nombre de la tarea: señala diferencias entre versiones (PowerShell 5.1 frente a 7) y cmdlets exclusivos de Windows.
  4. Baja a las secciones de alias, comillas y directiva de ejecución si un comando se comporta de forma distinta a lo que esperabas.
  5. Usa Imprimir / Guardar como PDF para tener una copia en la mesa; la página también funciona en el móvil, donde cada fila se convierte en una tarjeta.

Preguntas frecuentes

¿Cuál es el equivalente de grep en PowerShell?

Select-String. Busca en un archivo con Select-String -Path app.log -Pattern error, o filtra la salida de un comando con ipconfig | Select-String IPv4. No distingue mayúsculas y minúsculas por defecto (añade -CaseSensitive), usa expresiones regulares de .NET, y -NotMatch equivale a grep -v. Para búsquedas recursivas, canaliza Get-ChildItem -Recurse -Filter *.log hacia Select-String. Su alias corto es sls.

¿Por qué curl se comporta de forma extraña en PowerShell?

En Windows PowerShell 5.1, curl y wget son alias de Invoke-WebRequest, así que las opciones de curl como -X, -H y -d se rechazan o significan otra cosa. Escribe curl.exe para ejecutar el curl real que incluye Windows 10 1803 y posteriores. PowerShell 7 eliminó esos alias, así que allí curl ejecuta curl.exe. En Linux y macOS, curl nunca fue un alias.

¿PowerShell es mejor que CMD?

Para cualquier cosa más allá de ejecutar un programa o un archivo por lotes corto, sí. PowerShell canaliza objetos estructurados en lugar de texto, así que filtras y ordenas por nombre de propiedad (Where-Object, Sort-Object) en lugar de analizar columnas, y tiene funciones de verdad, manejo de errores, soporte de JSON y CSV y administración remota. CMD sigue sirviendo para archivos .bat heredados y algunos instaladores, y cualquier herramienta de CMD (ipconfig, robocopy, netstat) también se puede ejecutar desde PowerShell.

¿Cómo soluciono “la ejecución de scripts está deshabilitada en este sistema”?

Es la directiva de ejecución, que es Restricted por defecto en las ediciones cliente de Windows 10 y 11. Ejecuta Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser en PowerShell (no requiere administrador). A partir de ahí se ejecutan tus propios scripts, y los descargados de internet deben estar firmados o desbloquearse con Unblock-File. Get-ExecutionPolicy -List muestra qué está configurado y dónde; una directiva de grupo prevalece sobre lo que configures tú.

¿Puedo ejecutar comandos de bash en Windows?

Sí, con el Subsistema de Windows para Linux (WSL). Ejecuta wsl --install desde una consola con privilegios elevados (Windows 10 versión 2004 o posterior, o Windows 11) para instalar Ubuntu; después ábrelo desde el menú Inicio o ejecuta comandos sueltos desde CMD o PowerShell con wsl seguido del comando, como wsl grep -rn TODO. Git for Windows también incluye Git Bash, un bash más ligero con las herramientas de Unix habituales.

¿Qué diferencia hay entre Windows PowerShell y PowerShell 7?

Windows PowerShell 5.1 (powershell.exe) viene integrado en Windows y solo recibe correcciones. PowerShell 7 (pwsh) es la versión actual y multiplataforma que funciona en Windows, Linux y macOS y se instala por separado; se pueden tener ambas instaladas. La versión 7 añade && y || entre comandos y los operadores ternario y ??, escribe archivos en UTF-8 por defecto y elimina algunos alias confusos como curl y wget.

Objetos frente a texto: la idea que hace que PowerShell encaje

En CMD y bash, una tubería transporta texto. Para obtener en bash el proceso que más memoria usa, sacas la columna correcta de la salida de ps con sort -k o awk, y el comando se rompe si cambia la disposición de las columnas. En PowerShell, la tubería transporta objetos con propiedades con nombre, así que la misma tarea es Get-Process | Sort-Object WS -Descending | Select-Object -First 1. No se analiza nada y los nombres de las propiedades son los mismos en todas las máquinas.

La consecuencia práctica es una forma distinta de descubrir las cosas. En bash lees una página man para conocer el formato de salida; en PowerShell canalizas cualquier comando hacia Get-Member para ver qué propiedades y métodos tienen sus objetos, y luego filtras con Where-Object y eliges campos con Select-Object. PowerShell solo convierte la salida en texto cuando llega a la pantalla o a un archivo.

Los programas nativos como ipconfig, git o curl.exe siguen generando texto en PowerShell, así que Select-String y -match funcionan con ellos como lo haría grep. Su código de salida está en $LASTEXITCODE, no en $?.

Traducir un script entre las tres shells

La traducción línea a línea funciona con scripts sencillos, pero algunas diferencias pillan a casi todo el mundo:

• Operadores de comparación: CMD usa == para cadenas y EQU, GTR, LSS para números; PowerShell usa -eq, -gt, -lt, -like y -match (un > suelto es una redirección); bash usa = dentro de [ ] para cadenas y -gt o (( )) para números.

• Variables: %name% en CMD (y !name! dentro de bucles tras setlocal EnableDelayedExpansion), $name en PowerShell, $name en bash, sin espacios alrededor de = al asignar.

• Los bucles en archivos .bat duplican el signo de porcentaje: for %%f in (*.txt) dentro de un archivo, for %f en la consola.

• Rutas: PowerShell acepta tanto / como \ en Windows; bash en Linux necesita /. Las variables de entorno no distinguen mayúsculas y minúsculas en Windows y sí en Linux.

• Errores: CMD continúa tras un fallo salvo que compruebes %ERRORLEVEL%; bash continúa salvo con set -e; PowerShell continúa tras errores no terminales salvo con $ErrorActionPreference = 'Stop'.

Cuando un script tiene que ejecutarse en Windows y en Linux, PowerShell 7 o bash bajo WSL evitan mantener dos copias.

Herramientas gratis relacionadas

  • Guía rápida de comandos de Linux — Comandos de Linux por tarea, desde archivos y permisos hasta redes, systemd y procesamiento de texto. Cada entrada incluye opciones, ejemplos para copiar y notas para macOS.
  • Atajos de teclado de Windows — Todos los atajos de Windows 11 en una lista con búsqueda e imprimible: tecla Windows, Snap, escritorios, capturas de pantalla y Explorador de archivos.
  • Atajos de teclado de Mac — Todos los atajos de macOS con los símbolos ⌘ ⌥ ⌃ ⇧ explicados: capturas de pantalla, mosaico de ventanas, Finder, Safari y caracteres especiales.
  • curl a código — Pega un comando curl, incluido el "Copy as cURL" de Chrome, y obtén la misma petición en Python, JavaScript, Node, Go, PHP, Ruby, Java, C#, wget o HTTPie.
  • Guía rápida de Git — Comandos de Git organizados según lo que quieres hacer: deshacer el último commit, renombrar una rama, eliminar una rama remota. Los comandos modernos switch/restore con sus equivalentes clásicos y avisos de peligro.