2012-03-15 66 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)"