使用Powershell在每个子目录中找到最旧的文件

时间:2019-05-07 17:52:56

标签: powershell

我的公司最近搬到了Outlook365。我们完全基于VDI,因此我们的用户配置文件存储在单个服务器上。结果,我们所有用户现在都拥有2个以上的.ost文件,占用了服务器上的存储空间。我想编写一个脚本来查找和删除多余的.ost文件。另外,我想安排脚本每月运行一次,以清理由于任何其他原因而发生的所有孤立的.ost。

我尝试了几种不同的解决方案,但似乎找不到正确的语法来仅标识每个子目录中的最旧/原始.ost,所有尝试均已从整个目录或目录中的所有.ost文件。

$Path = "<path>" 

$SubFolders = dir $Path -Recurse | Where-Object {$_.PSIsContainer} | ForEach-Object -Process {$_.FullName}

ForEach ($Folder in $SubFolders)
    {
    $FullFileName = dir $Folder | Where-Object {!$_.PSIsContainer} | Sort-Object {$_.LastWriteTime} -Descending | Select-Object -First 1     
    }

2 个答案:

答案 0 :(得分:0)

在循环内,您可以使用以下命令列出具有最旧LastWriteTime值的.ost文件。只需将-Descending标志添加到Sort-Object即可列出最新文件。

$FullFileName = foreach ($folder in $Subfolders) {
    $Get-ChildItem -Path $folder -Recurse -File -Filter "*.ost" |
      Sort-Object -Property LastWriteTime |
        Select-Object -Property FullName -First 1
}
$FullFileName

如果在$folder路径中仅找到一个.ost文件,它将仍然找到该文件。因此,只有一个文件时,您需要逻辑不删除。这不能保证它是最旧的文件。您可能需要最旧的CreationTime和最新的LastWriteTime的组合。以下将列出基于CreationTime的最早的.ost文件。

$FullFileName = foreach ($folder in $Subfolders) {
    Get-ChildItem -Path $folder -Recurse -File -Filter "*.ost" |
          Sort-Object -Property CreationTime |
            Select-Object -Property FullName -First 1
}
$FullFileName

另一个问题是在foreach循环中设置$FullFileName变量。这意味着它将在每次循环迭代中被覆盖。因此,如果在循环完成后检索该值,则只会找到最后一个值。将变量设置为foreach循环输出的结果将创建一个具有多个值的数组。

要仅在存在多个OST文件时输出OST文件路径,可以执行以下操作:

$FullFileName = foreach ($folder in $Subfolders) {
    $files = Get-ChildItem -Path $folder -Recurse -File -Filter "*.ost" |
          Sort-Object -Property LastWriteTime -Descending
    if ($files.count -ge 2) {
           $files | Select-Object -Property FullName -First 1
    }
$FullFileName

答案 1 :(得分:0)

这名班轮应该完成这项工作,并将最新的LastWriteTime保留在ost文件中

gci -Path $Path -directory | where {(gci -Path $_\*.ost).count -gt 1}|%{gci -Path $_\*.cmd|Sort-Object LastWriteTime -Descending|Select-Object -Skip 1|Remove-Item -WhatIf}

随后出现了更长的变体。

$Path = '<path>'
$Ext  = '*.ost'
Get-ChildItem -Path $Path -directory -Recurse | 
  Where-Object {(Get-ChildItem -Path "$_\$Ext" -File -EA 0).Count -gt 1} | 
    ForEach-Object {
      Get-ChildItem -Path "$_\$Ext" -File -EA 0| Sort-Object LastWriteTime -Descending | 
        Select-Object -Skip 1 | Remove-Item -WhatIf
    }

前两行评估包含多个.ost文件的文件夹 接下来的几行将迭代这些文件夹,并按LastWriteTime降序对其进行排序,跳过第一个(最新的)文件夹,并将其他文件夹通过-WhatIf参数传递给Remove-Item,以仅显示在测试期间将删除的内容。

您当然也可以将它们移到备份位置。