Trabajar con archivos y carpetas

Navegar por las unidades de PowerShell y manipular los elementos son procesos similares al de manipular los archivos y carpetas en unidades de disco de Windows. En este artículo se describe cómo usar PowerShell para abordar tareas específicas de manipulación de archivos y carpetas.

Enumeración de todos los archivos y carpetas dentro de una carpeta

Para obtener todos los elementos directamente dentro de una carpeta, use Get-ChildItem. Agregue el parámetro Force opcional para mostrar elementos ocultos o del sistema. Por ejemplo, este comando muestra el contenido directo de la unidad C: de PowerShell.

Get-ChildItem -Path C:\ -Force

El comando muestra solo los elementos contenidos directamente, de forma muy parecida al comando cmd.exe de dir o ls en un shell de UNIX. Para mostrar los elementos de una subcarpeta, debe especificar el parámetro Recurse. El siguiente comando muestra todo el contenido de la unidad C::

Get-ChildItem -Path C:\ -Force -Recurse

Get-ChildItem puede filtrar elementos con sus parámetros Path, Filter, Include y Exclude, pero estos suelen basarse solo en el nombre. Puede realizar un filtrado complejo basado en otras propiedades de los elementos mediante Where-Object.

El siguiente comando encuentra todos los ejecutables de la carpeta Archivos de programa que se modificaron por última vez después del 1 de octubre de 2005, cuyo tamaño no es inferior a 1 megabyte ni superior a 10 megabytes:

Get-ChildItem -Path $env:ProgramFiles -Recurse -Include *.exe |
    Where-Object -FilterScript {
        ($_.LastWriteTime -gt '2005-10-01') -and ($_.Length -ge 1mb) -and ($_.Length -le 10mb)
    }

Copia de archivos y carpetas

La copia se realiza con Copy-Item. El comando siguiente realiza una copia de seguridad del script de perfil de PowerShell:

if (Test-Path -Path $PROFILE) {
    Copy-Item -Path $PROFILE -Destination $($PROFILE -replace 'ps1$', 'bak')
}

El comando Test-Path comprueba si el script de perfil existe.

Si el archivo de destino ya existe, se produce un error en el intento de copia. Para sobrescribir un destino preexistente, use el parámetro Force:

if (Test-Path -Path $PROFILE) {
    Copy-Item -Path $PROFILE -Destination $($PROFILE -replace 'ps1$', 'bak') -Force
}

Este comando funciona aunque el destino sea de solo lectura.

La copia de carpetas funciona del mismo modo. Este comando copia la carpeta C:\temp\test1 en la nueva carpeta C:\temp\DeleteMe de forma recursiva:

Copy-Item C:\temp\test1 -Recurse C:\temp\DeleteMe

También puede copiar una selección de elementos. El siguiente comando copia todos los archivos .txt contenidos en cualquier parte de C:\data en C:\temp\text:

Copy-Item -Filter *.txt -Path c:\data -Recurse -Destination C:\temp\text

Todavía puede ejecutar comandos nativos como xcopy.exe y robocopy.exe para copiar archivos.

Creación de archivos y carpetas

La creación de nuevos elementos funciona igual en todos los proveedores de PowerShell. Si un proveedor de PowerShell tiene más de un tipo de elemento (por ejemplo, el proveedor FileSystem de PowerShell distingue entre directorios y archivos), debe especificar el tipo de elemento.

Este comando crea una carpeta nueva C:\temp\New Folder:

New-Item -Path 'C:\temp\New Folder' -ItemType Directory

Este comando crea un nuevo archivo vacío C:\temp\New Folder\file.txt.

New-Item -Path 'C:\temp\New Folder\file.txt' -ItemType File

Importante

Al usar el modificador Force con el comando New-Item para crear una carpeta y la carpeta ya existe, no sobrescribirá ni reemplazará la carpeta. Simplemente devolverá el objeto de carpeta existente. Sin embargo, si usa New-Item -Force en un archivo que ya existe, el archivo se sobrescribe.

Eliminación de todos los archivos y carpetas de una carpeta

Los elementos contenidos se pueden quitar mediante Remove-Item, pero se pedirá que se confirme la eliminación si el elemento contiene algo más. Por ejemplo, si intenta eliminar la carpeta C:\temp\DeleteMe que contiene otros elementos, PowerShell le pide confirmación antes de eliminar la carpeta:

Remove-Item -Path C:\temp\DeleteMe
Confirm
The item at C:\temp\DeleteMe has children and the Recurse parameter wasn't
specified. If you continue, all children will be removed with the item. Are you
sure you want to continue?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is "Y"):

Si no quiere que se le solicite confirmación por cada elemento contenido, especifique el parámetro Recurse:

Remove-Item -Path C:\temp\DeleteMe -Recurse

Asignación de una carpeta local como unidad

También puede asignar una carpeta local mediante el comando New-PSDrive. El siguiente comando crea una unidad local P: con raíz en el directorio local Archivos de programa, visible solo desde la sesión de PowerShell:

New-PSDrive -Name P -Root $env:ProgramFiles -PSProvider FileSystem

Al igual que con las unidades de red, las unidades asignadas dentro de PowerShell son visibles inmediatamente en el shell de PowerShell. Para crear una unidad asignada visible desde el Explorador de archivos, use el parámetro Persist. Sin embargo, solo se pueden usar rutas de acceso remotas con Persist.

Lectura de un archivo de texto en una matriz

Uno de los formatos de almacenamiento más comunes para los datos de texto es en un archivo con líneas separadas que se tratan como elementos de datos distintos. El cmdlet Get-Content se puede usar para leer un archivo completo en un solo paso, como se muestra aquí:

Get-Content -Path $PROFILE
# Load modules and change to the PowerShell-Docs repository folder
Import-Module posh-git
Set-Location C:\Git\PowerShell-Docs

Get-Content trata los datos leídos del archivo como una matriz, con un elemento por línea de contenido del archivo. Para confirmarlo, compruebe la longitud del contenido devuelto:

PS> (Get-Content -Path $PROFILE).Length
3

Este comando es más útil para obtener listas de información en PowerShell directamente. Por ejemplo, podría almacenar una lista de nombres de equipo o direcciones IP en el archivo C:\temp\domainMembers.txt, con un nombre en cada línea del archivo. Puede usar Get-Content para recuperar el contenido del archivo y colocarlo en la variable $Computers:

$Computers = Get-Content -Path C:\temp\DomainMembers.txt

$Computers es ahora una matriz que contiene un nombre de equipo en cada elemento.