我希望能够将我手动输入的每个命令包装到具有我自己功能的交互式Powershell控制台中,有没有办法以理智的方式拦截它?我想要完成的是为每个命令计时,如果超过30秒,则在完成时自动弹出BurntToast通知。
我会用这样的工作:
function Invoke-CommandWithTimeout {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[Management.Automation.ScriptBlock]$ScriptBlock,
[Parameter(Mandatory=$false)]
[array]$ArgumentList = @(),
[Parameter(Mandatory=$false)]
[int]$Timeout = 30
)
$job = Start-Job -ScriptBlock $ScriptBlock -ArgumentList $ArgumentList
Wait-Job -Job $job -Timeout $Timeout
if ($job.State -ne 'Stopped') {
$job.StopJob()
Write-Warning 'Command timed out.'
}
Receive-Job -Job $job
Remove-Job -Job $job
}
Invoke-CommandWithTimeout {Test-Connection 'server.example.org'}
我不知道如何自动和透明地拦截在PowerShell控制台中输入的任何命令并以不同的方式运行它。
如果您只想测量交互式命令的执行时间,而不是更改或中断它们,那么您可以覆盖Out-Default
命令:
function Out-Default {
begin {
$StartTime = Get-Date
$OutDefault = { Microsoft.PowerShell.Core\Out-Default @args }.GetSteppablePipeline($MyInvocation.CommandOrigin)
$OutDefault.Begin($MyInvocation.ExpectingInput, $ExecutionContext)
}
process {
if($MyInvocation.ExpectingInput) {
$OutDefault.Process($_)
} else {
$OutDefault.Process()
}
}
end {
$OutDefault.End()
$OutDefault.Dispose()
$ExecutionTime = New-TimeSpan -Start $StartTime
if($ExecutionTime -gt (New-TimeSpan -Seconds 30)) {
Write-Host -ForegroundColor Red -Object $ExecutionTime
# popup toast notification
} else {
Write-Host -ForegroundColor Green -Object $ExecutionTime
}
}
}
PowerShell隐式注入Out-Default
命令,以便在PowerShell控制台中显示结果。