powershell scripting zip target 7zip

El script de PowerShell no comprime los archivos correctos



scripting zip (2)

Function Zip { Param ( [string]$zipFile , [string[]]$toBeZipped ) $CurDir = Get-Location Set-Location "C:/Program Files/7-Zip" ./7z.exe A -tzip $zipFile $toBeZipped | Out-Null Set-Location $CurDir } $Now = Get-Date $Days = "60" $TargetFolder = "C:/users/Admin/Downloads/*.*" $LastWrite = $Now.AddDays(-$Days) $Files = Get-Childitem $TargetFolder -Recurse | Where {$_.LastWriteTime -le "$LastWrite"} $Files Zip C:/Users/Admin/Desktop/TEST.zip $Files

Estoy probando este script que encontré en línea. Mi problema es que, en lugar de comprimir los archivos en la carpeta de destino, está copiando y comprimiendo el contenido de la carpeta de archivos del programa 7-zip. Que podria causar esto? Gracias por adelantado


Si usted (temporalmente) desactiva el |Out-Null , verá qué mensaje de error pasa.
$ Files contiene objetos, no solo una matriz de nombres de archivos.

De forma predeterminada, powershell intenta crear una cadena de caracteres utilizando la propiedad Name , que no contiene la ruta, por lo que 7zip no puede encontrar los archivos, ya que también se cambia la ruta a la carpeta 7zip (y -receptan la recolección de $ archivos)

Entonces cambia la linea

$Files = Get-Childitem $TargetFolder -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}

y añadir

| Select-Object -ExpandProperty FullName

Un verson ligeramente reformateado de tu fuente:

Function Zip{ Param ( [string]$zipFile, [string[]]$toBeZipped ) & "C:/Program Files/7-Zip/7z.exe" A -tzip $zipFile $toBeZipped | Out-Null } $Days = "60" $LastWrite = (Get-Date).Date.AddDays(-$Days) $TargetFolder = "$($ENV:USERPROFILE)/Downloads/*" $Files = Get-Childitem $TargetFolder -Recurse | Where {$_.LastWriteTime -le $LastWrite} | Select-Object -ExpandProperty FullName $Files Zip "$($ENV:USERPROFILE)/Desktop/TEST.zip" $Files


Pase los archivos como rutas completas a la función Zip , usando su propiedad .FullName (sintaxis de PSv3 +):

Zip C:/Users/Admin/Desktop/TEST.zip $Files.FullName

El problema es que las instancias de [System.IO.FileInfo] devueltas por Get-ChildItem situacionalmente [1] solo se ajustan a sus nombres de archivo , que es lo que sucedió en su caso, por lo que su función Zip interpretó los valores de $toBeZipped como relativos a la ubicación actual , que es C:/Program Files/7-Zip en ese punto.

Dicho esto, es mejor no usar Set-Location en su función por completo , de modo que, en caso de que quiera pasar rutas relativas reales, se interpreten correctamente como relativas a la ubicación actual :

Function Zip { Param ( [Parameter(Mandatory)] # make sure a value is passed [string]$zipFile , [Parameter(Mandatory)] # make sure a value is passed [string[]]$toBeZipped ) # Don''t change the location, use & to invoke 7z by its full path. $null = & "C:/Program Files/7-Zip/7z.exe" A -tzip $zipFile $toBeZipped # You may want to add error handling here. }

[1] Cuando la salida de Get-ChildItem se limita a los nombres de archivo solamente:

Nota:

  • Afortunadamente, la salida de Get-Item siempre se limita a la ruta completa.
  • En PowerShell Core , Get-ChildItem también se limita a la ruta completa , lo que es recomendable, pero no está claro si el cambio fue intencional .

Por lo tanto, lo siguiente solo se aplica a Get-ChildItem en Windows PowerShell :

El problema es doble:

  • Incluso los cmdlets incorporados de PowerShell vinculan los argumentos del archivo / directorio (valores de parámetros, en lugar de la entrada a través de la canalización ), no como objetos , sino como cadenas ( este tema de GitHub se está discutiendo para cambiar este comportamiento).

  • Por lo tanto, para una Get-ChildItem argumentos sólida, debe asegurarse de que la salida de su Get-ChildItem coherente con las rutas completas , lo que Get-ChildItem no garantiza, y es fácil de olvidar cuando se produce una clasificación de solo nombre, incluso de lo que necesita pagar. atención a ello en absoluto.

.FullName siempre los valores de propiedad .FullName lugar es la solución más simple o, para una operación confiable con cualquier proveedor de PowerShell, no solo el sistema de archivos, .PSPath .

[System.IO.FileInfo] instancias [System.IO.FileInfo] y [System.IO.DirectoryInfo] generadas por un comando Get-ChildItem limitan a sus nombres de archivo, si y solo si :

  • Si se pasan una o más rutas de directorio literales a -Path o -Path (posiblemente como el primer argumento posicional) o no se pasa ninguna ruta ( -Path la ubicación actual); es decir, si se enumeran los contenidos de los directorios.

  • y tampoco usa los parámetros -Exclude / -Exclude (si se usa -Filter no hace ninguna diferencia).

  • Por el contrario, si los siguientes también están presentes o no, no hay diferencia:

    • -Filter (opcionalmente como el segundo argumento posicional, pero tenga en cuenta que al especificar una expresión comodín como *.txt como el primer argumento posicional (y posiblemente solo) se enlaza con el parámetro -Path )
    • -Recurse (por sí mismo , pero tenga en cuenta que a menudo se combina con -Exclude / -Exclude )

Ejemplos de comandos:

# NAME-ONLY stringification: Get-ChildItem | % ToString # no target path Get-ChildItem . | % ToString # path is literal dir. Get-ChildItem . *.txt | % ToString # path is literal dir., combined with -Filter # FULL PATH stringification: Get-ChildItem foo* | % ToString # non-literal path (wildcard) Get-ChildItem -Recurse -Include *.txt | % ToString # use of -Include Get-ChildItem file.txt | % ToString # *file* path