Powershell 脚本用于删除 X 天前的文件,并不断提示确认子文件

Powershell 脚本用于删除 X 天前的文件,并不断提示确认子文件

我找到了下面的脚本,并尝试使用它来自动监视文件夹并删除超过 2 天的文件。我遇到的问题是系统提示“G:\test\XXX 中的项目有子项,并且未指定 Recurse 参数”。

我试图弄清楚应该把这个参数放在哪里,但没有成功。有谁能帮我吗?

Set-StrictMode -Version Latest

# Function to remove all empty directories under the given path.
# If -DeletePathIfEmpty is provided the given Path directory will also be deleted if it is empty.
# If -OnlyDeleteDirectoriesCreatedBeforeDate is provided, empty folders will only be deleted if they were created before the given date.
# If -OnlyDeleteDirectoriesNotModifiedAfterDate is provided, empty folders will only be deleted if they have not been written to after the given date.
function Remove-EmptyDirectories([parameter(Mandatory)][ValidateScript({Test-Path $_})][string] $Path, [switch] $DeletePathIfEmpty, [DateTime] $OnlyDeleteDirectoriesCreatedBeforeDate = [DateTime]::MaxValue, [DateTime] $OnlyDeleteDirectoriesNotModifiedAfterDate = [DateTime]::MaxValue, [switch] $OutputDeletedPaths, [switch] $WhatIf)
{
    Get-ChildItem -Path $Path -Recurse -Force -Directory | Where-Object { (Get-ChildItem -Path $_.FullName -Recurse -Force -File) -eq $null } | 
        Where-Object { $_.CreationTime -lt $OnlyDeleteDirectoriesCreatedBeforeDate -and $_.LastWriteTime -lt $OnlyDeleteDirectoriesNotModifiedAfterDate } | 
        ForEach-Object { if ($OutputDeletedPaths) { Write-Output $_.FullName } Remove-Item -Path $_.FullName -Force -WhatIf:$WhatIf }

    # If we should delete the given path when it is empty, and it is a directory, and it is empty, and it meets the date requirements, then delete it.
    if ($DeletePathIfEmpty -and (Test-Path -Path $Path -PathType Container) -and (Get-ChildItem -Path $Path -Force) -eq $null -and
        ((Get-Item $Path).CreationTime -lt $OnlyDeleteDirectoriesCreatedBeforeDate) -and ((Get-Item $Path).LastWriteTime -lt $OnlyDeleteDirectoriesNotModifiedAfterDate))
    { if ($OutputDeletedPaths) { Write-Output $Path } Remove-Item -Path $Path -Force -WhatIf:$WhatIf }
}

# Function to remove all files in the given Path that were created before the given date, as well as any empty directories that may be left behind.
function Remove-FilesCreatedBeforeDate([parameter(Mandatory)][ValidateScript({Test-Path $_})][string] $Path, [parameter(Mandatory)][DateTime] $DateTime, [switch] $DeletePathIfEmpty, [switch] $OutputDeletedPaths, [switch] $WhatIf)
{
    Get-ChildItem -Path $Path -Recurse -Force -File | Where-Object { $_.CreationTime -lt $DateTime } | 
        ForEach-Object { if ($OutputDeletedPaths) { Write-Output $_.FullName } Remove-Item -Path $_.FullName -Force -WhatIf:$WhatIf }
    Remove-EmptyDirectories -Path $Path -DeletePathIfEmpty:$DeletePathIfEmpty -OnlyDeleteDirectoriesCreatedBeforeDate $DateTime -OutputDeletedPaths:$OutputDeletedPaths -WhatIf:$WhatIf
}

# Delete all files created more than 2 days ago.
Remove-FilesCreatedBeforeDate -Path "G:\test" -DateTime ((Get-Date).AddDays(-2)) -DeletePathIfEmpty

# Delete all empty directories in the Transport Fotografie folder.
Remove-EmptyDirectories -Path "G:\test"

答案1

您的脚本太复杂了,客观地说,脚本写得不是很好。有更好的方法可以实现您的意图,而且它们可以更简单。

基本上,你想做的事情可以通过以下方式实现:

