PowerShell脚本未压缩正确的文件 [英] PowerShell script not zipping correct files
问题描述
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] $ c $
,这就是您遇到的情况,因此您的 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屋!