I have often had to analyse many robocopy logs and wasted a lot of time running through huge text files. That's why I wanted to share here a script I coded to run through logfiles generated by robocopy.exe and print out just a summary of useful information. The logfiles to analyse are generated using the following robocopy switch:
/LOG+:C:\log_robocopy\log_robocopy_01.txt
Here's the script. It takes in all the robocopy logfiles and recursively prints out statistics about failed file copies. The output report can be easily read.
- $files=get-childitem \\servername\c$\log_robocopy\*.txt
- $pattern1 = $null
- $pattern2 = $null
- $pattern3 = $null
- $pattern4 = $null
- foreach ($file in $files)
- {
- write-host "Working on" $file
- select-string $file -pattern " Started : "
- select-string $file -pattern "Source : "
- select-string $file -pattern "Dest : "
- $pattern1 = select-string $file -pattern "Files : "
- $pattern1 = $pattern1.tostring() -replace '\s+', " "
- $pattern2 = $pattern1.tostring().split(" ")
- write-host "Total files on source:`t" $pattern2[3]
- write-host "Total files copied:`t`t" $pattern2[4]
- write-host "Total files skipped:`t" $pattern2[5]
- write-host "Total files failed:`t`t" $pattern2[7]
- $pattern3 = select-string $file -pattern "Bytes : "
- $pattern3 = $pattern3.tostring() -replace " 0 ", " 0 m "
- $pattern3 = $pattern3.tostring() -replace '\s+', " "
- $pattern4 = $pattern3.tostring().split(" ")
- write-host "Total bytes on source:`t" $pattern4[3] $pattern4[4]
- write-host "Total bytes copied:`t`t" $pattern4[5] $pattern4[6]
- write-host "Total bytes skipped:`t" $pattern4[7] $pattern4[8]
- write-host "Total bytes failed:`t`t" $pattern4[11] $pattern4[12]
- $error1 = select-string $file -pattern "0x00000002"
- write-host "File not found error :"$error1.count
- $error2 = select-string $file -pattern "0x00000003"
- write-host "File not found errors :"$error2.count
- $error3 = select-string $file -pattern "0x00000005"
- write-host "Access denied errors :"$error3.count
- $error4 = select-string $file -pattern "0x00000006"
- write-host "Invalid handle errors :"$error4.count
- $error5 = select-string $file -pattern "0x00000020"
- write-host "File locked errors :"$error5.count
- $error6 = select-string $file -pattern "0x00000035"
- write-host "Network path not found errors :"$error6.count
- $error7 = select-string $file -pattern "0x00000040"
- write-host "Network name unavailable errors :"$error7.count
- $error8 = select-string $file -pattern "0x00000070"
- write-host "Disk full errors :"$error8.count
- $error9 = select-string $file -pattern "0x00000079"
- write-host "Semaphore timeout errors :"$error9.count
- $error10 = select-string $file -pattern "0x00000033"
- write-host "Network path errors :"$error10.count
- $error11 = select-string $file -pattern "0x0000003a"
- write-host "NTFS security errors :"$error11.count
- $error12 = select-string $file -pattern "0x0000054f"
- write-host "Internal errors :"$error12.count
- select-string $file -pattern "Ended : "
- write-host "============================="
- sleep 2
- }
I hope this helps. For more information about robocopy error codes have a look here.
Please leave a comment if this script was useful top you or if you would like to suggest an improvement.
Hello Happy Sysadmin,
ReplyDeleteit is very good idea that you use PS to parse the logs!!!
One thing I would change:
Instead of issuing multiple Select-String commands that have to read the file again and again, you could read it once and use a regex to parse it line by line adding up the values you want to display in the end or just remembering them for later use!
You can use a "swtich -regex -file" command to accomplish this ( see: http://blogs.technet.com/b/heyscriptingguy/archive/2011/03/29/learn-how-to-use-switch-regex-and-powershell-to-parse-files.aspx )
This means: less IO by reading the file once
You can report all the results after having read the file at the end of your script.
kind regards,
Klaus (Schulte) - KSchulte
Hi Klaus,
ReplyDeletethanks for your feedback!
I have rewritten the second part of the script but I am now noticing 4-times poorer performances, which I cannot explain for the moment.
Maybe my syntax can be improved to solve this. Have you got any other suggestion? Please share your feedback!
Here's the new second part of the script:
$hash = @{}
switch -regex (Get-Content $file)
{
"0x00000002" {$count02=$count02+1}
"0x00000003" {$count03=$count03+1}
"0x00000005" {$count05=$count05+1}
"0x00000006" {$count06=$count06+1}
"0x00000020" {$count20=$count20+1}
"0x00000035" {$count35=$count35+1}
"0x00000040" {$count40=$count40+1}
"0x00000070" {$count70=$count70+1}
"0x00000079" {$count79=$count79+1}
"0x00000033" {$count33=$count33+1}
"0x0000003a" {$count3a=$count3a+1}
"0x0000004f" {$count4f=$count4f+1}
}
write-host "File not found error :"$count02
write-host "File not found errors :"$count03
write-host "Access denied errors :"$count05
write-host "Invalid handle errors :"$count06
write-host "File locked errors :"$count20
write-host "Network path not found errors :"$count35
write-host "Network name unavailable errors :"$count40
write-host "Disk full errors :"$count70
write-host "Semaphore timeout errors :"$count79
write-host "Network path errors :"$count33
write-host "NTFS security errors :"$count3a
write-host "Internal errors :"$count4f
Thanks
Hi, thanks for this - it gives me what I want, with a couple of edits (too much information) - however I can't figure out how to output the results to a test file, rather than to screen. Any help would be gratefully received.
ReplyDeleteI've tried putting the Out-File command in at various locations and just get an empty text file.
This is my amended code.
$files=get-childitem c:\data\logs\*.log
$pattern1 = $null
$pattern2 = $null
$pattern3 = $null
$pattern4 = $null
foreach ($file in $files)
{
write-host "Working on" $file
$pattern1 = select-string $file -pattern "Files : "
$pattern1 = $pattern1.tostring() -replace '\s+', " "
$pattern2 = $pattern1.tostring().split(" ")
write-host "Total files on source:`t" $pattern2[3]
write-host "Total files copied:`t`t" $pattern2[4]
write-host "Total files skipped:`t" $pattern2[5]
write-host "Total files failed:`t`t" $pattern2[7]
$pattern3 = select-string $file -pattern "Bytes : "
$pattern3 = $pattern3.tostring() -replace " 0 ", " 0 m "
$pattern3 = $pattern3.tostring() -replace '\s+', " "
$pattern4 = $pattern3.tostring().split(" ")
write-host "Total bytes on source:`t" $pattern4[3] $pattern4[4]
write-host "Total bytes copied:`t`t" $pattern4[5] $pattern4[6]
write-host "Total bytes skipped:`t" $pattern4[7] $pattern4[8]
write-host "Total bytes failed:`t`t" $pattern4[11] $pattern4[12]
$error1 = select-string $file -pattern "0x00000002"
write-host "File not found error :"$error1.count
$error2 = select-string $file -pattern "0x00000003"
write-host "File not found errors :"$error2.count
$error3 = select-string $file -pattern "0x00000005"
write-host "Access denied errors :"$error3.count
$error4 = select-string $file -pattern "0x00000006"
write-host "Invalid handle errors :"$error4.count
$error5 = select-string $file -pattern "0x00000020"
write-host "File locked errors :"$error5.count
$error6 = select-string $file -pattern "0x00000035"
write-host "Network path not found errors :"$error6.count
$error7 = select-string $file -pattern "0x00000040"
write-host "Network name unavailable errors :"$error7.count
$error8 = select-string $file -pattern "0x00000070"
write-host "Disk full errors :"$error8.count
$error9 = select-string $file -pattern "0x00000079"
write-host "Semaphore timeout errors :"$error9.count
$error10 = select-string $file -pattern "0x00000033"
write-host "Network path errors :"$error10.count
$error11 = select-string $file -pattern "0x0000003a"
write-host "NTFS security errors :"$error11.count
$error12 = select-string $file -pattern "0x0000054f"
write-host "Internal errors :"$error12.count
write-host "============================="
sleep 2
}