我正在编写一组脚本来管理一些需要在压缩的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。似乎都没有用。我不知道为什么要这么长时间才能回来。
有人能帮忙吗?我该换个办法吗?
我的最终目标是有一种简单的方法在一组IIS日志上运行logparser查询,这些日志已经被goal压缩并存储在netapp设备中。到目前为止,我的非压缩部分与管道工作良好,只要我直接管道到LogParser,它就能工作。当我从另一个LogParser函数中调用PowerShell时,我就有问题了。
发布于 2016-01-30 21:32:43
虽然在管道上下文中自动变量$_表示当前对象是正确的,但在您的示例中,您需要一个不同的自动变量($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
}
}https://stackoverflow.com/questions/35102649
复制相似问题