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

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

问题描述

 Function Zip
{
    Param
    (
        [string]$zipFile
        ,
        [string[]]$toBeZipped
    )
    $CurDir = Get-Location
    Set-Location "C:Program Files7-Zip"
    .7z.exe A -tzip $zipFile $toBeZipped | Out-Null
    Set-Location $CurDir
}
$Now = Get-Date
$Days = "60"
$TargetFolder = "C:usersAdminDownloads*.*"
$LastWrite = $Now.AddDays(-$Days)
$Files = Get-Childitem $TargetFolder -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}
$Files
Zip C:UsersAdminDesktopTEST.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:UsersAdminDesktopTEST.zip $Files.FullName


问题在于 [System.IO.FileInfo] 实例返回的 Get-ChildItem situationally[1]em>仅文件名,这就是您的情况,因此您的 Zip 函数将 $toBeZipped 值解释为 相对于当前位置,在那个点是 C:Program Files7-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 Files7-Zip at that point.

也就是说,最好不要在您的函数中完全使用 Set-Location,以便在您确实想要传递实际的相对路径,它们被正确解释为相对于当前位置:

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 Files7-Zip7z.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:

注意:

  • 相关的Get-Item cmdlet 输出总是字符串化为完整路径,幸运的是.
  • 在 PowerShell [Core] v6.1+ 中,Get-ChildItem总是 字符串化为完整路径,幸运的是.
  • The related Get-Item cmdlet output always stringifies to the full path, fortunately.
  • In PowerShell [Core] v6.1+, Get-ChildItem too always stringifies to the full path, fortunately.

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

问题是双重的:

  • 即使是 PowerShell 的内置 cmdlet 也绑定文件/目录参数(参数值 - 与通过管道输入相反)而不是作为对象,但作为 strings(更改此行为正在 GitHub 问题 #6057).

  • 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 GitHub issue #6057).

因此,为了实现稳健的参数传递,您需要确保您的 Get-ChildItem 输出一致地字符串化为 完整路径,其中 Get-ChildItem保证——当name-only字符串化发生时很容易忘记,甚至你需要注意它.

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.

使用-Include/-Exclude参数(是否使用-Filter没有区别).

相比之下,以下是否也存在没有区别:

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

  • -Filter(可选作为 2nd 位置参数,但请注意,指定通配符表达式(例如 *.txt)作为 第一个(可能是唯一的)位置参数绑定到 -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天全站免登陆