我目前正在努力编写一个简单的powershell脚本来归档文件。
我在一个文件夹中有数千个旧文件,我想根据它们创建日期的月份/年份将它们归档,命名为"yyyym"。
我使用下面的代码
Get-ChildItem -Path $sourcePath -filter $filter |
Where-Object {(($_.CreationTime) -le $dateCriteria) -and ($_.psIsContainer -eq $false)}|
ForEach {
$archive = "{0:yyyy}{0:MM}.7z" -f $_.CreationTime
$archivePath= Join-Path -Path $destinationFolder -ChildPath $archive
& "C:Program Files7-Zip7z.exe" a -mx9 -t7z -m0=lzma2 -sdel $archivePath$_.FullName |Out-Null
}
逻辑看起来很好,因为它创建了如下文件201809.7 z201810.7 z…在我的目标文件夹
问题是我在控制台看到错误:
System ERROR:
The file exists
或
System ERROR:
Access denied
或
System ERROR:
The file exists
ERROR: ********202011.7z
Can not open the file as archive
结果,在我的目标文件夹中,除了预期的存档文件外,我还有像"201810.7z.tmp1">
这样的文件I通过添加-w"{WORK_PATH}"
来更改工作目录以隔离这些文件到命令行
我还添加了Start-Sleep -Milliseconds 1
因为它看起来像并发访问,即使我的脚本是单线程的(也许7zip没有正确结束),但它没有工作。
Start-Sleep -Milliseconds 500
似乎工作但对显而易见的原因我不想使用它。正确的做法是什么呢?
编辑1根据史密斯老师的回答,我修改了我的代码
Get-ChildItem -Path $emplacementSource -filter $filtreNomFichiers |
Where-Object {(($_.CreationTime) -le $dernierJour) -and ($_.psIsContainer -eq $false)}|
ForEach {
$archive = "{0:yyyy}{0:MM}.7z" -f $_.CreationTime
$cheminArchive= Join-Path -Path $dossierCible -ChildPath $archive
[Array]$arguments = "a" ,"-w$workDir", "-mx9" ,"-t7z" ,"-m0=lzma2" ,"-sdel" ,$cheminArchive, $_.FullName
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = $sevenZip
$pinfo.RedirectStandardError = $true
$pinfo.CreateNoWindow= $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "$arguments"
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $pinfo
$process.Start()
$output = $process.StandardError.ReadToEnd()
$process.WaitForExit()
if(0 -ne $process.ExitCode){
Write-Output "$(Get-TimeStamp) Erreur: $output" | Out-file $fichierLogs -append
}
}
我仍然有File exists
错误和.tmpX
档案在我的临时文件夹。
不要使用&
,使用Start-Process并传递-wait
开关或使用-PassThru
开关和返回的System.Diagnostics.Process
来检查进程是否已经自己完成。两者都将得到与Start-Sleep -Milliseconds 500
测试相同的结果,但它只会等待7z.exe完成执行所需的时间。
边注-您可以一次追加多个文件。这可能比单独添加每个文件更快。