Um mein Lab bei Bedarf wieder schnell aufzubauen habe ich mir vorgenommen alle Installationen, soweit möglich, zu automatisieren. Da nun auch wieder ein Veeam Backup & Replication 9.5 Server mit Veeam Enterprise Manager zu meinem Lab gehören soll, war mein erstes PowerShell Projekt der Veeam Availability Suite Unattended Install.
Natürlich habe ich mich als erstes umgesehen, ob sich nicht bereits jemand Anderes die Arbeit gemacht hat. Und tatsächlich, das Projekt von Timothy Dewin ist sogar in dem Veeam PowerShell GitHub Repository zur Verfügung gestellt (95_simple_auto_install_all.ps1). Dieses Skript sieht schon mehr als ordentlich aus, ich konnte es aber natürlich dennoch nicht lassen es noch etwas zu überarbeiten.
Zusätzlich zur reinen Installation der Veeam Availability Suite 9.5 hab ich mir auch angesehen wie man einige der grundlegenden Konfigurationen automatisieren könnte, z.B. VMware vCenter oder NetApp ONTAP Filer in Veeam Backup & Replication 9.5 aufnehmen. Daher ist der Artikel auch in zwei Teilabschnitte gegliedert.
Abschnitte:
Veeam Availability Suite Unattended Install im Detail
Wie bereits erwähnt habe ich mir als Basis das Skript von Timothy Dewin genommen und dieses etwas verfeinert. Wichtig war für mich unter anderem die Kontrolle der MSI Logs auf eine erfolgreiche Installation. Dazu suche ich ganz simple in dem Log nach dem String für eine fehlerfreie Installation „Installation success or error status: 0„.
Beispiel:
if (Select-String -path "$logdir\02_Shared.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" }
Die Anlage des lokalen Users für die Veeam Prozesse und die SQL Verbindung habe ich anders als beim dem originalen Skript mit dem in PowerShell 5.1 neu eingeführten Cmdlet New-LocalUser erledigt. Nachteil ist natürlich, dass man diese PowerShell Version installiert haben muss.
Alle notwendigen MSI Parameter für die einzelnen Veeam Komponenten können dem Veeam Unattended Installation Guide entnommen werden.
Unattended Install Skript
Um das Veeam Availability Suite Unattended Install Skript erfolgreich auszuführen, müssen ein paar Voranforderungen erfüllt werden:
- PowerShell 5.1 ist installiert und neu gestartet
- .Net 4.5.2 ist installiert und neu gestartet
- Veeam Availability Suite 9.5 Update 2 ISO ist eingelegt
- Administrator Rechte sind vorhanden
Für die beiden zusätzlichen Software Pakete habe ich die Installationsroutinen auch in das Skript eingefügt aber auskommentiert. Um PowerShell 5.1 zu installieren muss das Windows Management Framework 5.1 heruntergeladen werden, .Net 4.5.2 ist auf dem Veeam Availability Suite 9.5 Update 2 ISO zu finden.
# Requires PowerShell 5.1 # Requires .Net 4.5.2 and Reboot #region: Variables $source = "F:" $licensefile = "C:\_install\veeam_availability_suite_trial_32_0.lic" $username = "svc_veeam" $fulluser = $env:COMPUTERNAME+ "\" + $username $password = "Passw0rd!" $CatalogPath = "D:\VbrCatalog" $vPowerPath = "D:\vPowerNfs" #endregion #region: logdir $logdir = "C:\logdir" $trash = New-Item -ItemType Directory -path $logdir -ErrorAction SilentlyContinue #endregion ### Optional .Net 4.5.2 <# Write-Host " Installing .Net 4.5.2 ..." -ForegroundColor Yellow $Arguments = "/quiet /norestart" Start-Process "$source\Redistr\NDP452-KB2901907-x86-x64-AllOS-ENU.exe" -ArgumentList $Arguments -Wait -NoNewWindow Restart-Computer -Confirm:$true #> ### Optional PowerShell 5.1 <# Write-Host " Installing PowerShell 5.1 ..." -ForegroundColor Yellow $Arguments = "C:\_install\Win8.1AndW2K12R2-KB3191564-x64.msu /quiet /norestart" Start-Process "wusa.exe" -ArgumentList $Arguments -Wait -NoNewWindow Restart-Computer -Confirm:$true #> #region: create local admin Write-Host "Creating local user '$fulluser' with password '$password' ..." -ForegroundColor Yellow $trash = New-LocalUser -Name $username -Password ($password | ConvertTo-SecureString -AsPlainText -Force) -Description "Service Account for Veeam" -AccountNeverExpires -ErrorAction Stop Add-LocalGroupMember -Group "Administrators" -Member $username -ErrorAction Stop #endregion #region: Installation # Info: https://www.veeam.com/unattended_installation_ds.pdf ## Global Prerequirements Write-Host "Installing Global Prerequirements ..." -ForegroundColor Yellow ### 2012 System CLR Types Write-Host " Installing 2012 System CLR Types ..." -ForegroundColor Yellow $MSIArguments = @( "/i" "$source\Redistr\x64\SQLSysClrTypes.msi" "/qn" "/norestart" "/L*v" "$logdir\01_CLR.txt" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\01_CLR.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } ### 2012 Shared management objects Write-Host " Installing 2012 Shared management objects ..." -ForegroundColor Yellow $MSIArguments = @( "/i" "$source\Redistr\x64\SharedManagementObjects.msi" "/qn" "/norestart" "/L*v" "$logdir\02_Shared.txt" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\02_Shared.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } ### SQL Express ### Info: https://msdn.microsoft.com/en-us/library/ms144259.aspx Write-Host " Installing SQL Express ..." -ForegroundColor Yellow $Arguments = "/HIDECONSOLE /Q /IACCEPTSQLSERVERLICENSETERMS /ACTION=install /FEATURES=SQLEngine,SNAC_SDK /INSTANCENAME=VEEAMSQL2012 /SQLSVCACCOUNT=`"NT AUTHORITY\SYSTEM`" /SQLSYSADMINACCOUNTS=`"$fulluser`" `"Builtin\Administrators`" /TCPENABLED=1 /NPENABLED=1 /UpdateEnabled=0" Start-Process "$source\Redistr\x64\SQLEXPR_x64_ENU.exe" -ArgumentList $Arguments -Wait -NoNewWindow ## Veeam Backup & Replication Write-Host "Installing Veeam Backup & Replication ..." -ForegroundColor Yellow ### Backup Catalog Write-Host " Installing Backup Catalog ..." -ForegroundColor Yellow $trash = New-Item -ItemType Directory -path $CatalogPath -ErrorAction SilentlyContinue $MSIArguments = @( "/i" "$source\Catalog\VeeamBackupCatalog64.msi" "/qn" "/L*v" "$logdir\04_Catalog.txt" "VM_CATALOGPATH=$CatalogPath" "VBRC_SERVICE_USER=$fulluser" "VBRC_SERVICE_PASSWORD=$password" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\04_Catalog.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } ### Backup Server Write-Host " Installing Backup Server ..." -ForegroundColor Yellow $trash = New-Item -ItemType Directory -path $vPowerPath -ErrorAction SilentlyContinue $MSIArguments = @( "/i" "$source\Backup\Server.x64.msi" "/qn" "/L*v" "$logdir\05_Backup.txt" "ACCEPTEULA=YES" "VBR_LICENSE_FILE=$licensefile" "VBR_SERVICE_USER=$fulluser" "VBR_SERVICE_PASSWORD=$password" "PF_AD_NFSDATASTORE=$vPowerPath" "VBR_SQLSERVER_SERVER=$env:COMPUTERNAME\VEEAMSQL2012" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\05_Backup.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } ### Backup Console Write-Host " Installing Backup Console ..." -ForegroundColor Yellow $MSIArguments = @( "/i" "$source\Backup\Shell.x64.msi" "/qn" "/L*v" "$logdir\06_Console.txt" "ACCEPTEULA=YES" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\06_Console.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } ### Explorers Write-Host " Installing Explorer For ActiveDirectory ..." -ForegroundColor Yellow $MSIArguments = @( "/i" "$source\Explorers\VeeamExplorerForActiveDirectory.msi" "/qn" "/L*v" "$logdir\07_ExplorerForActiveDirectory.txt" "ACCEPTEULA=YES" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\07_ExplorerForActiveDirectory.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } Write-Host " Installing Explorer For Exchange ..." -ForegroundColor Yellow $MSIArguments = @( "/i" "$source\Explorers\VeeamExplorerForExchange.msi" "/qn" "/L*v" "$logdir\08_VeeamExplorerForExchange.txt" "ACCEPTEULA=YES" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\08_VeeamExplorerForExchange.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } Write-Host " Installing Explorer For SQL ..." -ForegroundColor Yellow $MSIArguments = @( "/i" "$source\Explorers\VeeamExplorerForSQL.msi" "/qn" "/L*v" "$logdir\09_VeeamExplorerForSQL.txt" "ACCEPTEULA=YES" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\09_VeeamExplorerForSQL.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } Write-Host " Installing Explorer For Oracle ..." -ForegroundColor Yellow $MSIArguments = @( "/i" "$source\Explorers\VeeamExplorerForOracle.msi" "/qn" "/L*v" "$logdir\10_VeeamExplorerForOracle.txt" "ACCEPTEULA=YES" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\10_VeeamExplorerForOracle.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } Write-Host " Installing Explorer For SharePoint ..." -ForegroundColor Yellow $MSIArguments = @( "/i" "$source\Explorers\VeeamExplorerForSharePoint.msi" "/qn" "/L*v" "$logdir\11_VeeamExplorerForSharePoint.txt" "ACCEPTEULA=YES" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\11_VeeamExplorerForSharePoint.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } ## Enterprise Manager Write-Host "Installing Enterprise Manager ..." -ForegroundColor Yellow ### Enterprise Manager Prereqirements Write-Host " Installing Enterprise Manager Prereqirements ..." -ForegroundColor Yellow $trash = Install-WindowsFeature Web-Default-Doc,Web-Dir-Browsing,Web-Http-Errors,Web-Static-Content,Web-Windows-Auth -Restart:$false -WarningAction SilentlyContinue $trash = Install-WindowsFeature Web-Http-Logging,Web-Stat-Compression,Web-Filtering,Web-Net-Ext45,Web-Asp-Net45,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Mgmt-Console -Restart:$false -WarningAction SilentlyContinue $MSIArguments = @( "/i" "$source\Redistr\x64\rewrite_amd64.msi" "/qn" "/norestart" "/L*v" "$logdir\12_Rewrite.txt" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\12_Rewrite.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } ### Enterprise Manager Web Write-Host " Installing Enterprise Manager Web ..." -ForegroundColor Yellow $MSIArguments = @( "/i" "$source\EnterpriseManager\BackupWeb_x64.msi" "/qn" "/L*v" "$logdir\13_EntWeb.txt" "ACCEPTEULA=YES" "VBREM_LICENSE_FILE=$licensefile" "VBREM_SERVICE_USER=$fulluser" "VBREM_SERVICE_PASSWORD=$password" "VBREM_SQLSERVER_SERVER=$env:COMPUTERNAME\VEEAMSQL2012" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow if (Select-String -path "$logdir\13_EntWeb.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } ### Enterprise Manager Cloud Portal Write-Host " Installing Enterprise Manager Cloud Portal ..." -ForegroundColor Yellow <# $MSIArguments = @( "/i" "$source\Cloud Portal\BackupCloudPortal_x64.msi" "/L*v" "$logdir\14_EntCloudPortal.txt" "/qn" "ACCEPTEULA=YES" ) Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow #> Start-Process "msiexec.exe" -ArgumentList "/i `"$source\Cloud Portal\BackupCloudPortal_x64.msi`" /l*v $logdir\14_EntCloudPortal.txt /qn ACCEPTEULA=`"YES`"" -Wait -NoNewWindow if (Select-String -path "$logdir\14_EntCloudPortal.txt" -pattern "Installation success or error status: 0.") { Write-Host " Setup OK" -ForegroundColor Green } else { throw "Setup Failed" } ### Update 2 Write-Host "Installing Update 2 ..." -ForegroundColor Yellow $Arguments = "/silent /noreboot /log $logdir\15_update.txt VBR_AUTO_UPGRADE=1" Start-Process "$source\Updates\veeam_backup_9.5.0.1038.update2_setup.exe" -ArgumentList $Arguments -Wait -NoNewWindow #endregion
Das Skript ist auch GitHub Gist zur Verfügung gestellt.
Weitere Konfigurationen
Neben dem reinen Veeam Availability Suite Unattended Install sind zusätzlich grundlegende Konfigurationen an der frischen Installation denkbar.
Zusätzliche Konfigurationen:
- vCenter hinzufügen
- NetApp Filer hinzufügen
- Backup Server in Enterprise Manager aufnehmen
vCenter zu Veeam Backup Server hinzufügen
Für diese Konfiguration muss das mit der Konsole zusammen installierte Veeam PowerShell PSSnapIn genutzt werden, und zwar konkret das Add-VBRvCenter Cmdlet. Wie der Veeam PowerShell Reference zu entnehmen ist, kann hierfür ein User mit Passwort mitgegeben werden oder auf bestehende Credentials zugegriffen werden. Ich mache in meinem Beispiel ersteres.
if (Get-PSSnapin -Registered -Name VeeamPSSnapIn -ErrorAction SilentlyContinue) { Add-PSSnapin -Name VeeamPSSnapIn } Disconnect-VBRServer -ErrorAction SilentlyContinue Connect-VBRServer -Server Veeam-01.lab.local if (Get-VBRServer) { Add-VBRvCenter -Name "192.168.3.101" -Description "Lab vCenter" -User "Admini[email protected]" -Password "Passw0rd!" -Verbose }
NetApp Filer zu Veeam Backup Server hinzufügen
Für das Add-NetAppHost Cmdlet gilt das gleiche wie im vorherigen Schritt mit dem vCenter, Details sind der Veeam PowerShell Reference zu entnehmen.
if (Get-PSSnapin -Registered -Name VeeamPSSnapIn -ErrorAction SilentlyContinue) { Add-PSSnapin -Name VeeamPSSnapIn } Disconnect-VBRServer -ErrorAction SilentlyContinue Connect-VBRServer -Server Veeam-01.lab.local if (Get-VBRServer) { Add-NetAppHost -Name "192.168.3.103" -Description "Lab NetApp" -UserName "admin" -Password "Anfang!!11" }
Veeam Backup Server zu Enterprise Manager hinzufügen
Für diese Konfiguration muss auf die Veeam Backup Enterprise Manager RESTful API zugegriffen werden, daher ist das Skript leider auch entsprechend komplexer.
Es sing vier REST Calls notwendig:
- Authentifizieren
- Server hinzufügen
- Server ID abrufen (optional)
- Server Collection (optional)
Die Collection ist optional, da der „default schedule“ für die Collection ohnehin alle 15 Minuten läuft.
[String] $Server = "192.168.3.100" [Boolean] $HTTPS = $True [String] $Port = "9398" [String] $Authentication = "<dummy>" #region: Workaround for SelfSigned Cert add-type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy #endregion #region: Switch Http/s if ($HTTPS -eq $True) {$Proto = "https"} else {$Proto = "http"} #endregion #region: POST - Authorization [String] $URL = $Proto + "://" + $Server + ":" + $Port + "/api/sessionMngr/?v=v1_2" Write-Verbose "Authorization Url: $URL" $Auth = @{uri = $URL; Method = 'POST'; Headers = @{Authorization = 'Basic ' + $Authentication; } } try {$AuthXML = Invoke-WebRequest @Auth -ErrorAction Stop} catch {Write-Error "`nERROR: Authorization Failed!";Exit 1} #endregion #region: POST - Add BR Server [String] $URL = $Proto + "://" + $Server + ":" + $Port + "/api/backupServers?action=create" Write-Verbose "Add BR Server Url: $URL" $BRServer = @{uri = $URL; Method = 'POST'; Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']; 'Content-Type' = 'application/xml'} Body = ' <BackupServerSpec xmlns="http://www.veeam.com/ent/v1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Description>Veeam Lab Server</Description> <DnsNameOrIpAddress>192.168.3.100</DnsNameOrIpAddress> <Port>9392</Port> <Username>Veeam-01\svc_veeam</Username> <Password>Passw0rd!</Password> </BackupServerSpec> ' } try {$BRServerXML = Invoke-RestMethod @BRServer -ErrorAction Stop} catch {Write-Error "`nERROR: Add BR Server Failed!";Exit 1} #endregion #region: GET - Get BR Server [String] $URL = $Proto + "://" + $Server + ":" + $Port + "/api/backupServers" Write-Verbose "Get BR Server Url: $URL" $BRServer = @{uri = $URL; Method = 'GET'; Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']} } try {$BRServerXML = Invoke-RestMethod @BRServer -ErrorAction Stop} catch {Write-Error "`nERROR: Get BR Server Failed!";Exit 1} #endregion #region: POST - Collect BR Server [String] $URL = $BRServerXML.EntityReferences.Ref.Href + "?action=collect" Write-Verbose "Collect BR Server Url: $URL" $BRServer = @{uri = $URL; Method = 'POST'; Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']} } try {$BRServerXML = Invoke-RestMethod @BRServer -ErrorAction Stop} catch {Write-Error "`nERROR: Collect BR Server Failed!";Exit 1} #endregion
No Responses