New Blog

Dear reader,

To work more inline with my twitter activities and to open my blog for more interessting stuff (not just Veeam related), I am blogging only on the http://andyandthevms.com/ blog from now.

If I will write some updates at individual posts (e.g. Exchange Backup stuff) I will add an warning message with a link to the article on this blog.

So do not hesitate to check out my new blog under http://andyandthevms.com

Thanks for all the Feedback and support

Andy

Freitag, 5. August 2011

Einführung in die Veeam Powershell

Ein neues Wochenende ... ein neuer Beitrag.
In der vergangenen Wochen bin ich immer wieder auf 2 Themen von Kunden angesprochen worden.
1. Ich würde gerne ein Backup Skript erstellen, wie finde ich am besten den Einstieg?
2. Bei der Near-CDP Replikation (Replikation startet sofort nach dessen Beendigung wieder) würde ich diese gerne anhalten um ein Backup zu erstellen. Wie kann ich dies steuern?

Somit kombiniere ich einfach diese beiden Anforderungen in diesem Tutorial. Viel Spaß beim lesen und viel Erfolg beim umsetzten.

Die hier gezeigten Beispiele müssen nicht zwingend in Ihre Umgebung passen. Bitte prüfen Sie den gesamten Code sorgsam bevor Sie Ihn in einer Testumgebung einsetzten. Prüfen Sie hier ob alles soweit funktioniert, keine Fehler auftreten und ob die Replikationsziele und Backups auch die passenden Daten aufweisen. Das Backup kann z.B. mit einem SureBackup Job geprüft werden und die Replikation in dem Sie die Replik der Server aus Backup & Replikation heraus ohne Netzwerkkarten (im VCenter abhängen) starten. Bitte nicht die Replik mit dem vCenter starten, hierbei werden alle übrigen Replikationsstände verworfen. Wenn Sie sich dann sicher fühlen, kann der Code in der produktive Umgebung übernommen werden. Der Author dieses Beitrags haftet nicht für eventuell auftretenden Datenverlust. Prüfen Sie Ihre Arbeit auf jedenfall gegen!!!! Als Testumgebung können Sie z.B. einen Ihrer Windows Server mit der SureBackup Funktion in ein Virtual Lab starten, dort Backup & Replication erneut installieren und den Code testen.

Anforderungen:
Aktuelle Veeam Backup & Replication Version
Falls Sie Windows 2003 Server einsetzten muss von Microsoft noch die Powershell nachinstalliert werden.
Die Skripte funktionieren nur direkt auf dem Backupserver.

Grundüberlegung und Ausgangssituation:
Wir haben einen Replikationsjob Namens SQL-REPLIKATION der zeitgesteuert oder kontinuierlich einen oder mehrere Server repliziert. Ein weiterer Job sichert als Backupjob die selben Server. Jobname hierfür SQL-BACKUP.
Ziel ist es
1. Den SQL-REPLIKATION Job anzuhalten, bzw. diesen fertig durchlaufen zu lassen.
2. Ein Backup mit SQL-BACKUP zu erstellen.
3. Anschließend den Replikationsjob wieder zu starten und zu prüfen ob die Replikation wieder angelaufen ist.

Grundüberlegungen zum Code:
Wir erstellen eine Powershell-Skriptdatei (*.ps1) die den Code aufnimmt.
Eine weitere "Start"-Datei (*.ps1 oder *.bat) die Parameter an die Powershell-Skriptdatei übergiebt.

Wir benötigen 2 variable Werte die wir an die Skriptdatei übergeben:
Replikationsjobname
Backupjobname
dateiname.ps1 -parameter1 wert1 -parameter2 wert2

# In unserem Fall
dateiname.ps1 -jobname SQL-REPLIKATION -backupjobname SQL-BACKUP

Erstellung der Startdatei:
Erstellen Sie mit dem Windows Editor eine Textdatei mit der Endung .bat .
Legen Sie diese in ein Verzeichnis ab. Editieren Sie diese mit dem Editor.

Zunächst erstellen wir in der Datei 5 Variable die wir mit folgendem füttern:
1. Parameter für den Pfad zur Powershell-EXE von Windows
2. Pfad zu der noch zu erstellenden PS1 Datei
3. Replikationsjobname
4. Backupjobname
5. Pfad zur Logdatei.

