powershell - 如果PS脚本失败,则显示通过CMD提示执行Powershell脚本的SQL 2005作业失败

  显示原文与译文双语对照的内容
0 0

我有一个sql 2005实例运行工作,使用sqlTXpowershell脚本重命名当前日志备份文件通过添加"-prevday",( 随后删除已经命名的备份"xxx prevday。贝克"如果存在), 然后运行数据库的完整备份和tx日志备份,如果db NOT 在简单模式。

在每个作业步骤中,SQL Server Agent 作业都通过启动了Powershell脚本,而Powershell脚本则使用"调用 sql CMD"cmdlet启动了sql备份。 这很好,除非备份失败,因为SQL作业仍然显示为"成功"。 这是因为通过CMD提示符启动Powershell脚本的SQL作业只关心Powershell脚本是否运行。如果脚本中的命令实际上成功或者失败了。

是否可能在 powershell ( 或者任何方法) 中使用错误捕获使powershell脚本"失败"运行脚本的提示操作。使SQL作业报告失败?

这是不是有意义? LOL

我认为如果我能够使用sql 2008,它允许一个sql工作步骤"脚本脚本"类型(而不是步骤类型 Having 操作系统。启动这个ps脚本)这将不是一个问题。然而。这是 NOT 一个选项。

现在,作业步骤运行powershell脚本,通过使用参数为 DBName,路径和Servername使用参数,如下所示:


powershell.exe"C:SQLBackupScriptsTestSQLServerBackup.ps1" -DBName 'Angel_Food' -Path 'E:SQLBackup1' -Server 'DEVSQLSRV'

实际的Powershell脚本如下所示:


Param($DBName,$Path,$Server)

## Add sql snapins...must have for Invoke-Sqlcmd with powershell 2.0 ##

add-pssnapin sqlserverprovidersnapin100
add-pssnapin sqlservercmdletsnapin100
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null

## Set parameter for finding DB recovery model ##
$Recovery = (Invoke-Sqlcmd -Query"SELECT recovery_model_desc FROM sys.databases WHERE name = '$DBName'" -Server $Server)

## Do full backup of DB ##
(Invoke-Sqlcmd -Query"BACKUP DATABASE $DBName TO DISK = N'$Path$DBName$DBName.bak' WITH NOFORMAT, INIT, NAME = N'$DBNameTEST', SKIP, NOREWIND, NOUNLOAD, STATS = 10, CHECKSUM" -Server $Server -ConnectionTimeout 0 -QueryTimeout 65535)

############################################################################################################
## Check recovery mode, if FULL, check for Log-PrevDay.bak. If exists then delete. If not exist, move on ##
## Then check for Current TX log backup. If exists, rename to Log-PreDay.bak. If not exist, move on ##
## Then perform TX Log backup ##
## If recovery mode NOT FULL, do nothing ##
############################################################################################################
 IF
 ($Recovery.recovery_model_desc -eq 'FULL')
 #THEN#
 {
 ## Look to see if PrevDay TX log exists. If so, delete, if not, move on ##
 IF 
 (Test-Path $Path$DBName$DBName-Log-PrevDay.bak) 
 #THEN#
 {remove-item $Path$DBName$DBName-Log-PrevDay.bak -force}
 ELSE
 {}
 ## Look to see if current TX log exists, if so, rename to Prev Day TX Log, if not, move on ##
 IF
 (Test-Path $Path$DBName$DBName-Log.bak)
 #THEN#
 {rename-item $Path$DBName$DBName-Log.bak -newname $DBName-Log-PrevDay.bak -force}
 ELSE
 {}

 Invoke-Sqlcmd -Query"BACKUP LOG $DBName TO DISK = N'$Path$DBName$DBName-Log.bak' WITH NOFORMAT, INIT, NAME = N'$DBName LogTEST (Init)', SKIP, NOREWIND, NOUNLOAD, STATS = 10, CHECKSUM" -Server $Server -ConnectionTimeout 0 -QueryTimeout 65535}
 ELSE
 {}

时间: 原作者:

0 0

