2015-04-01 87 views
0

我試圖從robocopy日誌文件創建一個PSCustomObject。第一部分很容易,但我正在努力與$Footer部分。我似乎無法找到分割價值的好方法。解析robocopy日誌文件到PSCustomObject

這將是很好,如果每個條目都有它自己的Property,所以它可以使用例如$Total.Dirs$Skipped.Dirs。我在考慮Import-CSV,因爲這對你如何使用列標題非常有用。但這似乎不適合這裏。還有另一個解決方案,我發現here,但它似乎有點矯枉過正。

代碼:

Function ConvertFrom-RobocopyLog { 
    Param (
     [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)] 
     [String]$LogFile 
    ) 

    Process { 
     $Header = Get-Content $LogFile | select -First 10 
     $Footer = Get-Content $LogFile | select -Last 7 

     $Header | ForEach-Object { 
      if ($_ -like "*Source*") {$Source = (($_.Split(':'))[1]).trim()} 
      if ($_ -like "*Dest*") {$Destination = (($_.Split(':'))[1]).trim()} 
     } 

     $Footer | ForEach-Object { 
      if ($_ -like "*Dirs*") {$Dirs = (($_.Split(':'))[1]).trim()} 
      if ($_ -like "*Files*") {$Files = (($_.Split(':'))[1]).trim()} 
      if ($_ -like "*Times*") {$Times = (($_.Split(':'))[1]).trim()} 
     } 

     $Obj = [PSCustomObject]@{ 
       'Source'  = $Source 
       'Destination' = $Destination 
       'Dirs'  = $Dirs 
       'Files'  = $Files 
       'Times'  = $Times 
     }    
     Write-Output $Obj 
    } 
} 

日誌文件:

------------------------------------------------------------------------------- 
    ROBOCOPY  ::  Robust File Copy for Windows        
------------------------------------------------------------------------------- 

    Started : Wed Apr 01 14:28:11 2015 

    Source : \\SHARE\Source\ 
    Dest : \\SHARE\Target\ 

    Files : *.* 

    Options : *.* /S /E /COPY:DAT /PURGE /MIR /Z /NP /R:3 /W:3 

------------------------------------------------------------------------------ 
     0 Files... 
     0 More Folders and files... 

------------------------------------------------------------------------------ 

       Total Copied Skipped Mismatch FAILED Extras 
    Dirs :   2   0   2   0   0   0 
    Files :  203   0  203   0   0   0 
    Bytes :   0   0   0   0   0   0 
    Times : 0:00:00 0:00:00      0:00:00 0:00:00 

    Ended : Wed Apr 01 14:28:12 2015 

謝謝您的幫助。

+0

我知道你在問什麼,但不知道你對輸出的期望。你有一個名爲Dirs的財產,有總共的子屬性,複製等。 – Matt 2015-04-01 14:58:09

回答

3

你可以清理更多,但這是我會採取的基本方法。

Function ConvertFrom-RobocopyLog { 
    Param (
     [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,Position=0)] 
     [String]$LogFile 
    ) 

    Process { 
     $Header = Get-Content $LogFile | select -First 10 
     $Footer = Get-Content $LogFile | select -Last 7 

     $Header | ForEach-Object { 
      if ($_ -like "*Source*") {$Source = (($_.Split(':'))[1]).trim()} 
      if ($_ -like "*Dest*") {$Destination = (($_.Split(':'))[1]).trim()} 
     } 

     $Footer | ForEach-Object { 
      if ($_ -like "*Dirs*"){ 
       $lineAsArray = (($_.Split(':')[1]).trim()) -split '\s+' 
       $Dirs = [pscustomobject][ordered]@{ 
        Total = $lineAsArray[0] 
        Copied = $lineAsArray[1] 
        Skipped = $lineAsArray[2] 
        Mismatch = $lineAsArray[3]  
        FAILED = $lineAsArray[4]  
        Extras = $lineAsArray[5] 
       } 
      } 
      if ($_ -like "*Files*"){ 
       $lineAsArray = ($_.Split(':')[1]).trim() -split '\s+' 
       $Files = [pscustomobject][ordered]@{ 
        Total = $lineAsArray[0] 
        Copied = $lineAsArray[1] 
        Skipped = $lineAsArray[2] 
        Mismatch = $lineAsArray[3]  
        FAILED = $lineAsArray[4]  
        Extras = $lineAsArray[5] 
       } 
      } 
      if ($_ -like "*Times*"){ 
       $lineAsArray = ($_.Split(':',2)[1]).trim() -split '\s+' 
       $Times = [pscustomobject][ordered]@{ 
        Total = $lineAsArray[0] 
        Copied = $lineAsArray[1]  
        FAILED = $lineAsArray[2]  
        Extras = $lineAsArray[3] 
       } 
      } 
     } 

     $Obj = [PSCustomObject]@{ 
       'Source'  = $Source 
       'Destination' = $Destination 
       'Dirs'  = $Dirs 
       'Files'  = $Files 
       'Times'  = $Times 
     }    
     Write-Output $Obj 
    } 
} 

我想作一個函數來解析頁腳行,但$Times是一個特例,因爲它不具備的所有數據相同的列。

With $Times重要區別在於我們是如何進行拆分的。由於該字符串包含多個冒號,因此我們需要對此進行說明。使用.Split()中的其他參數,我們指定要返回的元素的數量。

$_.Split(':',2)[1]

由於這些日誌總是有輸出,無空白行元素,我們可以做到這一點假設的$lineAsArray解析的元素總是有6個元素。

樣本輸出

Source  : \\SHARE\Source\ 
Destination : \\SHARE\Target\ 
Dirs  : @{Total=2; Copied=0; Skipped=2; Mismatch=0; FAILED=0; Extras=0} 
Files  : @{Total=203; Copied=0; Skipped=203; Mismatch=0; FAILED=0; Extras=0} 
Times  : @{Total=0:00:00; Copied=0:00:00; FAILED=0:00:00; Extras=0:00:00} 

所以,如果你想總的文件複製,你現在可以使用點符號。

(ConvertFrom-RobocopyLog C:\temp\log.log).Files.Total 
203 
+0

謝謝你,馬特,你是老闆!我不知道這個('$ _。Split(':',2)')可能與'Split'一起使用。真的很棒的解決方案! :)我現在明白它是如何完成的。 – DarkLite1 2015-04-02 06:26:50

+0

我添加的一個小改進是Total = [TimeSpan] $ Array [0]'。 – DarkLite1 2015-04-02 06:36:06

1

不是說清楚自己想要做什麼,但是這將在一定程度上顯示你如何獲得的統計信息爲對象

$statsOut = @() 
$stats = Get-Content $LogFile | select -Last 6 | select -first 4 

$stats | % { 
    $s = $_ -split "\s+" 
    $o = new-object -type pscustomobject -property @{"Name"=$s[0];"Total"=$s[2];"Copied"=$s[3];"Skipped"=$s[4];"mismatch"=$s[5]}; 
    $statsOut += ,$o 
} 

的陣列能夠提供:

[PS] > $statsOut | ft -Auto 
mismatch Name Skipped Total Copied 
-------- ---- ------- ----- ------ 
0  Dirs 2  2  0 
0  Files 203  203  0 
0  Bytes 0  0  0