REM  PowerShell.exe
set powershell="c:\windows\system32\windowspowershell\v1.0\powershell.exe"

REM  Set Folder with the VBRStopCDPStartBackupRestartCDP.ps1 in it
set PS1=E:\Backups\VBRStopCDPStartBackupRestartCDP.ps1

REM Set CDP Jobname
set REPLIKATION=SQL-REPLIKATION

REM Set Backupjobname
set BACKUP=SQL-BACKUP

REM Output LOG
set joblog=E:\Backups\VBRStopCDPStartBackupRestartCDP.log


Danach erstellen wir die eigentliche Ausführungszeile die die Parameter im richtigen Kontext aufruft. ">>" bedeutet, dass in der Log Datei alle neuen Ereignisse immer angehängt werden.
Eventuell wird diese Log Datei über die Monate zu groß und Sie müssen das Skript später anpassen.
"%powershell%" "%PS1%" -jobname "%REPLIKATION%" -backupjobname "%BACKUP%" >> "%joblog%"

Grundlagen Powerhellskript
Write-Output "Text"
gibt einen Text aus. Bei uns ist die Ausgabe mit >> in eine Log Datei umgelenkt. Somit bleibt das Skriptfenster einfach schwarz.

$AStartTime =
setzt eine Variable mit dem Wert der hinter dem Gleich kommt. Diese Variable kann dann an beliebiger Stelle im Code mit
$AStartTime
wieder abgerufen werden.

$variable.irgendetwas
Bietet die Möglichkeit Erweiterungen der jeweiligen Variablen abzufragen.

z.B.:
Wenn wir den Veeamjob in die variable "&infodisjob" geschrieben haben, können wir mit
$infodisjob.Info.IsScheduleEnabled
abrufen, ob der Scheduler des Jobs enabled ist.

Hierbei wird .Info.IsScheduleEnabled durch Backup & Replication definiert, sprich dies ist keine direkte Funktion der Powershell.

Wo stehen jetzt die ganzen Möglichkeiten der Funktionen?

Zunächst kann in der Powershell eine Übersicht aller Veeam Befehle abgerufen werden.
add-pssnapin veeampssnapin
get-command -pssnapin veeampssnapin

Mit
get-help Veeambefehl -full
erhalten Sie alle Informationen über den Befehl.

Befehle, Informationen und Einstellungen zu den Jobs können Sie wie folgt abrufen:
$job = Get-VBRJob | ?{$_.name –eq “Jobname”}
$job | gm


Sie können eine oder mehrere Ebene tiefer springen in dem Sie einen der Befehle aus der Liste mit einem Punkt hinzufügen und z.B. folgendes aufrufen:
$job = Get-VBRJob | ?{$_.name –eq “Jobname”}
$job.getvssoptions | gm
$job.getvssoptions() | gm


Hierbei liefert der Befehl mit und ohne Klammern andere Werte.

In dem Userguide und in dem Veeam Forum finden Sie weitere Beispiele und Optionen. Warum sich Plagen wenn schon andere sich die Arbeit gemacht haben :-)
Am besten bei Google eingeben "+site:veeam.com +forum +powershell +Suchbegriff"

Übrigens finden Sie dort auch Hilfe bei Codefragen. Hierbei gillt wie immer: Zuerst die Suche verwenden, das gefundene auch Auswerten und dann Fragen stellen.

Die Skriptdatei
Erstellen Sie z.B. mit dem Windows Editor eine leere Datei mit der Endung .ps1.
Editieren Sie diese Datei mit einem Powershell Editor oder dem Windows Editor.

Und schon geht es mit der eigentlichen Arbeit los:

Übergabewerte mit param definieren:
param ([string]$JobName, [string]$BackupJobName)

Startzeitpunkt für das Log in eine variable einlesen und passend formatieren:
$AStartTime = get-date
$AStartTimeFormated = $AStartTime.ToUniversalTime()
Um Veeam befehle in der Powershell verwenden zu können müssen wir zunächst ein Veeam Powershell Plugin laden, welches mit Backup&Replication installiert wurde (Code stammt von Veeam Matt Carpenter´s PSHelperv1 Kit):
# Load Veeam Powershell Snapin 
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

