对无文件文件夹进行递归操作-仅需要在包含文件的文件夹上工作

时间:2018-11-29 10:49:50

标签: powershell scripting windows-scripting

我正在使用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

在第二个目录中,我使用Get-ChildItem -Recurse针对\\ store2 \ output执行脚本,它运行良好!但是,一旦我尝试对\\ 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 \ Output文件夹中运行。但是,当我针对\\ store \ logs进行启动时,它会尝试将\ ops \ scriptAlpha中的所有内容和\ ops \ scriptBeta中的所有内容移动到\ ops中的zip文件中,这不符合需要。我希望最终得到的是:

\\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,其中包含\ ops级别的WorkingFolder中的所有ScriptAlpha(及其文件夹/文件)和所有ScriptBeta(及其文件夹/文件)信息,并将它们压缩在一起。

我当时想做的是遍历根目录并将每个目录馈入一个数组,然后对数组中的每个项目进行操作,以查看其中是否有文件,是否有文件,然后做压缩文件。但是,我不知道这样做是否可行。我有点被困在精神上。

感谢您的帮助!对于它的价值,我已经搜索并搜索了SO,但我真的找不到任何东西。

0 个答案:

没有答案