Home > Back-end >  PowerShell Copy All Files in Folders and Sub=Folders Not older than 300 minutes
PowerShell Copy All Files in Folders and Sub=Folders Not older than 300 minutes

Time:05-02

I am trying to copy all files in folders and sub-folders not older than 300 minutes, but the code I got working only copies the files in the main folder, it doesn't copy the files in subfolders. At the destination I don't want to maintain the folder structure of the original files, I just want to put all the origin files into a single specific destination folder. This is the code I have:

Powershell -NoL -NoP -C "&{$ts=New-TimeSpan -M 300;"^
 "Get-ChildItem "C:\Origin" -Filter '*.dat'|?{"^
 "$_.LastWriteTime -gt ((Get-Date)-$ts)}|"^
 %%{Copy-Item $_.FullName 'C:\Destination'}}"

Could someone help me out please? Thanks in advance.

CodePudding user response:

Here's a modified script for you you can save as "Copy-Unique.ps1" you can run from a batch file.

function Copy-Unique {
    # Copies files to a destination. If a file with the same name already exists in the destination,
    # the function will create a unique filename by appending '(x)' after the name, but before the extension. 
    # The 'x' is a numeric sequence value.
    [CmdletBinding(SupportsShouldProcess)]  # add support for -WhatIf switch
    Param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
        [Alias("Path")]
        [ValidateScript({Test-Path -Path $_ -PathType Container})]
        [string]$SourceFolder,

        [Parameter(Mandatory = $true, Position = 1)]
        [string]$DestinationFolder,

        [Parameter(Mandatory = $true, Position = 2)]
        [int]$NewerThanMinutes = -1,

        [Parameter(Mandatory = $false)]
        [string]$Filter = '*',

        [switch]$Recurse
    )

    # create the destination path if it does not exist
    if (!(Test-Path -Path $DestinationFolder -PathType Container)) {
        Write-Verbose "Creating folder '$DestinationFolder'"
        $null = New-Item -Path $DestinationFolder -ItemType 'Directory' -Force
    }
    # get a list of file FullNames in this source folder
    $sourceFiles = @(Get-ChildItem -Path $SourceFolder -Filter $Filter -File -Recurse:$Recurse)
    # if you want only files not older than x minutes, apply an extra filter
    if ($NewerThanMinutes -gt 0) {
        $sourceFiles = @($sourceFiles | Where-Object { $_.LastWriteTime -gt (Get-Date).AddMinutes(-$NewerThanMinutes).Date })
    }
    foreach ($file in $sourceFiles) {
        # get an array of all filenames (names only) of the files with a similar name already present in the destination folder
        $destFiles = @((Get-ChildItem $DestinationFolder -File -Filter "$($file.BaseName)*$($file.Extension)").Name)
        # for PowerShell version < 3.0 use this
        # $destFiles = @(Get-ChildItem $DestinationFolder -Filter "$baseName*$extension" | Where-Object { !($_.PSIsContainer) } | Select-Object -ExpandProperty Name)

        # construct the new filename
        $newName = $file.Name
        $count = 1
        while ($destFiles -contains $newName) {
            $newName = "{0}({1}){2}" -f $file.BaseName, $count  , $file.Extension
        }
        # use Join-Path to create a FullName for the file
        $newFile = Join-Path -Path $DestinationFolder -ChildPath $newName
        Write-Verbose "Copying '$($file.FullName)' as '$newFile'"

        $file | Copy-Item -Destination $newFile -Force
    }
}

# you can change the folder paths, file pattern to filter etc. here
Copy-Unique -SourceFolder 'C:\Origin' -DestinationFolder 'C:\Destination' -Filter '*.dat' -Recurse -NewerThanMinutes 300

When you have saved the above code to let's say 'C:\Scripts\Copy-Unique.ps1' you can then call it from a batch file like:

Powershell.exe -NoLogo -NoProfile -File "C:\Scripts\Copy-Unique.ps1"
  • Related