Wir prüfen jetzt ab ob der Backupserver auch ein Veeam Backup&Replication Server ist. Wir verwenden IF ELSE um eine Fehlermeldung auszugeben oder den restlichen Code auszuführen. Die } Klammer muss ganz am Schluss Ihres Code angebracht werden, da wir ja den restlichen Code nur ausführen wollen wenn der Server auch ein Backup & Replication Server ist.(Code stammt von Veeam Matt Carpenter´s PSHelperv1 Kit):
$BackupServer = Get-VBRlocalhost

IF ($BackupServer -eq $NULL)
{
Write-Output "There is an issue with the local Veeam Backup instance"
}
ELSE
{ 
Hier steht Ihr restlicher Code
}
Nun steht eine Prüfung der beiden übergebenen Job Parameter an. Sind diese auch im Backup&Replication als Jobs vorhanden. Auch hier wiederum brauchen wir zwei } am ganz unteren Ende des Codes(Code stammt von Veeam Matt Carpenter´s PSHelperv1 Kit).

$BackupJobCheck1 = Get-VBRJob | where {$_.Name -eq $JobName}


IF ($BackupJobCheck1 -eq $NULL)

{
Write-Output "Cannot start Veeam Job"
Write-Output "$JobName does not exist"
}

ELSE
{

$BackupJobCheck2 = Get-VBRJob | where {$_.Name -eq $BackupJobName}


IF ($BackupJobCheck2 -eq $NULL)

{
Write-Output "Cannot start Veeam Job"
Write-Output "$BackupJobName does not exist"
}

ELSE
{
Hier steht Ihr restlicher Code
}}

Jetzt der Bereich in dem wir den Ausführungszeitplan (Scheduler) des Replikationsjobs anhalten.
1. Wir schreiben die Zeit ins Logfile.
2. Wir schreiben, was wir ausführen ins Logfile.
3. Name des Replikationsjobs festlegen.
4. Halte den Scheduler an.
5. Lies nochmals den Replikationsjob ein, um aktuelle Statuswerte zu erhalten.
6. Setze eine Variable mit dem Wert "None" welches dem Wert des ausgeschalteten Schedulers entspricht (Diesen werden wir später verwenden)
7. Prüfe ob der Scheduler eingeschaltet ist.
8. Gebe das Ergebnis in das LOG aus.
Write-Output "Job started: $AStartTimeFormated"
Write-Output "Disabling Veeam Backup/Replication Job $JobName"
$disjob = Get-VBRJob | where {$_.name -eq $Jobname}
$disjob.DisableScheduler()
$infodisjob = Get-VBRJob | where {$_.name -eq $Jobname}
$disjobendstatus = "None"
$infodisjobanzeigeend = $infodisjob.Info.IsScheduleEnabled
Write-Output "Actual Status of the Veeam $Jobname Job: $infodisjobanzeigeend"

Eventuell ist jetzt noch immer ein Replikationsjob aktiv - wenn wir z.B. den Zeitplan mitten in der Ausführung angehalten haben. Wir warten in einer Schleife die Beendigung des letzten Jobs ab. Löschen Sie nicht die Zeile mit dem Get-VBRJob heraus, da Sie sonst bei Info.LatestStatus nicht den dann aktuellen Wert angezeigt bekommen.
DO{
$infodisjob = Get-VBRJob | where {$_.name -eq $Jobname}
Write-Output "Waiting until the Veeam $Jobname Job is finished. Waiting 10 seconds"
Start-Sleep -s 10
}
UNTIL ($infodisjob.Info.LatestStatus -ne $disjobendstatus)

$infodisjobanzeige = $infodisjob.Info.LatestStatus
Write-Output "The last state of the Veeam $Jobname Jobs was: $infodisjobanzeige"

