PowerShell的保存标准输出和显示标准输出

问题描述:

我使用PowerShell来发动所谓的GoodSync一个应用程序为我进行备份。在这个过程结束时,我会通过电子邮件向我发送结果。我还喜欢(有时)观看PowerShell窗口以关注它并在处理备份时观察备份的状态。正如我的代码现在,标准输出将控制台,就是这样。PowerShell的保存标准输出和显示标准输出

我的问题:是否有可能让stdout转到控制台,并将其保存到变量以备后续处理?

你可以看到我试图用$输出变量的东西,但一事无成。这里的错误$输出返回:

You cannot call a method on a null-valued expression. 
At GoodSync.ps1:119 char:42 
+  $output = $proc.StandardOutput.ReadToEnd <<<<() 
    + CategoryInfo   : InvalidOperation: (ReadToEnd:String) [], Runtime 
    Exception 
    + FullyQualifiedErrorId : InvokeMethodOnNull 

You cannot call a method on a null-valued expression. 
At GoodSync.ps1:120 char:42 
+  $output += $proc.StandardError.ReadToEnd <<<<() 
    + CategoryInfo   : InvalidOperation: (ReadToEnd:String) [], Runtime 
    Exception 
    + FullyQualifiedErrorId : InvokeMethodOnNull 

这里是我的代码:

(而且是从你大师那里一点点积极的,是的,我做了很多与此代码输出到这两个文件和stdout,所以我可以保持眼睛上的一切。这部分只是整个文件的片段。)

############################### 
## Call the GoodSync process ## 
############################### 

# This is the section taken from http://*.com/questions/8925323 
# This is a known working section. However, right now I don't know how to save the stdout to variable and insert into email log file. 
$procInfo = New-Object System.Diagnostics.ProcessStartInfo 
$procInfo.FileName = "C:\Program Files\Siber Systems\GoodSync\gsync.exe" 
$procInfo.UseShellExecute = $false 
$procInfo.Arguments = '/progress=yes /exit sync MyBackupJobName' 
$proc = New-Object System.Diagnostics.Process 
$proc.StartInfo = $procInfo 
$proc.Start() | Out-Host 
(Get-Date -format T) + " - Loaded gsync.exe. Backup process running. Please stand by..." | Tee-Object -Variable RoboLog 
$RoboLog >> $myLogFile 
"" | Tee-Object -Variable RoboLog 
$RoboLog >> $myLogFile 
$proc.WaitForExit() 
(Get-Date -format T) + " - Backup complete and gsync.exe has exited." | Tee-Object -Variable RoboLog 
$RoboLog >> $myLogFile 
"" | Tee-Object -Variable RoboLog 
$RoboLog >> $myLogFile 

# Now we take the exit code, write it to console and log file, and begin to build our email report. 
if ($proc.ExitCode -eq 0) { 
    "Success: GoodSync Reported: Analyze or Sync Successfully Completed." | Tee-Object -Variable RoboLog 
    $RoboLog >> $myLogFile 
    $subject = $RoboLog 
    "" | Tee-Object -Variable RoboLog 
    $RoboLog >> $myLogFile 
} elseif ($proc.ExitCode -eq 1) { 
    "Failure: GoodSync Error: Analyze had Terminal Errors. Did gsync.exe close abruptly?" | Tee-Object -Variable RoboLog 
    $RoboLog >> $myLogFile 
    $subject = $RoboLog 
    "" | Tee-Object -Variable RoboLog 
    $RoboLog >> $myLogFile 
} elseif ($proc.ExitCode -eq 2) { 
    "Failure: GoodSync Error: Sync had Terminal Errors. Did gsync.exe close abruptly?" | Tee-Object -Variable RoboLog 
    $RoboLog >> $myLogFile 
    $subject = $RoboLog 
    "" | Tee-Object -Variable RoboLog 
    $RoboLog >> $myLogFile 
} else { 
    "Failure: GoodSync Error: General Error. Check log file." | Tee-Object -Variable RoboLog 
    $RoboLog >> $myLogFile 
    $subject = $RoboLog 
    "" | Tee-Object -Variable RoboLog 
    $RoboLog >> $myLogFile 
} 

# Grab the stdout and stderr to a variable 
$output = $proc.StandardOutput.ReadToEnd() 
$output += $proc.StandardError.ReadToEnd() 
# The ReadToEnd() makes everything 1 long string, so we break it up by carriage return, and filter 
$output -split "`n" 
# Write to log file for email capture 
$output >> $myLogFile 

"" | Tee-Object -Variable RoboLog 
$RoboLog >> $myLogFile 

#--------------------------------------------------------------------------------------------------- 
# GoodSync backup jobs are now complete. 
#--------------------------------------------------------------------------------------------------- 

$proc.StandardOutput.ReadToEndYou cannot call a method on a null-valued expression.)中的错误是因为你需要设置的这些属性ProcessStartInfo对象:

$procInfo.RedirectStandardError = $true 
$procInfo.RedirectStandardOutput = $true 

注 - 设置这些时,输出将被显示在控制台上。

而且这里有一个方法来存储输出变量并在控制台上显示它使用Tee-Object

& ping.exe localhost -n 1 | Tee-Object -Variable output 
$output 

顺便说一句 - 您可以在$LASTEXITCODE做一个开关 - 例如

switch ($LASTEXITCODE) { 
    0 {'good'} 
    1 {'bad'} 
    2 {'ugly'} 
} 
+0

谢谢安迪,我已经添加了这些重定向,但现在我不没有任何东西显示在控制台中,并基于您的示例(我没有使用ping.exe,但假设我将其替换为gsync.exe),我不确定我会在代码中保留它的位置?它是实时显示呢? – Pat 2013-04-23 20:32:44

+0

@Pat,你可以使用'System.Diagnostics.Process'类。因此,而不是使用不重定向*和*显示,只是用电话运营商'&'(例如给调用程序用ping.exe的),你可以使用'$ LASTEXITCODE'后检查退出代码。 – 2013-04-23 20:34:51

+0

好吧,我会给一个尝试。 – Pat 2013-04-23 20:40:31

为什么不把它作为后台工作来运行?然后你可以使用接收-工作得到输出(多次,只要你想,如果你使用 - 保持,并且做任何你想做的事情。

+0

听起来不错,但我不得不承认:我不知道该怎么做。 (至少我不认为我知道)。这段代码主要来自代码注释区域中的*链接。我猜这是开始 - 过程?我在这边做了一些小小的阅读。 – Pat 2013-04-23 20:37:56

+2

开始获取帮助About_Jobs – mjolinor 2013-04-23 20:42:09

+0

会这样做,谢谢。 – Pat 2013-04-23 21:07:28