Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 10273
  • Last Modified:

Powershell progressbar copy-item

Hi,

I want to show a progress-bar while copying items from one folder to another using copy-item.

The following script does not work as intended. I've tried alot of things, but nothing seems to work.
The documentation of progress-bar does not show a good example of copying items.

The progress bar shows 100% and starts to copy everything afterwards.
If i move the copy-item into the foreach loop, it loops and starts to copy again in another subfolder of the destination. After the second copy it continues to loop, but fails.
Any suggestions how to make a progress-bar while copying items?

if (Test-Path -path C:\Source\)
            {
                Remove-Item C:\Source -recurse
                $sourcePath = 'C:\Source'
                $destinationPath = 'C:\Drivers'
                $file = Get-ChildItem -Path $sourcePath
                $filecount= $file.count
                Foreach ($filecount in $file)
                    {
                        $i++
                        Write-Progress -activity "Copying drivers" -Status "Progress:" -percentcomplete (($i/$file.count)*100)
                       
                    }
                    Copy-Item $sourcePath $destinationPath -recurse
            }
            else
            {
                Copy-Item C:\Source C:\Drivers -recurse
            }
0
Ball_Group
Asked:
Ball_Group
1 Solution
 
jwarnkenCommented:
Try this
if (Test-Path -path C:\Source\)
            {
                Remove-Item C:\Source -recurse
                $sourcePath = 'C:\Source'
                $destinationPath = 'C:\Drivers'
                $file = Get-ChildItem -Path $sourcePath
                $filecount= $file.count
                Foreach ($filecount in $file)
                    {
                        $i++
                        Write-Progress -activity "Copying drivers" -Status "Progress:" -percentcomplete (($i/$file.count)*100)
                        Copy-Item $File.fullname $destinationPath -recurse
                       
                    }
                    
            }
            else
            {
                Copy-Item C:\Source C:\Drivers -recurse
            }

Open in new window

0
 
jwarnkenCommented:
sorry correction for copy and paste error
if (Test-Path -path C:\Source\)
            {
                Remove-Item C:\Source -recurse
                $sourcePath = 'C:\Source'
                $destinationPath = 'C:\Drivers'
                $file = Get-ChildItem -Path $sourcePath -Recurse
                $filecount= $file.count
                Foreach ($filecount in $file)
                    {
                        $i++
                        Write-Progress -activity "Copying drivers" -Status "Progress:" -percentcomplete (($i/$file.count)*100)
                        Copy-Item $File.fullname $destinationPath
                       
                    }
                    
            }
            else
            {
                Copy-Item C:\Source C:\Drivers -recurse
            }

Open in new window

0
 
Ball_GroupAuthor Commented:
It does not seem happy about Copy-Item $File.fullname $destinationPath

I've tried the following Copy-Item -Path $File.fullname -Destination $destinationPath
If i make a write-host $File.fullname it does not print anything.

Any suggestions?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
jwarnkenCommented:

if (Test-Path -path C:\Source\)
            {
                Remove-Item C:\Source -recurse
                $sourcePath = 'C:\Source'
                $destinationPath = 'C:\Drivers'
                $file = Get-ChildItem -Path $sourcePath -Recurse
                $filecount= $file.count
                Foreach ($f in $file)
                    {
                        $i++
                        Write-Progress -activity "Copying drivers" -Status "Progress:" -percentcomplete (($i/$file.count)*100)
                        Copy-Item $F.fullname $destinationPath
                       
                    }
                    
            }
            else
            {
                Copy-Item C:\Source C:\Drivers -recurse
            }

Open in new window

0
 
Ball_GroupAuthor Commented:
Hmm, it looks like the progressbar is working now, but all the files is in one huge mess in the C:\Drivers folder.

There should be a few sub folders, with drivers in, but instead the C:\Drivers is with all files i a big mess.

Something wrong with the -Recurse argument?
0
 
jwarnkenCommented:
0
 
Ball_GroupAuthor Commented:
It may be the solution.
I just think the write-progress is a little more eye candy than the progress meter...

Well, i'll work a little more with write-progress, and see if i can find a solution.
0
 
dicconbCommented:
Hi Ball_Group,

The reason the progress bar wasn't working in your script is that copy-item -recurse is a single operation, whereas write-progress needs to be called multiple times so the progress bar can advance with each increment.

The trick to getting write-progress to work is to put your copy-item line into the for-each loop, but to copy only one file at a time, which jwarnken's latest script does for you.

Unfortunately because we're now copying each file manually we miss out on some of the clever stuff that copy-item -recurse does for you, for instance keeping track of the folder hierarchy.  To do this we need to determine the path of each object relative to the source folder and use this to calculate which folder within the destination folder it should be copied to.  I have added some extra lines that do this.

Have a read through the script and let me know if you have any questions.  If you're sure you understand what it will do, remove the -whatif argument from the copy-item command and run it.

Cheers,

D

 
$sourcePath = 'C:\folder1'
$destinationPath = 'C:\folder2'
$files = Get-ChildItem -Path $sourcePath -Recurse
$filecount = $files.count
$i=0
Foreach ($file in $files) {
    $i++
    Write-Progress -activity "Copying drivers..." -status "$file ($i of $filecount)" -percentcomplete (($i/$filecount)*100)
  
    # Determine the absolute path of this object's parent container.  This is stored as a different attribute on file and folder objects so we use an if block to cater for both
    if ($file.psiscontainer) {$sourcefilecontainer = $file.parent} else {$sourcefilecontainer = $file.directory}

    # Calculate the path of the parent folder relative to the source folder
    $relativepath = $sourcefilecontainer.fullname.SubString($sourcepath.length)

    # Copy the object to the appropriate folder within the destination folder
    Copy-Item $file.fullname ($destinationPath + $relativepath) -whatif
}

Open in new window

0
 
Ander MuCommented:
Hi there,

I need to back up user profiles in Win 7, so Im trying to implement the last solution you posted. However, I got a question as I need to back up all folders allocated for each user including appdata. The only way I have found to do it is with copy-item -recurse but as you mentioned this is a single operation that cannot integrated to progressbar. So Im just wondering if there is another way of developing a powershell script to have the appdata folder backed up and the progressbar working together?

If you can give me some tips, I will really appreciate it.

Thanks.

Ander
0

Featured Post

Who's Defending Your Organization from Threats?

Protecting against advanced threats requires an IT dream team – a well-oiled machine of people and solutions working together to defend your organization. Download our resource kit today to learn more about the tools you need to build you IT Dream Team!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now