PowerShell脚本未压缩正确的文件

tec*_*029 2 powershell scripting zip 7zip target

 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
Run Code Online (Sandbox Code Playgroud)

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

mkl*_*nt0 6

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

Zip C:\Users\Admin\Desktop\TEST.zip $Files.FullName
Run Code Online (Sandbox Code Playgroud)

问题是,[System.IO.FileInfo]通过返回的情况下Get-ChildItem situationally [1]字符串化他们的唯一文件名,这是你的情况发生了什么事,所以你的Zip函数,则解释$toBeZipped相对于当前位置,这是C:\Program Files\7-Zip在这一点上。

也就是说,最好不要Set-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.
}
Run Code Online (Sandbox Code Playgroud)

[1] Get-ChildItem输出仅字符串化为文件名时

注意:

  • Get-Item幸运的是,输出总是字符串化为完整路径。
  • 在PowerShell中的核心Get-ChildItem总是 stringifies的完整路径,幸运。

因此,以下内容仅适用Get-ChildItemWindows PowerShell

问题是双重的:

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

  • 因此,对于稳健的参数传递,你需要确保你的Get-ChildItem输出始终stringifies到完整路径,这Get-ChildItem确实保证-这很容易,当忘记的名字,只字串的出现,甚至,你需要注意它。

始终传递.FullName属性值是最简单的解决方法,或者是为了与任何 PowerShell提供程序进行可靠操作,而不仅仅是文件系统.PSPath

[System.IO.FileInfo][System.IO.DirectoryInfo]输出由实例Get-ChildItem命令字符串化到它们的文件而已,当且仅当

  • 如果将一个或多个文字目录路径传递给-LiteralPath-Path(可能是第一个位置参数),或者 根本不传递任何路径(以当前位置为目标);也就是说,如果目录的内容被枚举。

  • 并且同时使用-Include/ -Exclude参数(是否-Filter使用没有区别)。

  • 相比之下,是否同时存在以下内容也没有区别:

    • -Filter(任选地作为第二位置参数,但请注意,指定一个通配符表达如*.txt作为第一(并且可能只)位置参数绑定到-Path参数)
    • -Recurse本身,但请注意,它通常与-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
Run Code Online (Sandbox Code Playgroud)