Copying a file to all subfolders and renaming it

A friend asked me about this issue. He needed to copy a onenote file to all subfolders and rename the file accordingly. This is how I did it.

Copying a file to all subfolders and renaming it

My friend wanted the copied file to be renamed to the folder number + "example.one". For example in the subfolder "123 Madeup"the file should be called "123 example.one". He also had some subfolders where this file already existed so it should not overwrite it.

The good thing is that all subfolders were labeled correctly, a 3 to 5 digit number, followed by a whitespace and then the folder name. This lets us easily get the number in a variable by just reading everything until the first whitespace.

There are probably much better ways to do it but this is how my script looked:

$folders = Get-ChildItem  -Directory '.\rootfolder\' 
$file = " example.one"

foreach ($folder in $folders) {

    $rename = ($folder.FullName -split (" "))[0].split('\')[-1]
    Write-Output $folder.FullName
    $newname = "$($rename)$($file)"

    if (-not(Test-Path -Path  "$($folder.fullname)\$($newname)" -PathType Leaf)) {
        try {
            Copy-Item -Path "example.one" -Destination "$($folder.fullname)\$($newname)" -Recurse -Whatif 
            Write-Host "The file [$newname] has been created."
        }
        catch {
            throw $_.Exception.Message
        }
    }
    else {
        Write-Host "Cannot create [$newname] because a file with that name already exists."
    }
    
}

First I set 2 variables, $folders is the rootdirectory above the subfolders and $file will be the filename (I would probably rename this variable since $file can cause confusion).

$folders = Get-ChildItem  -Directory '.\rootfolder\' 
$file = " example.one"

The second part is the way I go through all the subfolders. For this i just run a foreach through the folders in the directory $folders. The $rename variable splits the current subfolder name on the first whitespace. This can also be done with regex. The Write-Output just writes the subfolder name to the console for checking purposes.

I also create a newname file with the conjugated string of the variable $rename and $file. I could also do this in the actual copying part that follows.

foreach ($folder in $folders) {

    $rename = ($folder.FullName -split (" "))[0].split('\')[-1]
    Write-Output $folder.FullName
    $newname = "$($rename)$($file)"
    
}

To copy the file I use copy-item, however the default behavior of copy-item actually overwrites files at the destination. So I ask if the path and file already exists and if it does not I will try to copy the file to the destination. If it does already exists it will just skip this subfolder.

    if (-not(Test-Path -Path  "$($folder.fullname)\$($newname)" -PathType Leaf)) {
        try {
            Copy-Item -Path "example.one" -Destination "$($folder.fullname)\$($newname)" -Recurse -Whatif 
            Write-Host "The file [$newname] has been created."
        }
        catch {
            throw $_.Exception.Message
        }
    }
    else {
        Write-Host "Cannot create [$newname] because a file with that name already exists."
    }
    


For the first try I always leave in -whatif to see if there would be any issues. Just remove that flag once you want to actually copy for real.

Optimizations:

If I were to optimize this script I would probably get rid of the $rename/$newname variables and log the output to a file so I dont have to scroll through the console in case something goes wrong.

Special thanks:

Special thanks to another friend Mikail Aras for showing me how to do the things I know from python in powershell.

He writes articles in german about powershell at: https://germanpowershell.com/author/mikailaras/

Great! Next, complete checkout for full access to KHDev.
Welcome back! You've successfully signed in.
You've successfully subscribed to KHDev.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info has been updated.
Your billing was not updated.