Kaum sind wir aus der Schleife heraus, ist es an der Zeit den Backup Job auszuführen.
1. Schreiben in das Log was wir tun
2. Abrufen der Job Parameter
3. + 4. Starten des Backup Jobs (Geht theoretisch auch kürzer - dann können wir aber nicht die nun folgenden Werte in Variablen speichern (5. - 12.), um Sie später auszugeben. (Code stammt von Veeam Matt Carpenter´s PSHelperv1 Kit):
Write-Output "Start Veeam Backup Job $BackupJobName"
$BackupStartJob = Get-VBRJob | where {$_.Name -eq $BackupJobName}
$RunBackupStartJob = $BackupStartJob | Start-VBRJob
$RunBackupStartJob
$BackupStartJobResult = $RunBackupStartJob.Result
$JobDuration = $RunBackupStartJob.info.progress.Duration
$JobAvgSpeed = $RunBackupStartJob.info.progress.AvgSpeed
$JobVMSize = $RunBackupStartJob.info.progress.TotalSize
$JobVMSizeG = $JobVMSize/1GB
$JobAvgSpeedMB = $JobAvgSpeed/1MB
$JobAvgSpeedT = [System.Math]::Round($JobAvgSpeedMB, 0)
$JobVMSizeT = [System.Math]::Round($JobVMSizeG, 2)

Beinahe fertig...
Der Scheduler muss wieder gerstartet werden und es muss geprüft werden, ob die nächste Replikation auch wirklich startet. Anmerkungen:
-ne bedeutet "nicht"
Get-VBRJOB wiederum drin lassen, damit wir weiter unten den dann aktuellen Wert bei Info.IsScheduleEnabled abrufen können.
Write-Output "Enabling Veeam Backup/Replication Job $JobName again"
$ScheduleStatus = $infodisjob.Info.IsScheduleEnabled
if ($ScheduleStatus -ne "True"){
DO{
$infodisjob = Get-VBRJob | where {$_.name -eq $Jobname}
$disjob.EnableScheduler()
$ScheduleStatus = $infodisjob.Info.IsScheduleEnabled
Write-Output "Wait 30 Seconds"
Start-Sleep -s 30
}
Until ($ScheduleStatus -eq "True")
Write-Output "Is the scheduler enabled again and at least 1 job has started: $schedulestatus"

Ausgabe ins Log der Ergebnisse mit alternativem Endergebnis im Log über IF ELSE gelößt.(Grundidee des Codes stammt von Veeam Matt Carpenter´s PSHelperv1 Kit mit Anpassungen von mir):
Write-Output ""
Write-Output ":::::::::::::::::::::::::::::::::::::::::::::::::::::::" 
Write-Output ":::::::::::::::::::::::::::::::::::::::::::::::::::::::" 
Write-Output "::: Final Job Results Part Summary :::" 
Write-Output ":::::::::::::::::::::::::::::::::::::::::::::::::::::::"
$AEndTime = get-date
$AEndTimeFormated = $AEndTime.ToUniversalTime()
Write-Output "Job started at $AStartTimeFormated"
Write-Output "Job finished at $AEndTimeFormated"
Write-Output "Temporary disabled Job Name is $JobName"
Write-Output "Is now active again: $schedulestatus"
Write-Output "Backup Job Name is $BackupJobName"
IF ($BackupStartJobResult -eq "Success")
{  
Write-Output "Veeam Backup Job $BackupJobName completed successfully" 
}
ELSE
{
Write-Output "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
Write-Output "ERROR ERROR ERROR ERROR ERROR ERROR ERROE"
Write-Output "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
Write-Output "Error: Veeam Backup Job $BackupJobName result: $BackupStartJobResult"
Write-Output "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"    
}
Write-Output "Backup Job duration was $JobDuration"
Write-Output "Backup Job average throughput was $JobAvgSpeedT MB/s"
Write-Output "Virtual Machines in Backup Job $JobName totaled $JobVMSizeT GB in size"
Write-Output ""

Jetzt fehlen nur noch die gangen } von oben.
}
}
}
}


Man könnte den Code an der einen oder anderen Stelle noch verbessern.
Z.B. wäre es eine Möglichkeit für das Log die Zeitstempel vor und nach jedem Teilschritt einzubauen. Weiterhin fehlen Benachrichtigungen an Administratoren die bei bestimmten Ereignissen benachrichtigt werden. Thema E-Mail, Netzwerkmeldungen, Event Log Eintrag, Übergabe an EMS Systeme... dies ist dann zu individuell um es hier zu behandeln.

Viel Spaß beim Umsetzten, Testen !!! und Verbessern.

Es wäre nett wenn Sie Ihren angepassten Code hier als Kommentar veröffentlichen. Code Zeilen können Sie mit http://formatmysourcecode.blogspot.com/ als solchen einbauen.

Grüße Andreas Neufert

Update 09.09.2011:
Backupdatenmenge anhand der Powershell errechnen: http://ict-freak.nl/2011/08/30/veeam-calculate-destination-storage-needs-with-powershell/ "

1 Kommentar:

Dieses Blog durchsuchen