我们有一个部署数据库脚本的powershell脚本。但是,如果数据库脚本失败,则输出不会向PowerShell脚本抛出异常。
以下是.ps1文件的示例:
function Publish-DatabaseProject
{
sqlcmd -S . -b -v DatabaseName=Integration -q "alter table xx add test Varchar(10)"
}
function Add-Timestamp {
process {
if ($_.GetType() -eq [string]) {
"[$(Get-Date -Format o)] $_"
} else {
$_
}
}
}
function Write-LogFile {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)] [string] $Path,
[Parameter(Mandatory=$true, ValueFromPipeline=$true)] [object[]] $InputObject
)
begin {
$root = Split-Path -Path $Path -Parent
if ($root -and !(Test-Path -Path $root)) { New-Item -Path $root -Type Directory
| Out-Null }
}
process {
$InputObject |
Add-Timestamp |
Tee-Object -File $Path -Append
}
}
Publish-DatabaseProject -ErrorVariable DeployError 2>&1 |
Write-LogFile -Path "C:\output.log"
if ($DeployError -and $DeployError.Count -ne 0)
{
Write-Output "Failed"
} else
{
Write-Output "Succeeded"
}
有问题的查询是针对不存在的表执行的。文本输出显示:
[2015-12-11T14:42:45.1973944 + 00:00] Msg 4902,Level 16,State 1,Server ABDN-DEV-PC1,Line 1
[2015-12-11T14:42:45.2053944 + 00:00]无法找到对象" xx"因为它不存在或您没有权限 第
成功
我期待最后一行阅读:失败。
如果您自己运行sqlcmd行,并使用$LastExitCode
进行跟踪,则会吐出非零退出代码。
> sqlcmd -S . -b -v DatabaseName=Integration -q "alter table xx add test Varchar(10)"
Msg 4902, Level 16, State 1, Server ABDN-DEV-PC1, Line 1
Cannot find the object "xx" because it does not exist or you do not have permissions.
> $LastExitCode
1
由于各种原因,我们无法使用Invoke-SqlCmd
,并且需要坚持使用SQLCMD.exe。
我们如何才能将SQLCMD内的异常正确地映射到调用脚本?
答案 0 :(得分:3)
如果-ErrorVariable DeployError
cmdlet本身无法执行,则只会触发Publish-DatabaseProject
语句。由于该函数主要是sqlcmd.exe的包装器,因此没有任何智能来冒泡这个错误。我们可以使用$LastExitCode
自动变量来包装它。
function Publish-DatabaseProject
{
sqlcmd -S . -b -v DatabaseName=Integration -q "alter table xx add test Varchar(10)"
if ($LastExitCode -ne 0)
{
Write-error $LastExitCode
throw $LastExitCode
}
}
现在,PowerShell将从.exe中捕获此错误,您可以使用-ErrorVariable
。
<强>更新强>
因此,既然您想要在遇到错误时继续运行而不是放弃发货,我们需要用Publish-DataBaseProject
块包裹您的try{}catch{}
函数,以捕获我们正在生成的错误,不停止执行。
try {Publish-DatabaseProject -ErrorAction STOP -ErrorVariable DeployError 2>&1 |
Write-LogFile -Path "C:\output.log" }
catch{
Write-Output "Current job $($_), failed"
Write-Output "Exception $($Error.ExceptionID)"
}
现在我们正在从CMD中正确生成异常,通过我们的函数对其进行冒泡,并将其作为正常函数进行处理,所有这些都使用Native PowerShell。我相信这就是你想要做的。如果没有,请发布整个剧本的要点,我会以更有针对性的方式帮助您。