I am currently strugling on a simple powershell script to archive files.
I have thousand of old file in a folder and i want to archive them depending on the month/year of their creation date in archives named "YYYYMM".
I use the code below
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 Files\7-Zip\7z.exe" a -mx9 -t7z -m0=lzma2 -sdel $archivePath$_.FullName |Out-Null
}
The logic seems fine as it creates files like 201809.7z 201810.7z ... In my destination folder.
The problem is i see errors in the console:
System ERROR:
The file exists
or
System ERROR:
Access denied
or
System ERROR:
The file exists
ERROR: ********\202011.7z
Can not open the file as archive
As a result, in my destination folder, in addition to the expected archive files i have file like "201810.7z.tmp1"
I changes the working directory to isolate those files by adding -w"{WORK_PATH}"
to the command line.
I also added Start-Sleep -Milliseconds 1
as it looked like concurrent access even if my script is mono threaded (maybe 7zip doesn't end properly) but it didn't work.
With Start-Sleep -Milliseconds 500
it seems to work but for obvious reasons i dont want to use that. What would the proper way to do that be ?
EDIT 1 Following MisterSmith's answer i changed my code for
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
}
}
I still have File exists
errors and .tmpX
archives in my temp folder.