我正在尝试开发一个powershell脚本,它允许我归档所有超过2年的文件,并将其父目录复制到新的根文件夹。我还想在归档完成后删除原始文件和任何空目录。
我有以下函数,它应该允许我执行从测试脚本调用的第一部分(移动文件和父目录),但是它失败并出现错误:
Copy-Item:无法计算参数'Destination',因为它的参数被指定为脚本块而没有输入。如果没有输入,则无法评估脚本块。 在C:\ Users \ cfisher \ Documents \ WindowsPowerShell \ Modules \ ShareMigration \ ShareMigration.psm1:99 char:43 + Copy-Item -Force -Destination { +〜 + CategoryInfo:MetadataError:(:) [Copy-Item],ParameterBindingException + FullyQualifiedErrorId:ScriptBlockArgumentNoInput,Microsoft.PowerShell.Commands.CopyItemCommand
这是功能:
功能ArchiveFiles { [列出CmdletBinding()]
Param (
[Parameter(Mandatory=$True)][string]$SourceDirectory,
[Parameter(Mandatory=$True)][string]$DestinationDirectory,
[Parameter(Mandatory=$True)][ValidateSet('AddMinutes','AddHours','AddDays','AddMonths','AddYears')][string]$TimeUnit,
[Parameter(Mandatory=$True)][int]$TimeLength
)
Begin {
Write-Host "Archiving files..." -ForegroundColor Yellow -BackgroundColor DarkGreen
}
Process {
$Now = Get-Date
$LastWrite = $Now.$TimeUnit(-$TimeLength)
$Items = Get-ChildItem -Path $SourceDirectory -Recurse | where { $_.LastWriteTime -lt "$LastWrite" }
ForEach($Item in $Items) {
Copy-Item -Force -Destination {
If ($_.PSIsContainer) {
If (!(Test-Path -Path $_.Parent.FullName)) {
New-Item -Force -ItemType Directory -Path
(
Join-Path $DestinationDirectory $_.Parent.FullName.Substring($SourceDirectory.length)
)
}
Else {
Join-Path $DestinationDirectory $_.Parent.FullName.Substring($SourceDirectory.length)
}
}
Else {
Join-Path $DestinationDirectory $_.FullName.Substring($SourceDirectory.length)
}
}
}
}
End {
Write-Host "Archiving has finished." -ForegroundColor Yellow -BackgroundColor DarkGreen
}
}
我认为将Join-Path的结果作为输入传递给-Destination参数可以解决这个问题,但它似乎没有发挥作用。我是否需要为每条路径创建新项目?如果这看起来很草率,那对PowerShell来说是个新鲜事。我感谢任何建设性的批评和解决方案。
谢谢!
答案 0 :(得分:1)
您可以使用 Robocopy 来实现您的目标。
来源:要复制的内容
目的地:放置副本的位置
天数:复制前文件的最后访问时间应为多少
RemoveOldFiles:从源中删除已复制的文件和文件夹。
Robocopy有很多不同的选项,可以帮助您更轻松地实现这一目标
在这种情况下,我们正在使用
/ MINLAD:获取比上次访问日期更早的文件
/ e:复制子目录甚至是空目录
/ mov:移动文件而不是复制它们
Function ArchiveFileSystem([string]$Source, [string]$Destination, [int]$Days, [switch]$RemoveOldFiles){
$LastWrite = Get-date (Get-Date).AddDays(-$Days) -Format yyyyMMdd
robocopy $Source $Destination /MINLAD:$LastWrite /e (&{if($RemoveOldFiles -eq $true){'/mov'}})
}
ArchiveFileSystem -Source C:\TestSource -Destination C:\TestDestination -Days 1 -RemoveOldFiles