Powershell 根据超过 x 天的时间移动文件和文件夹

问题描述

我是 powershell 的新手,正在尝试学习从一个目录到另一个目录的基本文件移动。我的目标是将超过 18 个月的文件文件夹移动到作为计划任务运行的冷存储文件夹。我需要能够轻松修改它的目录以满足我们的需要。它需要保留文件夹结构,只移动符合上述参数的文件。我还需要它来记录它所做的一切,如果我知道哪里出了问题。 如果我运行它,它只会复制所有内容。如果我注释掉 %{copy-Item... 然后它运行并仅根据我的参数列出并记录它。我哪里出错了,还是我离基地很远?

是的,使用 robocopy 来做到这一点很容易,但我想使用 powershell 并从中学习。

#Remove-Variable * -ErrorAction SilentlyContinue; Remove-Module *; $error.Clear();
#Clear-Host
#Days older than
$Days = "-485"
#Path Variables
$Sourcepath = "C:\Temp1"
$DestinationPath = "C:\Temp2"
#Logging
$Logfile = "c:\temp3\file_$((Get-Date).ToString('MM-dd-yyyy_hh-mm-ss')).log"

#transcript logs all outputs to txt file 
Start-Transcript -Path $Logfile -Append
Get-ChildItem $Sourcepath -Force -Recurse | 
    Where-Object {$_.LastwriteTime -le (Get-Date).AddDays($Days)} | 
    % {copy-Item -Path $Sourcepath -Destination $DestinationPath -Recurse -Force}
Stop-Transcript

解决方法

问题

Copy-Item -Path $Sourcepath -Destination $DestinationPath -Recurse -Force

您始终为源和目标指定相同的路径。使用参数 -recurse,您将为每个匹配的文件复制整个目录 $SourcePath

解决方案

您需要使用 Copy-Item(又名 $_)变量将前面管道步骤的输出提供给 $PSItem,基本上在单项模式下使用 Copy-Item .

试试这个(GetRelativePath 方法需要 .NET >= 5.0):

Get-ChildItem $Sourcepath -File -Force -Recurse | 
    Where-Object {$_.LastwriteTime -le (Get-Date).AddDays($Days)} | 
    ForEach-Object {
        $relativeSourceFilePath = [IO.Path]::GetRelativePath( $sourcePath,$_.Fullname )
        $destinationFilePath    = Join-Path $destinationPath $relativeSourceFilePath
        $destinationSubDirPath  = Split-Path $destinationFilePath -Parent 

        # Need to create sub directory when using Copy-Item in single-item mode
        $null = New-Item $destinationSubDirPath -ItemType Directory -Force

        # Copy one file
        Copy-Item -Path $_ -Destination $destinationFilePath -Force 
    }

没有 GetRelativePath 的替代实现(适用于 .NET

Push-Location $Sourcepath   # Base path to use for Get-ChildItem and Resolve-Path

try {
    Get-ChildItem . -File -Force -Recurse | 
        Where-Object {$_.LastwriteTime -le (Get-Date).AddDays($Days)} | 
        ForEach-Object {
            $relativeSourceFilePath = Resolve-Path $_.Fullname -Relative
            $destinationFilePath    = Join-Path $destinationPath $relativeSourceFilePath
            $destinationSubDirPath  = Split-Path $destinationFilePath -Parent 

            # Need to create sub directory when using Copy-Item in single-item mode
            $null = New-Item $destinationSubDirPath -ItemType Directory -Force

            # Copy one file
            Copy-Item -Path $_ -Destination $destinationFilePath -Force 
        }
}
finally {
    Pop-Location   # restore previous location
}

附带说明,$Days = "-485" 应替换为 $Days = -485。 您当前创建的是字符串而不是数字,并依赖 Powershell 在“必要”时自动将字符串转换为数字的能力。但这并不总是有效,因此最好首先创建一个具有适当数据类型的变量。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...