我找到了下面的脚本,并尝试使用它来自动监视文件夹并删除超过 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
#>