【问题标题】:How to Delete multiple files older than X days from different locations?如何从不同位置删除超过 X 天的多个文件?
【发布时间】:2016-03-16 20:23:15
【问题描述】:
#----- define parameters -----#
#----- get current date ----#
$Now = Get-Date

#----- define amount of days ----#
$Days = "3"
#----- define folder where files are located ----#
$TargetFolder = "C:\test2"
#----- define extension ----#
$Extension = "*.*"
#----- define LastWriteTime parameter based on $Days ---#
$LastWrite = $Now.AddDays(-$Days)

#----- get files based on lastwrite filter and specified folder ---#
$Files = Get-ChildItem $TargetFolder -Include $Extension -Recurse |
         Where  {$_.LastWriteTime -le "$LastWrite"} 

foreach ($File in $Files) {
    if ($File -ne $NULL) {
        Write-Host "Deleting File $File" -ForegroundColor "Red"
        Remove-Item $File.FullName | Out-Null
    } else {
        Write-Host "No more files to delete!" -foregroundcolor "Green"
    }
}

这是一个很好的 PowerShell 脚本,可以删除超过 X 天的文件,但我们想删除保存在不同位置的多个文件,每个路径的天数不同。

例如,如果我们必须删除超过 3 天的文件,那么我们可以像这个例子一样添加另一个位置:

$TargetFolder = "C:\test","C:\test2" 

它会处理这两个文件夹,但我们想知道是否有一种方法可以为不同的文件夹设置不同的天数。

ksh 中,我们曾经在配置文件中这样做:

Location 1;//Server1/c$/processed;14
位置 2;//Server2/backup/;3

【问题讨论】:

    标签: powershell


    【解决方案1】:

    使用“年龄”和“位置”等参数调用脚本

    Param
    (
        [int]$days,
        [string]$Targetfolder
    )
    #----- define parameters -----#
    #----- get current date ----#
    $Now = Get-Date
    
    #----- define amount of days ----#
    #$Days = '3'
    #----- define folder where files are located ----#
    #$TargetFolder = 'C:\test2'
    #----- define extension ----#
    $Extension = '*.*'
    #----- define LastWriteTime parameter based on $Days ---#
    $LastWrite = $Now.AddDays(-$Days)
    
    #----- get files based on lastwrite filter and specified folder ---#
    $Files = Get-Childitem $TargetFolder -Include $Extension -Recurse | Where-Object  {$_.LastWriteTime -le "$LastWrite"} 
    
    foreach ($File in $Files) 
    {
        if ($File -ne $NULL)
        {
            write-host "Deleting File $File" -ForegroundColor 'Red'
            Remove-Item $File.FullName | out-null
        }
        else
        {
            Write-Host 'No more files to delete!' -foregroundcolor 'Green'
        }
    }
    

    将其保存为 .ps1 并像 MyScript.ps1 -Targetfolder C:\Blah -Days 4 一样调用它。

    【讨论】:

    • 去掉$lastwrite周围的引号
    • 非常感谢@restless1987!它就像一个魅力!并感谢大家的宝贵意见 - 谢谢/阿德南
    • @Altimo 如果您发现它解决了您的问题,请考虑accepting the answer
    【解决方案2】:

    这是我的解决方案。您可以通过复制/粘贴到脚本中来使用它。然后,这样称呼它:

    PS> $Folders = 'C:\Folder1','C:\Folder2'
    PS> .\Remove-OldFiles.ps1 -FolderPath $Folders -DaysOld 30 -WhatIf
    

    然后,如果一切正常,请删除 -WhatIf。这应该比您拥有的脚本快得多,因为它使用 PSv4 中较新的 .where() 和 .foreach() 方法。

    #Requires -Version 4
    
    [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'High')]
    param (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string[]]$FolderPath,
    
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [int]$DaysOld,
    
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [ValidateLength(1, 3)]
        [string]$FileExtension
    )
    
    $Now = Get-Date
    
    $gciParams = @{
        'Recurse' = $true
        'File' = $true
    }
    
    if ($PSBoundParameters.ContainsKey('FileExtension')) {
        $gciParams.Filter = "Extension -eq $FileExtension"
    }
    
    $LastWrite = $Now.AddDays(-$DaysOld)
    
    foreach ($path in $FolderPath)
    {
        $gciParams.Path = $path
        ((Get-ChildItem @gciParams).Where{ $_.LastWriteTime -le $LastWrite }).foreach{
            if ($PSCmdlet.ShouldProcess($_.FullName, 'Remove'))
            {
                Remove-Item -Path $_.FullName -Force
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      我建议按照@restless1987 的建议对脚本进行参数化。但是,如果您想从文件中读取信息,您可以在第二个 PowerShell 脚本中创建一个哈希表:

      # config.ps1
      
      $locations = @{
        'C:\processed' = 14
        'D:\backup'    = 3
      }
      

      dot-source 脚本中的那个文件:

      . 'C:\path\to\config.ps1'
      

      所以你可以像这样使用哈希表:

      foreach ($TargetFolder in $locations.Keys) {
          $LastWrite = $Now.AddDays(-$locations[$TargetFolder])
          $Files = Get-ChildItem $TargetFolder -Include $Extension -Recurse |
                   Where-Object  {$_.LastWriteTime -le $LastWrite} 
      
          foreach ($File in $Files) {
              ...
          }
      }
      

      【讨论】:

        【解决方案4】:

        为您的工作创建一个函数,并将您的路径保存在哈希表中。

        $targetFolder = @()
        
        $targetFolder += @{'Folder'='c:\test1'; 'Extension'='*.*'; 'Days'=3}
        $targetFolder += @{'Folder'='c:\test2'; 'Extension'='*.*'; 'Days'=5}
        $targetFolder += @{'Folder'=@('c:\test3', 'c:\test4'); 'Extension'='*.*'; 'Days'=7}
        
        function DeleteOldFiles($TargetFolder, $Extension, $Days)
        {
            $lastWrite = (Get-Date).AddDays(-$Days)
        
            # do your Get-ChildItem logic here
            $files = Get-Childitem $TargetFolder -Include $Extension -Recurse | Where  {$_.LastWriteTime -le "$lastWrite"} 
        
            foreach ($file in $files) 
            {
                if ($file -ne $null)
                {
                    Write-host "Deleting File $file" -ForegroundColor "Red"
                    Remove-Item $file.FullName | out-null
                }
                else
                {
                    Write-Host "No more files to delete!" -foregroundcolor "Green"
                }
            }
        }
        
        $targetFolder | DeleteOldFiles $_.Folder $_.Extension $_.Days
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多