PowerShell脚本未压缩正确的文件 [英] PowerShell script not zipping correct files

查看:123
本文介绍了PowerShell脚本未压缩正确的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 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

我正在测试我在网上找到的脚本。我的问题是,不是压缩目标文件夹中的文件,而是复制并压缩7-zip程序文件文件夹的内容。是什么原因造成的?预先感谢

I am testing out this script I found online. My problem is that instead of zipping the files in the target folder, it is copying and zipping the contents of the 7-zip program file folder. What could cause this? Thanks in advance

推荐答案

将文件作为完整路径 传递给 Zip 函数,使用其 .FullName 属性(PSv3 +语法):

Pass the files as full paths to the Zip function, using their .FullName property (PSv3+ syntax):

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






问题是 [System.IO.FileInfo] Get-ChildItem 按条件 [1] 返回的c>个实例仅字符串化为其文件名 ,这就是您遇到的情况,因此您的 Zip 函数然后解释了 $ toBeZipped 相对于当前位置的值为 ,即当前位置的 C:\Program Files\7-Zip


The problem is that the [System.IO.FileInfo] instances returned by Get-ChildItem situationally[1] stringify to their file names only, which is what happened in your case, so your Zip function then interpreted the $toBeZipped values as relative to the current location, which is C:\Program Files\7-Zip at that point.

也就是说,最好不要在函数中完全使用 Set-Location ,这样在您要做想要传递实际相对路径的事件,它们是e正确地解释为相对于 current 位置:

That said, it's better not to use Set-Location in your function altogether, so that in the event that you do want to pass actual relative paths, they are correctly interpreted as relative to the current location:

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] 何时 Get-ChildItem 输出仅字符串化为文件名称


[1] When Get-ChildItem output stringifies to file names only:

注意:


  • 获取项目输出<幸运的是,em>总是字符串化为完整路径。

  • 在PowerShell Core 中, Get-ChildItem < /幸运的是,/ code>总是始终字符串化。

  • Get-Item output always stringifies to the full path, fortunately.
  • In PowerShell Core, Get-ChildItem too always stringifies to the full path, fortunately.

因此,以下内容仅适用于 Windows PowerShell 中的 Get-ChildItem

问题有两个:


  • 甚至PowerShell的内置cmdlet绑定文件/目录参数(参数值-与通过管道输入相反)不是作为对象,而是作为字符串(正在讨论如何更改此行为)在此GitHub问题)。

  • Even PowerShell's built-in cmdlets bind file / directory arguments (parameter values - as opposed to input via the pipeline) not as objects, but as strings (changing this behavior is being discussed in this GitHub issue).

因此,要进行可靠的参数传递,您需要确保 Get-ChildItem 输出始终字符串化为完整路径,而 Get-ChildItem 不会 保证-而且很容易忘记何时出现仅名称字符串化,甚至根本不需要注意它。

Therefore, for robust argument-passing, you need to ensure that your Get-ChildItem output consistently stringifies to full paths, which Get-ChildItem does not guarantee - and it's easy to forget when name-only stringification occurs of even that you need to pay attention to it at all.

始终传递 .FullName 属性值是最简单的解决方法,或者对于使用任何 PowerShell提供程序,而不仅仅是文件系统 .PSPath

Always passing the .FullName property values instead is the simplest workaround or, for reliable operation with any PowerShell provider, not just the filesystem, .PSPath.

[System.IO.FileInfo] [System.IO.DirectoryInfo] 实例的输出 Get-ChildItem 命令仅将其字符串化为文件名称当且仅当 时:

[System.IO.FileInfo] and [System.IO.DirectoryInfo] instances output by a Get-ChildItem command stringify to their file names only, if and only if:


  • 如果一个或多个文字目录路径 重新传递给 -LiteralPath -Path (可能是第一个位置参数) 完全没有路径 (定位到当前位置);也就是说,如果枚举目录的内容

  • If one or more literal directory paths are passed to -LiteralPath or -Path (possibly as the 1st positional argument) or no path at all is passed (target the current location); that is, if the contents of directories are enumerated.

and 不会使用 -Include / -Exclude 参数(是否 -Filter 的使用使没有有所不同)。

and does not also use the -Include / -Exclude parameters (whether -Filter is used makes no difference).

通过对比,无论是否以下内容也可以使没有有所不同:

By contrast, whether or not the following are also present makes no difference:


  • -过滤器(可选地作为 2nd 位置参数,但请注意,将通配符表达式(例如 *。txt )指定为 1st (并且可能只有)位置参数绑定到 -Path 参数)

  • -Recurse (通过本身,但请注意,它通常与 -Include / -Exclude

  • -Filter (optionally as the 2nd positional argument, but note that specifying a wildcard expression such as *.txt as the 1st (and possibly only) positional argument binds to the -Path parameter)
  • -Recurse (by itself, but note that it is often combined with -Include / -Exclude)

示例命令:

# 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

这篇关于PowerShell脚本未压缩正确的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