如何使用Power Shell过滤特定单词

时间:2019-03-28 20:29:19

标签: powershell csv

我试图确定谁在从2008打印服务器进行打印。我从服务器管理器生成了一个日志文件,现在将此信息保存在一个csv文件中。我的目标是解析此信息并将其导出到新的csv中,以找出仅关联user IDcomputer host nameprinter name的所有关联,这些都包含在csv日志文件中,因此我可以确定谁在此服务器上进行打印,并确保我可以将它们映射到我们的新打印服务器。 CSV由一列具有模式的数据组成。

csv中的每一行都遵循以下模式,但是每行的措辞都不同,因为作业名称长/短或我不想要的其他信息。

总体模式是:

Document #, job name owned by **user ID** on **computer host name** was printed on **printer name** through port ********  

我不想要的更多信息

我的问题是我不能像忽略每行的前5个单词那样硬编码,然后第6个单词将是用户ID等,因为每行的格式都不同。

对我来说,忽略所有单词的最佳方法是什么,直到短语“拥有者”或更好的用户ID,然后将其保存到新的csv中,然后对计算机主机名执行相同的操作,打印机名称?

3 个答案:

答案 0 :(得分:1)

使用正则表达式匹配可以很容易地做到这一点。正则表达式使用模式匹配,因此您可以执行以下操作:

Get-Content LogFile.csv | Where{$_ -match "^(.*?),.+? owned by (.+?) on (.+?) was printed on (.+?) through port (.+)"} | ForEach{
    [PSCustomObject]@{
        JobNumber=$Matches[1]
        UserId=$Matches[2]
        ComputerName=$Matches[3]
        PrinterName=$Matches[4]
        Port=$Matches[5]
    }
}|Export-Csv NewLogFile.csv -NoTypeInfo

这将为您提供CSV,您可以在Excel中打开CSV或仅包含作业号,用户ID,使用的计算机,使用的打印机以及使用的端口。

答案 1 :(得分:1)

TheMadTechnician's Answer已经涵盖了大部分内容。

$a = Get-Content original.csv
$a[0] += ",Data"
$a | Set-Content updated.csv
$csv = Import-Csv updated.csv

$data = $csv.where({$_."Event ID" -eq 307}) | Select-String -pattern "(?<=owned by )(?<user>[^ ]+)(?: on )(?<host>.*?)(?: was printed on )(?<printer>.*?)(?= through )"

$(ForEach ($m in $data.matches) {
    [pscustomobject][ordered]@{"User"=$m.groups["user"].value
                "Host"=$m.groups["host"].value
                "Printer"=$m.groups["printer"].value
    }
}) | Export-Csv Output.csv -notypeinformation

从Windows打印服务器导出的CSV存在一些问题。如果在这种情况下,以下编号问题无关紧要,那么我可以删除此答案。

  1. 包含您关心的数据的CSV列没有名称。其他列具有标题,但是由于某种原因,没有。没有该标头,您的Import-Csv命令将毫无用处。代码的前四行涵盖了将Data头添加到该文件。因此,您可以使用代码来解决此问题,也可以只打开文件,添加列名并保存。
  2. 您关心的事件ID是307。该事件日志中还有很多其他噪音,除非您在将其保存为CSV之前对其进行了预过滤,否则可能会影响正则表达式的匹配。

我在这里的方法与其他发布的答案确实没有什么不同。我只匹配较少的字符串,并使用命名索引访问那些匹配项。

答案 2 :(得分:0)

这不是关于如何从消息文本中提取信息的答案,而是关于如何避免首先处理格式化文本的答案。看来您正在尝试解析ID为307的事件日志事件的消息。此代码改编自PowerShell One-Liner to Audit Print Jobs on a Windows based Print Server

使用Get-WinEvent cmdlet可以查询特定事件(Microsoft-Windows-PrintService/Operational)的特定日志(307),然后只需为每个属性检索并添加一个有意义的名称即可...

$eventFilter = @{
    LogName = 'Microsoft-Windows-PrintService/Operational';
    ID = 307;
}

Get-WinEvent -FilterHashTable $eventFilter `
    | Select-Object -Property `
        'TimeCreated', `
        @{ Name = 'JobId';       Expression = { $_.Properties[0].Value }; }, `
        @{ Name = 'JobName';     Expression = { $_.Properties[1].Value }; }, `
        @{ Name = 'UserName';    Expression = { $_.Properties[2].Value }; }, `
        @{ Name = 'MachineName'; Expression = { $_.Properties[3].Value }; }, `
        @{ Name = 'PrinterName'; Expression = { $_.Properties[4].Value }; }, `
        @{ Name = 'PortName';    Expression = { $_.Properties[5].Value }; }, `
        @{ Name = 'ByteCount';   Expression = { $_.Properties[6].Value }; }, `
        @{ Name = 'PageCount';   Expression = { $_.Properties[7].Value }; }

对于带有此类消息的活动……

  

文档1,\\ MachineName上的UserName拥有的打印文档为   通过端口X:\ Directory \ File.ext以Microsoft Print打印为PDF。   大小(以字节为单位):12345。打印的页数:1.无需用户操作。

...上面的代码将输出这样的对象...

TimeCreated : 3/28/2019 5:36:41 PM
JobId       : 1
JobName     : Print Document
UserName    : UserName
MachineName : \\MachineName
PrinterName : Microsoft Print to PDF
PortName    : X:\Directory\File.ext
ByteCount   : 12345
PageCount   : 1

您可以将上述命令传递到Export-CSV中以创建您的CSV文件,甚至可以直接使用Out-GridView在PowerShell中查看和过滤数据。无论哪种方式,都无需解析。