我正在处理一组脚本来管理我需要在gzip的非常糟糕的IIS日志上执行的一些日志记录任务。在处理它时,我遇到了管道问题logparser
。我将我的问题简化为以下内容。
如果我运行它,它按预期工作。日志文件不是很大,而且返回的速度非常快。
$query = "Select s-computername, Count(*) as count FROM stdin GROUP by s-computername"
Get-Content .\01-01-16\ex160101.log |
LogParser "$query" -i:IISW3C -o:CSV -headers:ON -fileMode:1 -q:ON
但是,如果我想将LogParser
部分放入PowerShell函数中以简化其运行。事实上,我真的想传递查询,但我试图从我能想到的最简单的事情向后工作。
这就是我最终的结果。
Function Test-IISLog {
Begin {
$query = "Select s-computername, Count(*) as count FROM stdin GROUP by s-computername"
}
Process {
$_ | LogParser "$query" -i:IISW3C -o:CSV -headers:ON -fileMode:1 -q:ON | Write-Output
}
}
Get-Content .\01-01-16\ex160101.log | Test-IISLog
当我跑步时,它只是旋转它的车轮很长一段时间。我尝试了这个命令的不同组合,没有$_
,一个没有Write-Output
。似乎没有工作。我不知道为什么要花这么长时间才能回来。
任何人都可以帮忙吗?我应该这样做吗?
我的最终目标是使用一种简单的方法在一组已经gzip压缩并存储在netapp设备中的IIS日志上运行logparser
查询。到目前为止,我的ungzipping部分与管道配合良好,只要我直接管道到LogParser,它就可以工作。我在另一个PowerShell函数中调用LogParser
时遇到了问题。
答案 0 :(得分:0)
虽然在管道上下文中自动变量$_
表示当前对象是正确的,但在您的情况下,您需要一个不同的自动变量($input
,如Mathias所建议的那样),因为你需要处理函数输入,即使它来自管道:
function Test-IISLog {
End {
$query = "SELECT s-computername, Count(*) AS count FROM stdin GROUP BY s-computername"
$input | LogParser "$query" -i:IISW3C -o:CSV -headers:ON -fileMode:1 -q:ON
}
}
<强>
$Input
强>
包含枚举器,枚举传递给函数的所有输入。$input
变量仅适用于函数和脚本块(未命名的函数)。在函数的Process
块中,$input
变量枚举当前在管道中的对象。当Process
块完成时,管道中没有剩余对象,因此$input
变量枚举空集合。如果函数没有Process
块,则在End
块中,$input
变量枚举函数的所有输入的集合。
你也可以给函数一个实际参数并使用它而不是自动变量,但是你必须自己收集数组中的行:
function Test-IISLog {
[CmdletBinding()]
Param(
[Parameter(
Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true
)]
[string[]]$LogLine
)
Begin {
$query = "SELECT s-computername, Count(*) AS count FROM stdin GROUP BY s-computername"
$lines = @()
}
Process {
$lines += $LogLine
}
End {
$lines | LogParser "$query" -i:IISW3C -o:CSV -headers:ON -fileMode:1 -q:ON
}
}
然而,为什么要首先解决所有这些麻烦? logparser
可以自行读取文件:
$filename = 'C:\path\to\ex160101.log'
$query = @"
SELECT s-computername, Count(*) AS count
FROM '$filename'
GROUP BY s-computername
"@
& logparser.exe $query -i:IISW3C -o:CSV -headers:ON -fileMode:1 -q:ON
如果我将文件名传递给函数:
function Test-IISLog {
[CmdletBinding()]
Param(
[Parameter(
Mandatory=$true,
Position=0,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true
)]
[ValidateScript({Test-Path -LiteralPath $_})]
[string]$Filename
)
Process {
$query = @"
SELECT s-computername, Count(*) AS count
FROM '$filename'
GROUP BY s-computername
"@
& logparser.exe $query -i:IISW3C -o:CSV -headers:ON -fileMode:1 -q:ON
}
}