Я работаю над сценарием PowerShell для архивирования старых журналов.Цель состоит в том, чтобы взять журналы старше X дней из всех других наших сценариев, событий, программного обеспечения и т. Д. (Которые записываются в центральное хранилище журналов) и заархивировать их для длительного хранения.Сценарий прекрасно работает, когда есть только один уровень вложенных папок, которые содержат файлы.Проблема в том, что он не работает хорошо, когда есть два (или более) слоя вложенных папок.
Вот пример структуры папок в центральном хранилище журналов:
\\store
└─logs
├─ops
│ ├─ScriptAlpha
│ │ ├─ScriptA-2018-10-17.log
│ │ └─ScriptA-2018-10-10.log
│ └─ScriptBeta
│ ├─ScriptB-2018-11-17.log
│ └─ScriptB-2018-11-09.log
├─Maintenance
│ └─ScriptA
│ ├─ScriptA-2018-10-22.log
│ └─ScriptA-2018-10-26.log
└─Ondemand
└─ScriptBigly
└─ScriptB-2018-11-27.log
У меня есть другой набор журналов, которые я создал сценарий для архивирования, и он прекрасно работает, но только когда нет многократных вложенных папок.Цель для этого выглядит следующим образом:
\\store2
└─Output
├─Alpha
│ └─Alpha-2018-11-27.log
├─Bravo
│ ├─Alpha-2018-11-27.log
│ └─Alpha-2018-11-19.log
├─Charlie
│ ├─Alpha-2018-11-27.log
│ ├─Alpha-2018-11-18.log
│ └─Alpha-2018-11-04.log
└─Delta
└─Alpha-2018-11-27.log
Во втором каталоге я выполняю сценарий для \\ store2 \ output с Get-ChildItem -Recurse
, и он прекрасно работает!Однако, как только я пытаюсь сделать тот же сценарий для \\ store \ logs, он делает то, чего я не хочу.Я думаю, может быть, я не знаю, как правильно использовать -Recurse
.
Первое, что я делаю со сценарием, это создаю PSDrives для корневой папки журналов (например, $sourcedrive = New-PSdrive -Name E -PSProvider FileSystem -Root \\\store\logs
Затем я запускаю цикл, чтобы перебрать и сжать содержимое.Вот цикл Foreach
, но есть некоторые функции, которые я определяю в другом месте. Если мне нужно включить их, просто дайте мне знать, и я добавлю их, но это довольно длинный сценарий с включенными ими (всего 401 строка).
$Targets = (Get-ChildItem -Recurse -Path $SourceDrive | Where-Object { $_.PSIsContainer }).FullName
Write-Host "kicking off the foreach loop"
foreach ($Dir in $Targets) {
Write-Host "Looking for relevant files"
$Files = (Get-ChildItem -Recurse -Path $Dir -Exclude *.7z, *.zip | Where-Object { !$_.PSIsContainer -and $_.LastWriteTime -le (Get-Date).AddDays(-$Days)})
Write-Host "$($Files.count) files older than $Days days found in $Dir" -ForegroundColor Green
if ($files.Count -gt 0) {
Write-Host "Compressing files in $dir"
Compress-Files $Files #Moves the files into a working folder, then zips that folder
Write-Host "Checking if zip created succesfully"
if ($fileszipped = $true) {
#Now that the files are all zipped, we can remove the source files, or not
if ($nomove.IsPresent ) {
Write-Host "Zip created! Removing working directories from $Dir and clearing out old files, not moving zip"
Get-ChildItem -Recurse -Path $sourcedrive | Where-Object {
$_.PSIsContainer -and ($_.BaseName -like '*WorkingFiles*')
} | Remove-Item -Recurse -Verbose
} else {
#If we didn't specify -nomove, then we can copy the zips, then remove the source files
Write-Host "Zip created! Copying zip files now"
$destin = (Join-Path -Path $LTSdrive -ChildPath (Split-Path $dir -Leaf))
$ExitCode = Start-Robocopy -source $Dir -destin $destin -Verbose
#Assuming robocopy was successful, let's remove our working directory and the files we've just zipped
Write-Host "Checking if zip(s) copied succesfully"
if (ParseRobocopyOutput $ExitCode){
Write-Host "Zip(s) copied! Removing working directories from $Dir and clearing out old files"
Get-ChildItem -Recurse -Path $sourcedrive | Where-Object {
$_.PSIsContainer -and ($_.BaseName -like '*WorkingFiles*')
} | Remove-Item -Recurse -Verbose
}
}
}
}
}
Для справки, вот «фактическая» часть функции Compress-Files
:
$Path0 = $Path +"\WorkingFiles"
if ($Check -eq $false) {
New-Item -Path $Path -ItemType Directory -Name WorkingFiles -Verbose
}
$i = 0
while ($i -lt $Files.Count) {
$Path1 = $Path +"\"+ $Files[$i]
Move-Item -Path $Path1 -Destination $Path0 -Verbose
$i++
}
Когда я запускаю эту функцию, она работает так, как я хочу на\\ store2 \ Выходные папки. Но когда я запускаю его для \\ store \ logs, он пытается переместить все в \ ops \ scriptAlpha И все в \ ops \ scriptBeta в zip-файл в \ ops, который не подходитВ конце я хочу получить:
\\Archive
├─ops
│ ├─ScriptAlpha
│ │ └─ScriptA-archive-2018-11.7z
│ └─ScriptBeta
│ └─ScriptB-archive-2018-11.7z
├─Maintenance
│ ├─ScriptA
│ │ └─ScriptA-archive-2018-11.7z
│ └─ScriptBigly
│ └─ScriptB-archive-2018-11.7z
└─Output
├─Alpha
│ └─Alpha-archive-2018-11.7z
├─Bravo
│ └─Alpha-archive-2018-11.7z
└─Charlie
└─Alpha-archive-2018-11.7z
Вместо этого я получаю zip-архив, содержащий все ScriptAlpha (и его папки / файлы) и все ScriptBeta (и его папки)./ files) информация в WorkingFolder в файле \ opsВел, который застегивается на молнию все вместе.
Я подумал, что вместо этого я могу пройти через корень и передать каждый каталог в массив, затем обработать каждый элемент в массиве, чтобы увидеть, есть ли в нем файлы, и есть ли в нем файлы вэто, а затем сделать сжатые файлы.Тем не менее, я не знаю, будет ли это делать это или нет.Я немного застрял, мысленно.
Я ценю помощь!И что бы это ни стоило, я гуглил и искал ТАК, и я не могу ничего найти.