2012-03-15 106 views
1

我試圖'on the fly'格式輸出openfiles.exe,而不是將輸出保存到CSV並導入它。 如果我只需運行openfiles /query /s SERVERNAME /fo table我得到openfiles.exe的格式表輸出

ID  Accessed By   Type  Open File (Path\executable) 
======== ==================== ========== ===================================== 
1558  AUSERNAME   Windows D:\..\Imaging\Itool.ldb 

現在,我想無論是訪問過由或打開文件,所以我已經試過 openfiles /query /s SERVERNAME /fo table | Format-Table "Accessed By","Open File (Path\executable)" -auto 剛剛吐出來的是同樣的事情,第一個命令在飛行中對結果進行排序。理想情況下,我只希望「訪問者」和「打開文件(路徑\可執行文件)」,只是可以通過任何一個進行排序。我試圖避免做CSV的事情。

回答

3

這有點棘手,因爲openfiles不是PowerShell cmdlet。它只是將數據顯示在表格中,但不是它返回的對象。 PowerShell只是將它們作爲字符串。

$item = New-Object PSObject 
switch -regex (openfiles /query /s SERVERNAME /fo list) { 
    '([^:]+):\s+(.*)$' { 
     $item | Add-Member NoteProperty $Matches[1] $Matches[2] 
    } 
    '^$' { 
     if ($item) { $item } 
     $item = New-Object PSObject 
    } 
} 

這使用列表格式,解析它並構建可以使用的對象。它包裝在一個函數(或$(...)子表達式),你可以使用Format-Table

$(
    $item = New-Object PSObject 
    switch -regex (openfiles /query /s SERVERNAME /fo list) { 
     '([^:]+):\s+(.*)$' { 
      $item | Add-Member NoteProperty $Matches[1] $Matches[2] 
     } 
     '^$' { 
      if ($item) { $item } 
      $item = New-Object PSObject 
     } 
    } 
) | ft 'Accessed By','Open File (Path\executable)' -auto 

,或者你只是改變命令一點點。我用switch的內在迭代的能力,但你可以做同樣的一個明確的管道:

openfiles /query /s SERVERNAME /fo list | 
    ForEach-Object { 
    $item = New-Object PSObject 
    } { 
    switch -regex ($_) { 
     '([^:]+):\s+(.*)$' { 
     $item | Add-Member NoteProperty $Matches[1] $Matches[2] 
     } 
     '^$' { 
     if ($item) { $item } 
     $item = New-Object PSObject 
     } 
    } 
    } 

由於這是一個管道,你可以隨意的末尾添加多個命令。

2

您不能格式化輸出,因爲它返回字符串數組。相反,你可以嘗試分析它,但恕我直言,它更容易保存爲CSV和進口

$out = openfiles /query /s SERVERNAME /fo table 
$out | 
    Select-Object -Skip 2 | 
    Foreach-Object { 
     if ($_ -match '([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+(.*)') { 
      New-Object PsObject -prop @{ 
       Id=[int]$matches[1]; 
       AccessedBy=$matches[2] 
       Type=$matches[3] 
       OpenFile=$matches[4] 
      } 
     } 
    } | 
    Sort-Object OpenFile 

(我沒有機會測試openFiles散)

+0

對於正則表達式,我猜'\ S'比'[^ \ s]'更容易閱讀。你可以在'\\ localhost \ c $ \ ...'上打開一個文件來測試它。至少我這樣做是爲了獲得不止一行數據。不過,用戶名和文件名可能包含空格,所以正則表達式可能會匹配不同的東西,這就是爲什麼我切換到列表格式,這樣更容易解析)。 – Joey 2012-03-16 06:46:53

1

剛走做到了這一點,你可以CSV輸出很容易轉換成一個PowerShell對象,通過做以下操作:

$FileList = Invoke-Expression "& C:\Windows\System32\openfiles.exe /query /s SERVERNAME /fo CSV" | 
    ConvertFrom-Csv | 
    Select "Accessed By","Open File (Path\executable)"