Philip Loyer
Philip Loyer

Reputation: 768

How to move folders from one location to another using PowerShell

So i have a directory full of folders that i want to move to another area, also i only want to move the folders that were created 30 days ago or more. I have a script that does what i need for files but it doesnt seem to work for folders. Script is below

Script for moving files

 param (
    [Parameter(Mandatory=$true)][string]$destinationRoot
 )

$path = (Get-Item -Path ".\").FullName

Get-ChildItem -Recurse | ?{ $_.PSIsContainer }
Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} |
Foreach-Object {
    $content = $path + "\" + $_.Name

    $year = (Get-Item $content).LastWriteTime.year.ToString()
    $monthNumber = (Get-Item $content).LastWriteTime.month
    $month = (Get-Culture).DateTimeFormat.GetMonthName($monthNumber)

    $destination = $destinationRoot + "\" + $year + "\" + $month 

    New-Item -ItemType Directory -Force -Path $destination

    Move-Item -Path $content -Destination $destination -force

}

The Get-ChildItem portion does not seem to pull directories in like it should.

Upvotes: 0

Views: 1043

Answers (1)

ArcSet
ArcSet

Reputation: 6860

So looking at the script i decided to change some things up

Function Move-FilesByAge(){
    param (
        [Parameter(Mandatory=$true)][string]$Source,
        [Parameter(Mandatory=$true)][string]$Destination,
        [Parameter(Mandatory=$true)][timespan]$AgeLimit
     )

    Get-ChildItem $Source -Directory -Recurse | ?{
        $($_.CreationTimeUtc.Add($AgeLimit)) -lt $((Get-Date).ToUniversalTime())
    } | %{
        $Dpath = $Destination + "\" + $_.CreationTimeUtc.ToString("yyyy") + "\" + $_.CreationTimeUtc.ToString("MMMM")
        New-Item -ItemType Directory -Force -Path $Dpath
        Move-Item $_ -Destination $Dpath -Force
    }
}

Move-FilesByAge -Source C:\Test -Destination C:\Test2 -AgeLimit (New-TimeSpan -days 30)

This can lead to a major issue. If a folder with the same name exists then it will pop a error that folder exists.

Since you are new to powershell lets go over some basics about this script. In Powershell we love Piping | which you did well in the original. We also a big fan of aliases Where-Object ?{}, Foreach-Object %{}.

Get-ChildItem has a built in switch for just returning directories -directory.

You are also using last LastWriteTime when you should be using CreationTime. CreationTimeUtc allows you to standardize your time across timezones by providing a base timezone.

Date.ToString(Date Format Here). IS a great way to shorten how you parse the date as a string. .ToString("yyyy") gets you the year in 4 numbers like 2018. .ToString("MMMM") will get the month by name like March.

Upvotes: 1

Related Questions