好的,在看了几个博客和一个小 trial/error/luck...I,让它做我想要的。

确定是使用显式宽度还是测量宽度的一种简便方法。 但是,从我发现,Powershell总是默认的退出代码 0 ( 成功) 。除非你使用 2 PS脚本来跳过几个 invloving - - 我真的不想这样做。 所以我决定只捕获任何错误,如果捕获错误,让它用 1代码退出PS脚本,不管什么原因。 老实说。我真正想要的是一个可靠的0 ( 成功) 或者 1 ( 失败) 退出代码。 长话短说。我改变了我的代码。

我将每个步骤的CMDEXEC更改为:


powershell.exe -noprofile C:SQLBackupScriptsTestSQLServerBackup2.ps1 -DBName 'Angel_Food' -Path 'E:SQLBackup' -Server 'DEVSQLSRV'
@Echo %errorlevel%

然后,我将PS脚本改为:


Param($DBName,$Path,$Server)

## Add sql snapins...must have for Invoke-Sqlcmd with powershell 2.0 ##

add-pssnapin sqlserverprovidersnapin100
add-pssnapin sqlservercmdletsnapin100
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null

## Set parameter for finding DB recovery model ##
$Recovery = (Invoke-Sqlcmd -Query"SELECT recovery_model_desc FROM sys.databases WHERE name = '$DBName'" -Server $Server)

## Do full backup of DB ##
trap {$_.Exception.Message; exit 1; continue}Invoke-Sqlcmd -Query"BACKUP DATABASE $DBName TO DISK = N'$Path$DBName$DBName.bak' WITH NOFORMAT, INIT, NAME = N'$DBNameTEST', SKIP, NOREWIND, NOUNLOAD, STATS = 10, CHECKSUM" -Server $Server -ConnectionTimeout 0 -QueryTimeout 65535 -ea stop

############################################################################################################
## Check recovery mode, if FULL, check for Log-PrevDay.bak. If exists then delete. If not exist, move on ##
## Then check for Current TX log backup. If exists, rename to Log-PreDay.bak. If not exist, move on ##
## Then perform TX Log backup ##
## If recovery mode NOT FULL, do nothing ##
############################################################################################################
 IF
 ($Recovery.recovery_model_desc -eq 'FULL')
 #THEN#
 {
 ## Look to see if PrevDay TX log exists. If so, delete, if not, move on ##
 IF 
 (Test-Path $Path$DBName$DBName-Log-PrevDay.bak) 
 #THEN#
 {remove-item $Path$DBName$DBName-Log-PrevDay.bak -force}
 ELSE
 {}
 ## Look to see if current TX log exists, if so, rename to Prev Day TX Log, if not, move on ##
 IF
 (Test-Path $Path$DBName$DBName-Log.bak)
 #THEN#
 {rename-item $Path$DBName$DBName-Log.bak -newname $DBName-Log-PrevDay.bak -force}
 ELSE
 {}

 trap {$_.Exception.Message; exit 1; continue}Invoke-Sqlcmd -Query"BACKUP LOG $DBName TO DISK = N'$Path$DBName$DBName-Log.bak' WITH NOFORMAT, INIT, NAME = N'$DBName LogTEST (Init)', SKIP, NOREWIND, NOUNLOAD, STATS = 10, CHECKSUM" -Server $Server -ConnectionTimeout 0 -QueryTimeout 65535 -ea stop}
 ELSE
 {}

基本上我添加了 trap {$_.Exception.Message; exit 1; continue} 在每个 Invoke-Sqlcmd 语句前面,并用 -ea stop 结束每个 Invoke-Sqlcmd 语句。

trap $_.Exception.Message 捕获任何错误。 收集错误消息,然后 exit 1 立即退出带有 1 退出代码的PS脚本。

SQL作业使用 0或者 1读取每个步骤,并自动将 0解释为成功和 1,并将SQL作为成功或者失败标记为成功或者失败。 另外,由于我捕获了实际的错误消息。它显示在SQL作业历史记录中。

这完全是我所需要的。 : )

如果你好奇。这是给我最大帮助的博客

...