jim*_*gee 6 powershell powershell-hosting write-host
Write-Host在可以针对任何合理主机实现运行的脚本中,是否有任何理智、可靠的契约指示在给定的 PowerShell 主机实现中是否受支持?
(假设我理解Write-Host和Write-Output/之间的区别,并且Write-Verbose我确实需要Write-Host语义,如果支持的话,对于这个特定的人类可读文本。)
我想尝试询问$Host变量,或$Host.UI/$Host.UI.RawUI但我发现的唯一相关差异是:
在$Host.Name:
$Host.Name = 'ConsoleHost'$Host.Name = 'Windows PowerShell ISE Host'$Host.Name = 'Default Host'在$Host.UI.RawUI:
$Host.UI.RawUI$null对于 的某些属性,ISE 不返回任何值(或)$Host.UI.RawUI,例如$Host.UI.RawUI.CursorSize$Host.UI.RawUI维护一个$Host.Name支持的值列表Write-Host似乎有点负担,尤其是现在 PowerShell 是跨平台的。我合理地希望脚本能够从任何主机调用,并且只做正确的事情。
我编写了一个脚本,可以从 PowerShell 命令提示符、ISE 或 SQL Server 代理作业中合理地运行该脚本。该脚本的输出完全是文本,供人类阅读。从命令提示符或 ISE 运行时,输出使用Write-Host.
SQL Server 作业可以通过两种不同的方式设置,并且都支持将输出捕获到 SQL Server 代理日志查看器中:
通过 CmdExec 步骤,这是简单的命令行执行,其中 Job Step 命令文本是一个可执行文件及其参数,因此您可以调用 powershell.exe 可执行文件。捕获的输出是进程的 stdout/sterr:
powershell.exe -Command x:\pathto\script.ps1 -Arg1 -Arg2 -Etc
Run Code Online (Sandbox Code Playgroud)通过 PowerShell 步骤,其中作业步骤命令文本是由其自己的嵌入式 PowerShell 主机实现解释的原始 PS 脚本。捕获的输出是通过Write-Outputor写入的任何内容Write-Error:
#whatever
Do-WhateverPowershellCommandYouWant
x:\pathto\script.ps1 -Arg1 -Arg2 -Etc
Run Code Online (Sandbox Code Playgroud)由于 SQL Server 主机实现的一些其他弱点,我发现您可以使用Write-Output或发出输出Write-Error,但不能同时使用两者。如果作业步骤失败(即如果您throw或Write-Error 'foo' -EA 'Stop'),您只会在日志中获得错误流,如果成功,您只会在日志中获得输出流。
此外,嵌入式 PS 实现不支持Write-Host. 至少在 SQL Server 2016 之前,Write-Host抛出一个System.Management.Automation.Host.HostException带有消息A command that prompt the user failed because host program or the command type does not support user interface。
到目前为止,为了支持我的所有用例,我开始使用一个自定义函数Write-Message,该函数基本上设置为(简化):
$script:can_write_host = $true
$script:has_errors = $false
$script:message_stream = New-Object Text.StringBuilder
function Write-Message {
Param($message, [Switch]$iserror)
if ($script:can_write_host) {
$private:color = if ($iserror) { 'Red' } else { 'White' }
try { Write-Host $message -ForegroundColor $private:color }
catch [Management.Automation.Host.HostException] { $script:can_write_host = $false }
}
if (-not $script:can_write_host) {
$script:message_stream.AppendLine($message) | Out-Null
}
if ($iserror) { $script:has_errors = $true }
}
try {
<# MAIN SCRIPT BODY RUNS HERE #>
}
catch {
Write-Message -Message ("Unhandled error: " + ($_ | Format-List | Out-String)) -IsError
}
finally {
if (-not $script:can_write_host) {
if ($script:has_errors) { Write-Error ($script:message_stream.ToString()) -EA 'Stop' }
else { Write-Output ($script:message_stream.ToString()) }
}
}
Run Code Online (Sandbox Code Playgroud)
从 SQL Server 2019(可能更早)开始,它似乎Write-Host不再在嵌入式 SQL Server Agent PS 主机中引发异常,而是一个不向输出或错误流发送任何内容的无操作。由于没有例外,我的脚本Write-Message函数无法再可靠地检测它是否应该使用Write-Host或StringBuilder.AppendLine。
SQL Server 代理作业的基本解决方法是使用更成熟的 CmdExec 步骤类型(其中Write-Output和Write-Host两者都被捕获为标准输出),但我更喜欢 PowerShell 步骤类型(除其他原因外)它能够可靠地将命令拆分多行,所以我很想看看是否有更全面的、基于 PowerShell 的方法来解决是否Write-Host对我所在的主机有用的问题。
实时跟踪脚本输出的另一种方法是将输出推送到日志文件,然后使用trace32 实时监视它。这只是一个解决方法,但它可能适合您。
Add-Content -Path "C:\Users\username\Documents\PS_log.log" -Value $variablewithvalue
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
291 次 |
| 最近记录: |