Ben
Ben

Reputation: 87

How to move files to Folder and Sub folder based on file name using Powershell?

Powershell beginner here. I tried coding this using Powershell, but without getting anywhere.

I have a list of Wav files that I need to move automatically into a folder based on the file name.

20190822091227_202123545.wav

20190822080957_202123545.wav

The file name determines the folder structure - Example

2019(This is the Year)08(This is the Month)22(This is the Day)_202123545.wav

So the folder structure will be

C:\Archive\2019(Year)\201908(YearMonth)\22(Day)
C:\Archive\2019\201908\22 

and the wav files will move to that folder - In this case its 22

I have tried this code that I found here on Stackoverflow and added my own, but its giving me errors.

$SourceFolder = Set-Location "C:\CR\Files"
$targetFolder = "C:\Archive\CR_Dev\Test_Folder"
$numFiles = (Get-ChildItem -Path $SourceFolder -Filter *.WAV).Count
$i=0

clear-host;
Write-Host 'This script will copy ' $numFiles ' files from ' $SourceFolder ' to ' $targetFolder
Read-host -prompt 'Press enter to start copying the files'

$files = Get-ChildItem $SourceFolder | where {$_.extension -in ".wav"} | select -expand basename

 # Out FileName, year and month
    $Year = $files.Substring(0,4)
    $Month = $files.Substring(4,2)
    $Day = $files.Substring(6,2)

foreach ($file in $files)

{

    # Set Directory Path
    $Directory = $targetFolder + "\" + $Year+$Month + "\" + $Day

    # Create directory if it doesn't exsist
    if (!(Test-Path $Directory))
    {
    New-Item $Directory -type Directory
    }

    [int]$percent = $i / $numFiles * 100

    # Move File to new location
    $file | Copy-Item -Destination $Directory

    Write-Progress -Activity "Copying ... ($percent %)" -status $_  -PercentComplete $percent -verbose
    $i++
}

Write-Host 'Total number of files read from directory '$SourceFolder ' is ' $numFiles
Write-Host 'Total number of files that was copied to '$targetFolder ' is ' $i
Read-host -prompt "Press enter to complete..."
clear-host;

The files are not moving to the folder and I am getting error in the file names

Example

C:\Archive\2019 2019\2019 08 2019 08\22 22

Upvotes: 1

Views: 591

Answers (1)

briantist
briantist

Reputation: 47772

$files is named appropriately plural as a variable that could contain many files. But when you go to retrieve the date parts, you use call it once, on the whole collection of files, instead of on each individual $file (which is the variable you have inside the loop which iterates over the collection of files).

So you want to set the date variables inside the loop, on every iteration, so that it's related to the current file.

$files = Get-ChildItem $SourceFolder | where {$_.extension -in ".wav"} | select -expand basename

foreach ($file in $files)
{
    $Year = $file.Substring(0,4)
    $Month = $file.Substring(4,2)
    $Day = $file.Substring(6,2)

   $Directory = $targetFolder + "\" + $Year+$Month + "\" + $Day

# etc
}

Also the pattern you laid out in your question doesn't seem to be what you're setting, so I'm a little confused how your output looks like it does.

What you have here:

$Directory = $targetFolder + "\" + $Year+$Month + "\" + $Day

Should produce: C:\Archive\201908\22 even though you want C:\Archive\2019\201908\22.

To produce what you wanted the line should be like this:

$Directory = $targetFolder + "\" + $Year + "\" + $Year+$Month + "\" + $Day

By the way you can use variables directly in double-quoted strings:

$Directory = "$targetFolder\$Year\$Year$Month\$Day"

Upvotes: 2

Related Questions