Copy and enumerate copied files


  • Build function parameters
  • Filter files
  • Copy folder structure
  • Copy and enumerate each file
  • Full script

Some weeks ago I saw a person asking for help in stackoverflow to build a script that would copy files and then enumerate each of them. Well, I’ve made a simple script for him but, some days after I had the idea of making a tool for it, so today I’ll share it here with you.


  • Build function parameters

Since we’re working in a tool concept here, we need to build a function which will provide us a single interface to re-use our code at different times for different targets for each purpose.


function Copy-EnumerateFiles {
    [Cmdletbinding()]
    param(
        [ValidateScript({Test-Path $_})]
        $Source,
        [ValidateScript({Test-Path $_})]
        $Destination,
        $FilterExtension
    )

LINE 2 – Cmdletbinding:

Adds several capabilities such as additional parameter checking, and the ability to easily use Write-Verbose. A function with cmdletbinding will throw an error if unhandled parameter values appear on the command line.

LINES 4 and 6 – ValidateScript:

Uses a script block that validates the parameter value, in this case the values of ‘$source‘ and ‘$destination‘ must be existent paths, otherwise the function will not run.


  • Filter files

We’ve added a FilterExtension parameter in our function, I found this useful since the tool will get all items contained in a folder, there’s a probability that you’ll not want all kind of files in that. So in that case we just need to specify this parameter with the name of the file extension we want.

With that said, the script must know how to do that and return a failed message if no files are found.

Follow the comments in the script below:

#If $FilterExtension is specified, get items where extension name are equal $FilterExtension value.
 if($FilterExtension){
        $Files = gci -Path $Source -Recurse -File | where {$_.Extension -eq ".$FilterExtension"}
    }
        #Else, do not use filters.
        else{
            $Files = gci -Path $Source -Recurse
        }

#If no files are found, return a message. (will appear only if '-Verbose' parameter was present).
 if(!$Files) {
        Write-Verbose "No files have been found!"
    }

  • Copy folder structure
 $DestinationFile = $Destination + ($File.FullName | Split-Path -NoQualifier)
 if(!(Test-Path -Path $DestinationFile -PathType Leaf)) {
 New-Item -Path $DestinationFile -ItemType File -Force | Out-Null

Line 1:

The property ‘fullname‘ of each file returns the full path of it, but we want to redirect it to our specified path we’ve determined in $destination parameter.

The command $file.fullname | Splith-Path -NoQualifier returns the file path without the qualifier, the qualifier is the drive.

This way we can add this path without the qualifier to our specified path.

Example:

$Destination = c:\users\administrator\desktop\EnumerateFiles
$File.Fullname | Split-Path -NoQualifier = users\administrator\downloads\file.extension
Result = c:\users\administrator\desktop\EnumarateFiles\users\administrator\downloads\file.extension

Lines 2 and 3:

We want to maintain the folder hierarchy from copied files, we can do this by using New-Item cmdlet which creates this structure automatically, but the trick is to set the -ItemType parameter to ‘File’ otherwise we wouldn’t succeed copying our structure without doing more complex methods. This way we just add a 0 byte file to the $DestinationFile to keep the whole folder structure!


  • Copy and enumerate files

Finally it’s time to copy and enumerate the copied files:

 #Copy file to the new copied folder structure
 Copy-Item $file.FullName -Destination $DestinationFile -Force
 #After copying the file, rename it adding a number to enumerate it.
 Rename-Item -Path $DestinationFile -NewName "$($file.basename)_$($i)$($file.Extension)" -Force
 #Increase +1 to variable $i for the next loop.
 $i++

For enumerating our files after copying each one, we use the Rename-Item cmdlet, this cmdlet needs the name of the file along with it’s extension to succefully rename it, that’s why whe need to use the properties ‘basename‘ and then ‘extension‘.

$File.Basename = Get only the name of the file without the path and it’s extension.

$i = A number which will increase for each loop.

$File.extension = Get the extension name of the file.


  • Full script


  • See it in action

See in the animation below, the whole structure from my downloads folder is copied to my destination which I’ve choosen as my desktop path.

First i copy all files in it, then I copy using the FilterExtension parameter to just copy the pdf files from my downloads folder.


  • Conclusion

I hope I’ve helped you, as I helped the person from stackoverflow.

Of course you can do much more by editing this script, get the idea and build it for you own purposes, the techniques demonstrate here are very helpful to manage your files and folders.

Thank you very much for reading, be sure to follow me in my social hub to receive the next updates!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s