尝试遍历文件夹并对每个文件执行递归操作

时间:2017-08-09 15:27:51

标签: powershell recursion filesystems data-management

我正在尝试构建一个脚本,我可以根据上次访问日期删除旧文件。作为脚本的一部分,我想询问每个子文件夹,查找过去X天未访问的文件,在找到的文件的同一文件夹中创建日志,并在日志中记录文件详细信息,然后删除文件。

我认为我需要的是一个嵌套循环,循环1将获取每个子文件夹(Get-ChildItem -Directory -Recurse)然后对于每个文件夹找到第二个循环检查所有文件的最后访问日期,如果超出限制将附加文件详细信息到文件夹中的日志文件(供用户参考)以及主日志文件(用于IT管理员)

循环1按预期工作并获取子文件夹,但是我无法通过文件夹中的对象获取内循环,我试图在第一个循环中使用Get-ChildItem,这是正确的进场?

下面的代码示例,我已经添加了伪示意逻辑,它实际上是我需要帮助的循环:

# Set variables
$FolderPath = "E:TEST_G"
$ArchiveLimit = 7
$ArchiveDate = (Get-Date).AddDays(-$ArchiveLimit)
$MasterLogFile = "C:\Temp\ArchiveLog $(Get-Date -f yyyy-MM-dd).csv"

# Loop 1 - Iterate through each subfolder of $FolderPath
Get-ChildItem -Path $FolderPath -Directory -Recurse | ForEach-Object {
    # Loop 2 - Check each file in the Subfolder and if Last Access is past
    # $ArchiveDate take Action
    Get-ChildItem -Path $_.DirectoryName | where {
        $_.LastAccessTime -le $ArchiveDate
    } | ForEach-Object {
        # Check if FolderLogFile Exists, if not create it
        # Append file details to folder Log
        # Append File & Folder Details to Master Log 
    }
}

2 个答案:

答案 0 :(得分:1)

您的嵌套循环不需要递归(外部循环已经处理了这一点)。只需处理每个文件夹中的文件(确保排除文件夹日志):

Get-ChildItem -Path $FolderPath -Directory -Recurse | ForEach-Object {
    $FolderLogFile = Join-Path $_.DirectoryName 'FolderLog.log'
    Get-ChildItem -Path $_.DirectoryName -File | Where-Object {
        $_.LastAccessTime -le $ArchiveDate -and
        $_.FullName -ne $FolderLogFile
    } | ForEach-Object {
        'file details' | Add-Content $FolderLogFile
        'file and folder details' | Add-Content $MasterLogFile
        Remove-Item $_.FullName -Force
    }
}

您无需测试文件夹日志文件是否存在,因为Add-Content会在缺少文件时自动创建它。

答案 1 :(得分:0)

我认为你过度复杂了一些:

#Set Variables
$FolderPath = "E:\TEST_G"
$ArchiveLimit = 7
$ArchiveDate = (Get-Date).AddDays(-$ArchiveLimit)
$MasterLogFile = "C:\Temp\ArchiveLog $(get-date -f yyyy-MM-dd).csv"
If (!(Test-Path $MasterLogFile)) {New-Item $MasterLogFile -Force}

Get-ChildItem -Path $FolderPath -File -Recurse |
  Where-Object { $_.LastAccessTime -lt $ArchiveDate -and
                 $_.Extension -ne '.log' } |
  ForEach-Object {
    $FolderLogFile = Join-Path $_.DirectoryName 'name.log'
    Add-Content -Value "details" -Path $FolderLogFile,$MasterLogFile

    Try {
      Remove-Item $_ -Force -EA Stop
    } Catch {
      Add-Content -Value "Unable to delete item! [$($_.Exception.GetType().FullName)] $($_.Exception.Message)"`
                  -Path $FolderLogFile,$MasterLogFile
    }
  }

编辑: 由于您已经在管道中进行了递归操作,因此不需要多个递归循环。它功能强大,无需采取额外措施即可完成处理。来自另一个答案的Add-Content也是Out-File的优秀解决方案,因此我取代了我的。

但请注意,Add-Content -Force标记不会像New-Item那样创建文件夹结构。这就是$MasterLogFile声明下的行的原因。