Get-ChildItem -Path "path\to\folder" -Force -Recurse -Directory | Where {$_.LastWriteTime -lt $((Get-Date).AddDays(-2))} | %{Remove-Item -Path $_.Fullname -Force -Recurse}
Get-ChildItem -Path "path\to\folder" -Force -Recurse -File | Where {$_.LastWriteTime -lt $((Get-Date).AddDays(-2))} | %{Remove-Item -Path $_.Fullname -Force}

这应该会删除所有超过 2 天的文件和文件夹。我想知道您是否觉得这个答案有帮助。

答案2

同意 SEL3NA 的说法...

你的脚本太复杂了

至于这个...


“自动监控文件夹并删除 2 天前的文件夹。”


只需使用一个计划任务,每小时(或其他时间)检查一次,运行一个简单的命令/脚本(按照 SEL3NA 示例)日期检查,删除匹配的文件,或者像我下面提供的那样。

注意事项:

以下并非全部都是必需的。这只是一个示例,用于展示您陈述用例时的端到端方法。只有这一块才是您的最终目标所需要的...

Remove-Item -Path $(Get-ChildItem -Path $RootFolder -Force -Recurse -ErrorAction Stop | 
Where-Object -Property LastWriteTime -lt (Get-Date).AddDays(-2)).FullName

...剩下的就是逻辑(你可以做任何你想做的事)在执行破坏性代码(添加/修改/更新、删除/移除/移动)之前进行自我检查,并验证前后结果。永远不要在未先验证的情况下运行破坏性代码。如果不这样做,你会发现自己处于非常糟糕的状态,尤其是在没有备份的情况下。

您只需使用上述命令并手动创建计划任务,即可在任意时间运行它。因此无需单独的脚本。

<#
.Synopsis
   Delete legacy files
.DESCRIPTION
   Remove all files in the target folder and sub-folders that are older than 2 days.
.EXAMPLE
   ---
.NOTE
    This will check for a scheduled task for a scheduled removal.
    Creates the task if it does not exist 
    Execute the remove, reporting on begin and end state results
    Removes the task
#>

[cmdletbinding(SupportsShouldProcess)]
Param
(
    [Parameter(Mandatory = $true)][string]$RootFolder
)

Try 
{
    If (-Not (Get-ScheduledTask -TaskName 'RemoveDatedFiles' -ErrorAction SilentlyContinue))
    {
        $ExecutableAction = $(New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument "-NoProfile -command & { Remove-Item -Path $(Get-ChildItem -Path $RootFolder -Force -Recurse -ErrorAction Stop | 
        Where-Object -Property LastWriteTime -lt (Get-Date).AddDays(-2)).FullName}")
        $Trigger          = New-ScheduledTaskTrigger -Once -At $("{0:hhtt}" -f (get-date).AddHours(1))
        Register-ScheduledTask -Action $ExecutableAction -Trigger $Trigger -TaskName 'RemoveDatedFiles' -Description 'Remove the target executable.'
    }

    Write-Host "Current file count [before] cleanup is: $((Get-ChildItem -Path $RootFolder).Count)" -ForegroundColor Yellow
}
Catch
{
    Write-Warning -Message 'Some other error occurred.'
    $PSItem.Exception.Message
}
Finally
{
    Write-Verbose "Current file count [after] cleanup is: $((Get-ChildItem -Path $RootFolder).Count)" -Verbose
    # Unregister-ScheduledTask -TaskName 'RemoveDatedFiles' -Confirm:$false
}

作为独立脚本运行以进行测试。

.\Remove-DatedFiles.ps1 -RootFolder 'C:\Temp' -WhatIf
# Results via WhatIf validation
<#
Current file count [before] cleanup is: 243
...
What if: Performing the operation "Remove File" on target "C:\Temp\(MSINFO32) command-line tool switches.pdf".
What if: Performing the operation "Remove File" on target "C:\Temp\23694d1213305764-revision-number-in-excel-book1.xls".
...
VERBOSE: Current file count [after] cleanup is: 243
#>

.\Remove-DatedFiles.ps1 -RootFolder 'C:\Temp'
# Results without WhatIf validation
<#
Current file count [before] cleanup is: 243
VERBOSE: Current file count [after] cleanup is: 26
#>

相关内容