Show Ausfall für SQL 2005 Job, die Powershell-Skript durch CMD-Eingabeaufforderung ausgeführt wird, schlägt fehl, wenn PS-Skript

StackOverflow https://stackoverflow.com/questions/3823661

Frage

Ich habe eine SQL 2005-Instanz, die einen Auftrag ausgeführt wird, dass Anwendungen ein Powershell-Skript den aktuellen SQL TX Log Backup-Datei umbenennen von „-PrevDay“, um es anhängt, (nachfolgend die Sicherung löschen bereits den Namen „XXX-PrevDay.bak“ wenn es) vorhanden ist, und dann eine vollständige Sicherung der DB laufen und ein TX Log-Backup, wenn die DB nicht im Einfach-Modus ist.

SQL Server Agent Job Kicks aus dem Powershell-Skript durch CMD in jedem Jobschritt und die Powershell-Skript Kicks aus dem SQL-Backup "Invoke-Sqlcmd" Cmdlets. Dies funktioniert gut, es sei denn, die Sicherung fehlschlägt, weil die SQL-Auftrag noch zeigt als „Erfolgreich“. Dies liegt daran, den SQL-Auftrag, dass Kicks aus dem Powershell-Skript durch die CMD-Eingabeaufforderung, nur Sorgen, wenn das Powershell-Skript läuft ... nicht, wenn die Befehle im Skript tatsächlich Erfolg hat oder scheitern.

Ist es möglich, mit Fehlern in Powershell-Trapping (oder jede Methode wirklich), den Powershell-Skript haben, „nicht bestanden“ die cmd Aufforderung Aktion das Skript ausgeführt wird ... so dass der SQL-Job meldet einen Fehler?

Ist dies noch sinnvoll? LOL

Ich würde davon ausgehen, dass, wenn ich in der Lage bin SQL 2008 zu verwenden, die für eine SQL-Jobschritt Art von „Powershell-Skript“ (anstelle des Schritttypen mit Betriebssystem sein ..., dass Kicks aus dem PS-Skript) erlaubt würde dies kein Problem sein ... aber ... das ist keine Option.

Im Moment der Jobschritt läuft die Powershell-Skript, durch CMD mit Parameter für DBName, Pfad und Server und sieht wie folgt aus:

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

Die tatsächliche Powershell-Skript sieht wie folgt aus:

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
    {}
War es hilfreich?

Lösung

Ok, nach ein paar Blogs suchen und ein wenig trial / error / Glück ... Ich habe es zu tun, was ich will.

Ich entschied ich brauchte die Powershell-Exit-Code zurück zum cmdexec zu senden. Doch von dem, was ich gefunden, Powershell standardmäßig immer ein Exit-Code 0 (Erfolg) ... es sei denn, Sie durch ein paar Reifen springen invloving mit 2 PS-Skripte ..., die ich wirklich nicht tun wollte. Also habe ich nur trap entschieden einen Fehler und wenn irgendein Fehler aufgefangen wurde, haben es mit einem Code von 1, egal, was die PS-Skript zu beenden. Ehrlich gesagt ... alles, was ich wirklich wollte, war ein zuverlässiger Exit-Code 0 (Erfolg) oder 1 (gescheitert). So ... lange Geschichte kurz ... hier ist, wie ich meinen Code geändert.

änderte es den cmdexec jeden Schritt auf diese:

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

Dann änderte ich meinen PS-Skript:

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
    {}

Im Grunde hat es trap {$_.Exception.Message; exit 1; continue} direkt vor jeder Invoke-Sqlcmd Anweisung und endete jede Invoke-Sqlcmd Aussage mit -ea stop.

Die trap $_.Exception.Message Fallen einen Fehler ... sammelt die Fehlermeldung, dann exit 1 sofort tritt aus dem PS-Skript mit einem Exit-Code von 1.

Der SQL-Auftrag liest jeden Schritt entweder mit einem 0 oder 1 und automatisch interpretiert 0 als Erfolg und 1 als Versagen und markiert der SQL Job als Erfolg oder richtig Versagen. Plus, da ich die eigentliche Fehlermeldung erfaßt ... es zeigt in dem SQL-Auftragsverlauf auf.

Diese Wunde auf genau das, was ich brauche. :)

Wenn Sie neugierig ... hier ist die Blogs, die mir geholfen haben die meisten:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top