我想为一堆模块提供一些使用统计信息。
如果我可以在从一组模块调用函数时运行代码,那将会很方便。它可行吗? powershell会生成我们可以挂钩的内部事件吗?我找不到任何指导
答案 0 :(得分:2)
我并不完全清楚您是否对记录事件或执行代码(挂钩)更感兴趣。
在Powershell写入日志的事件日志中有两个位置:
Applications and Services > Windows PowerShell
Applications and Services > Microsoft > Windows > PowerShell
在每个模块级别,您可以启用LogPipelineExecutionDetails
属性。要在加载时执行:
$mod = Import-Module ActiveDirectory
$mod.LogPipelineExecutionDetails = $true
或已经加载的模块:
$mod = Get-Module ActiveDirectory
$mod.LogPipelineExecutionDetails = $true
之后,检查我列出的第一个事件日志位置(Windows PowerShell
),您将看到显示带有绑定参数的各种cmdlet调用的日志。
您也可以通过组策略将其作为计算机或用户设置启用:
Administrative Templates > Windows Components > Windows PowerShell > Turn On Module Logging
您可以指定要为其启用日志记录的模块。
在PowerShell v5中,将提供更详细的日志记录(请参阅链接)。
您可以在Boe Prox's blog: More New Stuff in PowerShell V5: Extra PowerShell Auditing
上查看有关日志记录设置(当前和即将推出)的更多详细信息据我所知,没有直接的方法来挂钩现有模块中的调用,但我有一个糟糕的解决方法。
使用此方法,您可以围绕要跟踪的特定功能创建包装器。考虑这样的事情:
# Override Get-Process
function Track-GetProcess {
[CmdletBinding()]
param(
# All the parameters that the original function takes
)
# Run pre-execution hook here
& { "before" }
$params = @{}
foreach($h in $MyInvocation.MyCommand.Parameters.GetEnumerator()) {
try {
$key = $h.Key
$val = Get-Variable -Name $key -ErrorAction Stop | Select-Object -ExpandProperty Value -ErrorAction Stop
if (([String]::IsNullOrEmpty($val) -and (!$PSBoundParameters.ContainsKey($key)))) {
throw "A blank value that wasn't supplied by the user."
}
Write-Verbose "$key => '$val'"
$params[$key] = $val
} catch {}
}
Get-Process @params # call original with splatting
# run post execution hook here
& { "after" }
}
中间有uses splatting to send the given parameters and sending them to the real cmdlet。
最难的部分是手动重新创建参数块。如果你想快速运行一些东西来挂钩任何函数,你有可能以编程方式执行此操作,但这有点超出了这个答案的范围。如果你想走这条路,请看一下this New-MofFile.ps1 function中的一些代码,它们使用powershell自己的解析器来解析powershell代码。