Add to Technorati Favorites
Welcome to ThePowerShellGuy.com Sign in | Join | Help

PowerShell and Robocopy part 3

In this 3rd part of this  series we go on with the output of a Test copy, and will start to parse the robocopy log, I just made a sTest1 directory with some test files and started the command as explained in last post,

You can see in the output that there are 3 distinct parts in the Robocopy output, Start, Details, Stop information divided by a line, so the first thing is dividing the output of robocopy in the 3 parts and process them separately, we do that by this line :

$null,$StartBegin,$StartEnd,$StopBegin = $RoboLog | Select-String "----" |% {$_.linenumber}

as you see in the output below this gives us the line numbers of lines separating the different parts :

image

After that I make a new object and start parsing the Start information, adding the information to the $RobocopyStatus object,

note that the Date get's translated from text into a "Real" Date-time object (might need adapting for other cultures as en-us)

 -Value ([datetime]::ParseExact($matches[1].trim(),'ddd MMM dd HH:mm:ss yyyy',$null)) `

The Rest of the code for the start part of the Robocopy log :

#############################################################################################
## Robocopy example command :
#############################################################################################


robocopy 'c:\test1' c:\PowerShellRoboTest /r:2 /w:5 /s /v /np |
  Tee-Object -Variable RoboLog


#############################################################################################
## Process the Output
#############################################################################################


$null,$StartBegin,$StartEnd,$StopBegin = $RoboLog | Select-String  "----" |% {$_.linenumber}

$RoboStatus = New-Object object

# Start information 

$robolog[$StartBegin..$StartEnd] | % {
  Switch -regex ($_) {
    'Started :(.*)' {
      Add-Member -InputObject $RoboStatus -Name StartTime `
       -Value ([datetime]::ParseExact($matches[1].trim(),'ddd MMM dd HH:mm:ss yyyy',$null)) `
       -MemberType NoteProperty
    }
    'Source :(.*)' {
      Add-Member -InputObject $RoboStatus -Name Source `
        -Value ($matches[1].trim()) -MemberType NoteProperty
    }
    'Dest :(.*)' {
      Add-Member -InputObject $RoboStatus -Name Destination `
        -Value ($matches[1].trim()) -MemberType NoteProperty
    }    
    'Files :(.*)' {
      Add-Member -InputObject $RoboStatus -Name FileName `
        -Value ($matches[1].trim()) -MemberType NoteProperty
    }
    'Options :(.*)' {
      Add-Member -InputObject $RoboStatus -Name Options `
        -Value ($matches[1].trim()) -MemberType NoteProperty
    }
  }
}

This results in a $robostatus object that we can check the start information on like this  :

image

and as the StartTime is a Object also we can for example also select the Year only.

Next thing to do is and the End information also :

# Stop Information

$robolog[$StopBegin..( $RoboLog.Count  -1)] |% {
  Switch -regex ($_) {

    'Ended :(.*)' {
        Add-Member -InputObject $RoboStatus -Name StopTime `
          -Value ([datetime]::ParseExact($matches[1].trim(),'ddd MMM dd HH:mm:ss yyyy',$null))`
          -MemberType NoteProperty
    }

    'Speed :(.*) Bytes' {
        Add-Member -InputObject $RoboStatus -Name BytesSecond `
          -Value ($matches[1].trim()) -MemberType NoteProperty
    }

    'Speed :(.*)MegaBytes' {
        Add-Member -InputObject $RoboStatus -Name MegaBytesMinute `
          -Value ($matches[1].trim()) -MemberType NoteProperty
    }    

    '(Total.*)' {
      $cols = $_.Split() |? {$_}
    }

    'Dirs :(.*)' {
      $fields = $matches[1].Split() |? {$_}
      $dirs = new-object object
      0..5 |% {
          Add-Member -InputObject $Dirs -Name $cols[$_] -Value $fields[$_] -MemberType NoteProperty
          Add-Member -InputObject $Dirs -Name 'toString' -MemberType ScriptMethod `
            -Value {[string]::Join(" ",($this.psobject.Properties |
              % {"$($_.name):$($_.value)"}))} -force
      }
      Add-Member -InputObject $RoboStatus -Name Directories -Value $dirs -MemberType NoteProperty
    }

    'Files :(.*)' {
      $fields = $matches[1].Split() |? {$_}
      $Files = new-object object
      0..5 |% {
          Add-Member -InputObject $Files -Name $cols[$_] -Value $fields[$_] -MemberType NoteProperty
          Add-Member -InputObject $Files -Name 'toString' -MemberType ScriptMethod -Value `
            {[string]::Join(" ",($this.psobject.Properties |% {"$($_.name):$($_.value)"}))} -force
      }
      Add-Member -InputObject $RoboStatus -Name files -Value $files -MemberType NoteProperty
    }

    'Bytes :(.*)' {
      $fields = $matches[1].Split() |? {$_}
      $fields = $fields |% {$new=@();$i = 0 } {
          if ($_ -match '\d') {$new += $_;$i++} else {$new[$i-1] = ([double]$new[$i-1]) * "1${_}B" }
      }{$new}

      $Bytes = new-object object
      0..5 |% {
          Add-Member -InputObject $Bytes -Name $cols[$_] `
            -Value $fields[$_] -MemberType NoteProperty
          Add-Member -InputObject $Bytes -Name 'toString' -MemberType ScriptMethod `
            -Value {[string]::Join(" ",($this.psobject.Properties |
            % {"$($_.name):$($_.value)"}))} -force
      }
      Add-Member -InputObject $RoboStatus -Name bytes -Value $bytes -MemberType NoteProperty
    }
  }
}

Now it already get's more interesting as we can do things like this now :

image

You can see above that we can calculate the running time now and see the count of files, be sure to take a look at the code to parse the Stop information, as you can find some nifty tricks as overriding the ToString() method on the Files and Directory collections to make them more clear in default output:

Add-Member -InputObject $Files -Name 'toString' -MemberType ScriptMethod -Value ` {[string]::Join(" ",($this.psobject.Properties |% {"$($_.name):$($_.value)"}))} -force

In the next part we will do some more text parsing as we're also going to process the Detail information from the robocopy log .

Enjoy,

Greetings /\/\o\/\/

Published Sunday, September 21, 2008 5:11 PM by MoW

Comments

# Weekly news from The PowerShell world

Hi, and welcome to the first of many weekly news post from the PowerShell world. By The Scandinavian

Wednesday, September 24, 2008 7:53 AM by The Wall
Anonymous comments are disabled