PowerShell:正在处理来自标准输出的错误(使用Nessus Essentials)


Trying to use PowerShell to capture the running status of the "Nessus Essentials" software product.  Simply trying to capture product status: running, not running, or other.  Getting the below error each time. I've tried changing `-like` to `-match` and changing string **[warn] [scanner] Not linked to a manager** to various other shorter versions, with wildcards and without,  to no avail. I still get several lines of an ugly error message when all I want is one line with the string **Not linked to a manager** returned to console with nothing beneath that.  
Pertinent snippet working incorrectly:
} elseif(($agentStatus.stdOut -like "[warn] [scanner] Not linked to a manager")) {
Throw "Not linked to a manager"

The Error:

[![enter image description here][1]][1]
The Code:

Function Start-ProcessGetStreams {

[CmdLetBinding()]
Param(
[System.IO.FileInfo]$FilePath,
[string[]]$ArgumentList
)

$pInfo = New-Object System.Diagnostics.ProcessStartInfo
$pInfo.FileName = $FilePath
$pInfo.Arguments = $ArgumentList
$pInfo.RedirectStandardError = $true
$pInfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pInfo.CreateNoWindow = $true
$pInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden

$proc = New-Object System.Diagnostics.Process
$proc.StartInfo = $pInfo

Write-Verbose "Starting $FilePath"
$proc.Start() | Out-Null

Write-Verbose "Waiting for $($FilePath.BaseName) to complete"
$proc.WaitForExit()

$stdOut = $proc.StandardOutput.ReadToEnd()
$stdErr = $proc.StandardError.ReadToEnd()
$exitCode = $proc.ExitCode

Write-Verbose "Standard Output: $stdOut"
Write-Verbose "Standard Error: $stdErr"
Write-Verbose "Exit Code: $exitCode"

[PSCustomObject]@{
"StdOut" = $stdOut
"Stderr" = $stdErr
"ExitCode" = $exitCode
}

}

Function Get-NessusStatsFromStdOut {

Param(
[string]$stdOut
)

$stats = New-Object System.Collections.Hashtable

$StdOut -split "`r`n" | % {
if($_ -like "*:*") {
$result = $_ -split ":"
$stats.add(($result[0].Trim() -replace "[^A-Za-z0-9]","_").ToLower(),$result[1].Trim())
}
}

Return $stats
}

Function Get-DateFromEpochSeconds {
Param(
[int]$seconds
)

$utcTime = (Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($seconds))
Return Get-Date $utcTime.ToLocalTime() -Format "yyyy-MM-dd HH:mm:ss"
}    

Try {
$nessusExe = Join-Path $env:ProgramFiles -ChildPath "TenableNessusnessuscli.exe" -ErrorAction Stop
}  Catch {
Throw "Cannot find NessusCli.exe"
}

Write-Host "Getting Agent Status..."
$agentStatus = Start-ProcessGetStreams -FilePath $nessusExe -ArgumentList "managed status"

If($agentStatus.stdOut -eq "" -and $agentStatus.StdErr -eq "") {
Throw "No Data Returned from NessusCli"
} elseif($agentStatus.StdOut -eq "" -and $agentStatus.StdErr -ne "") {
Throw "StdErr: $($agentStatus.StdErr)"
} elseif(($agentStatus.stdOut -like "[warn] [scanner] Not linked to a manager")) {
Throw "Not linked to a manager"
} elseif(-not($agentStatus.stdOut -like "*Running: *")) {
Throw "StdOut: $($agentStatus.StdOut)"
} else {
$stats = Get-NessusStatsFromStdOut -stdOut $agentStatus.StdOut
If($stats.last_connection_attempt -as [int]) { $stats.last_connection_attempt = Get-DateFromEpochSeconds $stats.last_connection_attempt }
If($stats.last_connect -as [int]) { $stats.last_connect = Get-DateFromEpochSeconds $stats.last_connect }
If($stats.last_scanned -as [int]) { $stats.last_connect = Get-DateFromEpochSeconds $stats.last_scanned }
}

$stats | Out-Host
Note: Code above is courtesy of [here][2], I've only made a change to the path of Nessus, and I am adding the attempt to capture that it's not connected to a manager.

修改代码,使其将标准输出与错误输出分开,并分别处理每一行。

下面是如何捕获程序的标准输出(不包括else语句和错误处理)(根据$Proc变量)

if ($proc.Start())
{
while (!$proc.StandardOutput.EndOfStream)
{
$StreamLine = $proc.StandardOutput.ReadLine()
if (![string]::IsNullOrEmpty($StreamLine))
{
# TODO: Duplicate code in this scope as needed or rewrite to use multiline regex
$WantedLine = [regex]::Match($StreamLine, "(?<wanted>.*Not linked to a manager.*)")
$Capture = $WantedLine.Groups["wanted"]
if ($Capture.Success)
{
Write-Output $Capture.Value
}
}
}
}

之后分别处理错误输出:

$StandardError = $Proc.StandardError.ReadToEnd()
if (![string]::IsNullOrEmpty($StandardError))
{
# Or use Write-Error
Write-Output $StandardError
}

相关内容

  • 没有找到相关文章

最新更新