Trying to learn Powershell by giving myself a complicated task it would appear

Still trying to learn Powershell and the enjoyment of getting a script working that remove a - from thousands of files was great the other day.

So then thought I could use Powershell on my disorganised photos.

I’ve manged, in my test to look in a specific directory and all its child directories for all files with extension *.jpg

Worked nice. They all moved to the correct folder. Then I messed the command up with the ,

Get-ChildItem -path c:\testing\*.jpg,*.png

Not realising after that command it was now going to scan the whole laptop and move the *.png files and not just from the testing folder.

Anyway. What I’m now trying to do is appearing complicated. Like my disorganised photos collection, my dad also has the same. But in some folders we’ll have

c:\photos\march

c:\photos\April

Etc. I’ve now decided I want to keep the folder structure. So before I was going to move all the photos to one directory. I now want to go into the March folder. Check all files that are in there and move all *.jpg files to another folder called March and then any videos that are in that directory, move them to a new folder in March called videos.

This is where I got lost. Searching for all *.jpg files and moving them seems easier but keeping the folder structure seems like it might be a lot more difficult.

Any ideas would be great.

Well, just to clarify the code you posted, try this:

Get-ChildItem -path c:\testing\ -Recurse -Include .jpg,.png

$file = Get-ChildItem C:\photos\ -Recurse -Include *.jpg,*.png
$dest = '\\path\to\destination\'

# Create folder structure then move files
foreach ($f in $file){
    $path1 = split-path (split-path $f.FullName -NoQualifier)
    $path2 = Join-Path -Path $dest -ChildPath $path1
    New-Item -Path $path2 -ItemType Directory -ErrorAction SilentlyContinue
    $f | Move-Item -Destination $path2
}

Ooo thanks to both. That works. I thought the script would end up longer than that. I’m now gonna go through it so I understand each command because I’ve always been confused by foreach loops where you have the likes of that

$f in $file

I can see the variable $file declared but can’t work out what the $f is? Doing some reading it suggests this is the “placeholder” variable for reading data that is currently stored in $file. So I’m assuming $f could even be called $placeholdervariable if I wanted?

I also like to break scripts down so I can understand every part of it.

As you say, you can name $f anything you want as it’s basically just used within the foreach-loop (and then implicitly discarded - You can in principle call it again later in the script but at that time it will only contain the last referenced image).

If you put a $file.GetType() somewhere in the script, or just run:

$file = Get-ChildItem C:\photos\ -Recurse -Include *.jpg,*.png
$file.GetType()

You will see that it is an array; a list of all the .jpg and .png files found by Get-Item. On the first pass through the foreach-loop $f will contain the first file in the array, on the next pass $f will contain the second file in the array and so on until it reaches the end of the list.