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程序文件文件夹的内容。是什么原因造成的?预先感谢
答案 0 :(得分:4)
使用文件的Zip
属性(PSv3 +语法)将文件作为完整路径 传递到.FullName
函数:
Zip C:\Users\Admin\Desktop\TEST.zip $Files.FullName
问题是由[System.IO.FileInfo]
返回的{strong> Get-ChildItem
个实例按情况 [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.
}
[1] 何时 Get-ChildItem
输出仅字符串化到文件名称:
注意:
Get-Item
输出始终幸运地将字符串化为完整路径。Get-ChildItem
也总是 字符串化为完整路径,这值得称赞,但这是{{3 }}。因此,以下内容仅适用于 Windows PowerShell 中的Get-ChildItem
:
问题是双重的:
即使PowerShell的内置cmdlet绑定文件/目录参数(参数值-与通过管道输入的参数相反)也不是 objects < / em>,但作为 strings (在unclear whether the change was intentional中讨论更改此行为)。
因此,要进行可靠的参数传递,您需要确保Get-ChildItem
输出始终字符串化为完整路径,Get-ChildItem
不会这样做保证-很容易忘记何时发生仅名称字符串化,甚至根本不需要注意它。
始终传递.FullName
属性值是最简单的解决方法,或者,对于 any PowerShell提供程序的可靠操作,不仅仅是文件系统, .PSPath
。
[System.IO.FileInfo]
命令输出的 [System.IO.DirectoryInfo]
和Get-ChildItem
实例仅字符串化到其文件 names ,仅当且仅当 em> :
如果将一个或多个文字目录路径 传递给-LiteralPath
或-Path
(可能是第一个位置参数)< em>或 完全没有路径 (定位到当前位置);也就是说,如果枚举目录的内容。
和也也不使用-Include
/ -Exclude
参数(无论{{1 }}的使用使没有有所不同)。
相比之下,是否还存在以下内容使没有有所不同:
-Filter
(可选地作为 2nd 位置参数,但请注意,将通配符表达式(例如-Filter
指定为 1st )(并且可能仅)位置参数绑定到*.txt
参数)-Path
(通过本身,但请注意,它通常与-Recurse
/ -Include
结合使用)示例命令:
-Exclude
答案 1 :(得分:1)
如果(暂时)禁用# 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
,您会看到味精传递的错误。
$ Files包含对象而不仅仅是文件名数组。
默认情况下,powershell尝试使用不包含路径的|Out-Null
属性对此进行字符串化-因此7zip找不到文件,因为您还更改了7zip文件夹的路径(并且-recurse收集$文件)
因此更改行
Name
并追加
$Files = Get-Childitem $TargetFolder -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}
您的来源的格式稍稍重新格式化的版本:
| Select-Object -ExpandProperty FullName