首页 > 解决方案 > 当我将对象属性从“LastWriteTime”更改为“CreationTime”时,我的脚本不起作用,它只是删除了所有内容?

问题描述

我最近一直在疯狂地跑来跑去这个脚本,我试图修改它以满足我的需要。我最近发现使用“LastWriteTime”删除文件并不是我想要的。

我需要我的脚本做的是使用“CreationTime”属性删除超过 30 天的文件,问题是在我修改脚本以使用它之后,它会删除整个文件夹结构?

这个小修改如何改变整个脚本的行为?

这就是我使用的:

$limit = (Get-Date).AddDays(-30)

$del30 = "D:\CompanyX_ftp\users"

$ignore = Get-Content "C:\Users\UserX\Documents\Scripts\ignorelist.txt"

Get-ChildItem $del30 -Recurse | 

Where-Object {$_.CreationTime -lt $limit } |

Select-Object -ExpandProperty FullName |

Select-String -SimpleMatch -Pattern $ignore -NotMatch | 

Select-Object -ExpandProperty Line |

Remove-Item -Recurse

因此,如果我用“LastWriteTime”替换“CreationTime”属性,脚本将运行并执行它应该做的事情,但如果我使用“CreationTime”,它只会删除文件夹结构下的所有内容,包括文件夹本身和它应该的路径无视。

更新:该脚本现在正在为我工​​作以实际删除文件,但对于我用来获取脚本将删除的实际文件的报告的脚本实际上包括 ignorelist.txt 文件的路径?请看下面的脚本:

$limit = (Get-Date).AddDays(-30)

$del30 = "D:\CompanyX_ftp\users"

#Specify path for ignore-list

$ignore = Get-Content "C:\Users\UserX\Documents\Scripts\ignorelist.txt"

Get-ChildItem $del5 -File -Recurse | 

Where-Object {$_.CreationTime -lt $limit } |

Select-Object -ExpandProperty FullName |

Select-String -SimpleMatch -Pattern $ignore -NotMatch | 

Select-Object -ExpandProperty Line |

Get-ChildItem -Recurse | Select-Object FullName,CreationTime

ignorelist.txt样本数据:

D:\CompanyX_ftp\users\ftp-customerA\客户下载
D:\CompanyX_ftp\users\ftp-customerB\客户下载
D:\CompanyX_ftp\users\ftp-customerC\客户下载
D:\CompanyX_ftp\users\ftp-customerD\客户下载
D:\CompanyX_ftp\users\ftp-customerE\客户下载
D:\CompanyX_ftp\users\ftp-customerF\客户下载
D:\CompanyX_ftp\users\ftp-customerG\客户下载
D:\CompanyX_ftp\users\ftp-客户H\客户下载\

关于为什么它包括我在 ignorelist.txt 中提到的路径的任何想法?(我还将提供一张图片以便更好地说明)。

在此先感谢您提供任何帮助或指导。

//伦纳特

标签: powershellautomation

解决方案


我发现更新后的代码存在两个问题:

  • 重复递归。首先Get-ChildItem递归地遍历目录的内容。稍后在管道中,另一个递归迭代开始于第一个返回的项目Get-ChildItem,导致重叠。
  • 过滤时$ignore,只有与路径完全匹配的$ignore路径才会被忽略。忽略列表中项目的子路径不会被忽略。

这是我将如何做到这一点。创建一个Test-IgnoreFile将给定路径与忽略列表匹配的函数,检查当前路径是否以忽略列表中的任何路径开头。这样子路径也被忽略了。这使我们能够大大简化管道。

Param(
    [switch] $ReportOnly
)

# Returns $true if $File.Fullname starts with any path in $Ignore (case-insensitive)
Function Test-IgnoreFile( $File, $Ignore ) {
    foreach( $i in $Ignore ) { 
        if( $File.FullName.StartsWith( $i, [StringComparison]::OrdinalIgnoreCase ) ) { 
            return $true
        }
    }
    $false
}

$limit = (Get-Date).AddDays(-30)

$del30 = "D:\CompanyX_ftp\users"

$ignore = Get-Content "C:\Users\UserX\Documents\Scripts\ignorelist.txt"

Get-ChildItem $del30 -File -Recurse |
    Where-Object { $_.CreationTime -lt $limit -and -not ( Test-IgnoreFile $_ $ignore ) } |
    ForEach-Object {
        if( $ReportOnly) {
            $_ | Select-Object FullName, CreationTime
        }
        else {
            $_ | Remove-Item -Force
        }
    }

推荐阅读