PowerShell 脚本未压缩正确的文件 [英] PowerShell script not zipping correct files
问题描述
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屋!