2

I have the following robocopy command line:

robocopy $drv "B:\Blending Produções - Backup\Blending Produções - Tyrone Hirt - BC" /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos

This command will list all the files that must be copied following the established parameters.

The point is: I would like to find a way to count how many files will be copied.

For this I'm trying an approach of counting how many matches "T:" there are in the robocopy output, but I'm not getting the expected result...

This is my complete script:

$drv = "T:\"
$IgnorarPastas = "03. Proxy", "`$Recycle.Bin"
$IgnorarArquivos = "*.avi", "*.ini"

robocopy $drv "B:\Blending Produções - Backup\Blending Produções - Tyrone Hirt - BC" /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos

$robocopyCommand = "robocopy $drv ""B:\Blending Produções - Backup\Blending Produções - Tyrone Hirt - BC"" /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos" $filesToCopy = Invoke-Expression $robocopyCommand $numberOfFiles = ($filesToCopy | Select-String -Pattern "T:\" -AllMatches).Matches.Count

write-host "`nNumber of files to be copied " -NoNewline -f White; write-host "$numberOfFiles" -NoNewline -f Green;

This is the output of the script in the console:

$drv = "T:\"
 $IgnorarPastas = "03. Proxy", "`$Recycle.Bin"
 $IgnorarArquivos = "*.avi", "*.ini"

robocopy $drv "B:\Blending Produções - Backup\Blending Produções - Tyrone Hirt - BC" /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos

$comandoRobocopy = "robocopy $drv ""B:\Blending Produções - Backup\Blending Produções - Tyrone Hirt - BC"" /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos"

$robocopyCommand = "robocopy $drv ""B:\Blending Produções - Backup\Blending Produções - Tyrone Hirt - BC"" /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos" $filesToCopy = Invoke-Expression $robocopyCommand $numberOfFiles = ($filesToCopy | Select-String -Pattern "T:\" -AllMatches).Matches.Count

write-host "`nNumber of files to be copied " -NoNewline -f White; write-host "$numberOfFiles" -NoNewline -f Green;

           12680    T:\_Ferramenta Backup\Backup Local\_\BP - Backup Script - Root of this device - Get Backup.ps1

100%
379568522 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste Car_Imagens\Drone\DJI_0001.MOV 2380021041 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste Car_Imagens\Drone\DJI_0002.MOV 43588300 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste Car_Imagens\Drone\DJI_0003.MOV 3335677673 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste Car_Imagens\Drone\DJI_0004.MOV 2325513829 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste Car_Imagens\Drone\DJI_0005.MOV 3245228768 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste Car_Imagens\Drone\DJI_0006.MOV 1392290 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Fenauto 2023\Geral_Pr\Adobe Premiere Pro Auto-Save\Fenauto Geral 1--aa12bd8f-a378-c373-6d52-62bab88e86a6-2023-12-04_11-36-34.prproj 1398658 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Fenauto 2023\Geral_Pr\Adobe Premiere Pro Auto-Save\Fenauto Geral 1--aa12bd8f-a378-c373-6d52-62bab88e86a6-2023-12-04_12-12-44.prproj 54138464 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste\11. Novembro\07. Teste I Fenauto Overview Final\01. Fluxo\01. Ae\07-12-2023 Teste I Fenauto Overview Final (converted ).aep 84566896 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste\00. Identidade\01. Fluxo\01. Ae\Adobe After Effects Auto-Save\Teste I Identidade Audiovisual (converted) auto- save 5.aep 230815274 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste\11. Novembro\17. DLPL Cast - EP 15\05. Render\Vertical\DLPL Cast I EP 14 I Corte 1 I Vert I Financiamento I Final - v 01.mp4 230450405 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste\11. Novembro\17. DLPL Cast - EP 15\05. Render\Vertical\DLPL Cast I EP 14 I Corte 2 I Vert I Consigna‡Æo I Final - v01 .mp4 12200 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste Car\12. Dezembro\29. TesteCar I Carros e Repasse\01. Fluxo\01. Ae\02-01-2024 Nome.aep 12200 136490 B:\Blending Produ‡äes - Backup\Blending Produ‡äes - Tyrone Hirt - BC\Blending Produ‡äes\02. Clientes\2023\Grupo Teste\Teste Car\12. Dezembro\29. TesteCar I Carros e Repasse\01. Fluxo\02. Pr\02-01-2024 Nome.prproj


               Total   Copiada      IgnoradaIncompatibilidade     FALHA      Extras

Diret¢rios: 3407 3302 3406 0 1 6 Arquivos: 19705 1 19707 0 0 14 Bytes: 2037206266068 12680 2037651251411 0 0 12312508810 N.§ de Vezes: 0:00:00 0:00:00 0:00:00 0:00:00 Finalizado em: quinta-feira, 4 de janeiro de 2024 01:19:19

Number of files to be copied 169

I'm not able to get a correct count this way, the result is 169 when it should be 1, since in the output only one file is being copied.

How can I adjust my script to get the expected result?

Edit

I'm trying another approach:

# Find the line containing "Arquivos:"
$filesLine = $filesToCopy | Select-String -Pattern "Arquivos:.*?(\d+)\s+(\d+)" | ForEach-Object { $_.Matches }

Extract the second group of numbers from the line

$numberOfFilesCopied = $filesLine.Groups[2].Value

In this code, the regular expression Arquivos:.*?(\d+)\s+(\d+) is used to search for the line containing "Arquivos:" and capture both groups of numbers. The second group is then accessed using $filesLine.Groups[2].Value.

I still can't get the correct result.

In short, I need to have a count of how many files robocopy will copy before starting the copy.

2 Answers2

1

Use only ($filesToCopy | Select-String -Pattern "T:\\").Count in the logic omitting the -AllMatches and the .Matches parts out to get the correct counts matching the Robocopy log stored in an array variable.

Furthermore, when defining the $robocopyCommand variable, encapsulate it with single quotes rather than double quotes, and remove the double double quote escape characters.

PowerShell

$drv = "T:\"
$IgnorarPastas = "03. Proxy", "`$Recycle.Bin"
$IgnorarArquivos = "*.avi", "*.ini"

robocopy $drv "B:\Blending Produções - Backup\Blending Produções - Tyrone Hirt - BC" /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos

$robocopyCommand = 'robocopy $drv "B:\Blending Produções - Backup\Blending Produções - Tyrone Hirt - BC" /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos' $filesToCopy = Invoke-Expression $robocopyCommand $numberOfFiles = ($filesToCopy | Select-String -Pattern "T:\").Count

write-host "`nNumber of files to be copied " -NoNewline -f White; write-host "$numberOfFiles" -NoNewline -f Green;

1

There are 2 potential problems I spotted with your script:

  • double call of robocopy, which could result in different outcome on 2nd call and is definitely not needed
  • usage of Invoke-Expression, which is generally discouraged, similarly to alike code evaluating functions in other programming languages. I would recommend avoiding it for security reasons, which don't matter here most likely, but it's worth knowing there are almost always better replacements. See documentation for further info, e.g.:

Take reasonable precautions when using the Invoke-Expression cmdlet in scripts. When using Invoke-Expression to run a command that the user enters, verify that the command is safe to run before running it. In general, it is best to design your script with predefined input options, rather than allowing freeform input.


If you'd like to run it silently, I'd just replace both:

robocopy $drv $destination /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos

$robocopyCommand = "robocopy $drv $destination /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos"

with:

$robocopyResult = robocopy $drv $destination /e /NJH /NDL /NC /BYTES /MT:4 /l /xd /A-:SH $IgnorarPastas /xf $IgnorarArquivos

And stdout stream will be saved to the variable. You can then further e.g. mute stderr stream by adding 2>$null at the end, if needed.

Destroy666
  • 12,350