Veeam: Bitlooker & Powershell


In this post I will share some Powershell code to enable or disable the feature BitLooker for your Veeam jobs. Since Bitlooker is a “new” feature you have to enable it on your jobs that are created before you installed Veeam v9 or higher. I my case we are running Veeam Backup for quite some years now, so we had to enable this feature on hundreds of jobs. Once again Powershell to the rescue.

Bur first things first, what is Bitlooker?

With this option enabled, Veeam Backup & Replication performs the following operations during the job session:

  1. Veeam Backup & Replication accesses the MFT file on the VM guest OS to identify deleted file blocks, and zeros out these blocks.
  2. Veeam Backup & Replication processes and transports data blocks of the VM image in the following manner:
  • If a data block of the VM image contains only the deleted file blocks, Veeam Backup & Replication does not read this data block from the source datastore.
  • If a data block of the VM image contains zeroed out blocks and other data, Veeam Backup & Replication copies this block to the target. Due to data compression, data blocks that are marked as deleted are compressed, and the size of the resulting backup or replica file reduces.

source: https://helpcenter.veeam.com/docs/backup/vsphere/dirty_blocks.html?ver=95

You can find the Exclude delete file blocks option in the job configuration wizard under Storage – Advanced – Storage. This option is enabled by default if you configured the job after you installed Veeam v9 but is disabled on jobs created before the installation or upgrade to Veeam v9. See the screenshot below:

image

Well that’s great this new option but I need to configure this setting for hundreds or maybe even more jobs. Is this possible via Powershell? On the Veeam forum you can find a sample script written by v.Eremin. This script will enable this setting right away with no interaction to the user. I wanted to create a script so I was able to see which jobs needs to be configured. So I came up with the following script:

Add-PSSnapin VeeamPSSnapIn

Connect-VBRServer -Server VEEAM-SRV01.DOMAIN.LOCAL

$BitlookerInfo = @()
$AllVbrJobs = Get-VBRJob
$AllVbrJobsCount = ($AllVbrJobs | Measure).Count
$VeeamBackupServer = (Get-VBRLocalhost | Select -ExpandProperty Name).ToUpper()
Write-Output "Checking Veeam Server: $($VeeamBackupServer) ..."
Write-Output ''
$AllVbrJobsDirtyBlocksNullingDisabled = $AllVbrJobs | ?{$_.Options.ViSourceOptions.DirtyBlocksNullingEnabled -eq $False}
$AllVbrJobsDirtyBlocksNullingDisabled | %{
    $BitlookerInfo += New-Object PSCustomObject -Property @{
        BackupServer = $VeeamBackupServer
        Name = $_.Name
        ExcludeDeletedFileBlocks = $_.Options.ViSourceOptions.DirtyBlocksNullingEnabled
    }

    foreach($job in $BitlookerInfo){
        $vbrjob = Get-VBRJob -Name $job.Name
        Write-Output "Job: $($vbrjob.Name)"
        $options = $vbrjob.GetOptions()
        $options.ViSourceOptions.DirtyBlocksNullingEnabled = $true
        $vbrjob.SetOptions($options)
    }

}

$AllBitlookerDisabledJobsCount = ($BitlookerInfo | Measure).Count
Write-Output "Total Veeam jobs: $($AllVbrJobsCount)"
Write-Output "Total Veeam jobs where Bitlooker is enabled: $($AllBitlookerDisabledJobsCount)"
Write-Output ''
$BitlookerInfo | Sort Name | ft -AutoSize

Disconnect-VBRServer

This is the output of the script:

Checking Veeam Server: VEEAM-SRV01.DOMAIN.LOCAL …

Total Veeam jobs: 2
Total Veeam jobs where Bitlooker is enabled: 1

Name              BackupServer                              ExcludeDeletedFileBlocks
—-                   ————                                      ————————
Demo-Job-01 VEEAM-SRV01.DOMAIN.LOCAL    False

You can add a for each loop to loop through the Veeam Backup & Replication servers you configured. This will look like this:

Add-PSSnapin VeeamPSSnapIn $AllVeeamServers = @("VEEAM-SRV01.DOMAIN.LOCAL","VEEAM-SRV02.DOMAIN.LOCAL","VEEAM-SRV03.DOMAIN.LOCAL","VEEAM-SRV04.DOMAIN.LOCAL") foreach($VeeamServer in $AllVeeamServers){ Connect-VBRServer -Server $VeeamServer $BitlookerInfo = @() $AllVbrJobs = Get-VBRJob $AllVbrJobsCount = ($AllVbrJobs | Measure).Count $VeeamBackupServer = (Get-VBRLocalhost | Select -ExpandProperty Name).ToUpper() Write-Output "Checking Veeam Server: $($VeeamBackupServer) ..." Write-Output '' $AllVbrJobsDirtyBlocksNullingDisabled = $AllVbrJobs | ?{$_.Options.ViSourceOptions.DirtyBlocksNullingEnabled -eq $False} $AllVbrJobsDirtyBlocksNullingDisabled | %{ $BitlookerInfo += New-Object PSCustomObject -Property @{ BackupServer = $VeeamBackupServer Name = $_.Name ExcludeDeletedFileBlocks = $_.Options.ViSourceOptions.DirtyBlocksNullingEnabled } foreach($job in $BitlookerInfo){ $vbrjob = Get-VBRJob -Name $job.Name Write-Output "Job: $($vbrjob.Name)" $options = $vbrjob.GetOptions() $options.ViSourceOptions.DirtyBlocksNullingEnabled = $true $vbrjob.SetOptions($options) } } $AllBitlookerDisabledJobsCount = ($BitlookerInfo | Measure).Count Write-Output "Total Veeam jobs: $($AllVbrJobsCount)" Write-Output "Total Veeam jobs where Bitlooker is enabled: $($AllBitlookerDisabledJobsCount)" Write-Output '' $BitlookerInfo | Sort Name | ft -AutoSize Disconnect-VBRServer }

Powershell: Veeam Cloud Connect total virtual machines report


The PowerShell script below helps you to create a simple overview of your Veeam Cloud Connect environment. The environment where this script is developed in consist of two Veeam Cloud Connect Backup servers. The first server will be used for the Cloud Connect Backup solution and the second server will be used for the Cloud Connect Replica server. To connect to these servers we use the Connect-VBRServer cmdlet. I personally love this new cmdlet. It just works like the Connect-VIServer cmdlet. The script will get all the Cloud Tenants and gathers usage information, for Backup tenants only, and will return the total number of virtual machines. At the end of the script all the information will be bundled into a html report. This report will be send to the recipients defined in the $MailReportTo variable.

Add-PSSnapin VeeamPSSnapIn
$AllVccServers = @("vccr-bs01.lab.loc","vccb-bs01.lab.loc")

$MailReportTo = @("user1@domain.com","user2@doman.com")
$MailReportSubject = "Veeam Cloud Connect - Total virtual machines report"
$MailReportFrom = "$(hostname)@domain.com"
$MailReportSmtpServer = "smtp.domain.com"

$VeeamTenantInfo = @()
foreach($VccBackupServer in $AllVccBackupServers){
    Write-Output "Connecting to Veeam Cloud Connect Backup Server $($VccBackupServer)"
    Connect-VBRServer -Server $VccBackupServer

    foreach($VBRCloudTenant in (Get-VBRCloudTenant | Sort Name)){
        
        $RepositoryQuota = $([math]::Truncate($VBRCloudTenant.Resources.RepositoryQuota / 1024))
        $UsedSpace = $([math]::Truncate($VBRCloudTenant.Resources.UsedSpace / 1024))
        $UsedSpacePercentage = $VBRCloudTenant.Resources.UsedSpacePercentage
        $Repository = $VBRCloudTenant.Resources.Repository.name
        $Leaseperiod = $VBRCloudTenant.LeaseExpirationDate


        if($Repository -eq $null -and $VBRCloudTenant.ReplicaCount -ne 0){
            $UsedSpace = 0
            $Repository = 0
            $RepositoryQuota = 0
            $UsedSpacePercentage = 0
            $Repository = "n.a."
        }
        
        if($Leaseperiod -eq $null){
            $Leaseperiod = "n.a."
        }

        $VeeamTenantInfo += New-Object PSObject -Property ([ordered]@{
            User = $VBRCloudTenant.Name
            Enabled = $VBRCloudTenant.Enabled
            VMCount = $VBRCloudTenant.VMCount
            ReplicaCount = $VBRCloudTenant.ReplicaCount
            RepositoryQuota = $RepositoryQuota
            UsedSpace = $UsedSpace
            UsedSpacePercentage = $UsedSpacePercentage
            Repository = $Repository 
            LeaseExpirationEnabled = $VBRCloudTenant.LeaseExpirationEnabled
            LeaseExpirationDate = $Leaseperiod
        })
    }
    Disconnect-VBRserver
}

$html = "<html><body><h1>Veeam Cloud Connect</h1><table border=1 cellspacing=0 cellpadding=3>"
$html += "<html><body><h2>Cloud Connect Server: $((hostname).ToUpper())</h2><table border=1 cellspacing=0 cellpadding=3>"
$html += "<html><body><h3>Usage report generated on $(Get-Date -Format g)</h3><table border=1 cellspacing=0 cellpadding=3>"
$html += "<tr>"
$html += "<th>User</th>"
$html += "<th>Enabled</th>"
$html += "<th>VMCount</th>"
$html += "<th>ReplicaCount</th>"
$html += "<th>RepositoryQuota in GB</th>"
$html += "<th>UsedSpace in GB</th>"
$html += "<th>UsedSpacePercentage</th>"
$html += "<th>Repository</th>"
$html += "<th>LeaseExpirationEnabled</th>"
$html += "<th>LeaseExpirationDate</th>"
$html += "</tr>"
foreach($veeamTenant in $VeeamTenantInfo){
    $html += "<tr>"
    $html += "<td>$($veeamTenant.User)</td>"
    $html += "<td>$($veeamTenant.Enabled)</td>"
    $html += "<td>$($veeamTenant.VMCount)</td>"
    $html += "<td>$($veeamTenant.ReplicaCount)</td>"
    $html += "<td>$($veeamTenant.RepositoryQuota)</td>"
    $html += "<td>$($veeamTenant.UsedSpace)</td>"
    $html += "<td>$($veeamTenant.UsedSpacePercentage)</td>"
    $html += "<td>$($veeamTenant.Repository)</td>"
    $html += "<td>$($veeamTenant.LeaseExpirationEnabled)</td>"
    $html += "<td>$($veeamTenant.LeaseExpirationDate)</td>"
    $html += "</tr>"
}
$html += "<tr>"
$html += "<td colspan=2><b>Totaal</b></td>"
$html += "<td>$(($VeeamTenantInfo.VMCount | Measure -Sum).sum)</td>"
$html += "<td>$(($VeeamTenantInfo.ReplicaCount | Measure -Sum).sum)</td>"
$html += "<td>$(($VeeamTenantInfo.RepositoryQuota | Measure -Sum).sum)</td>"
$html += "<td>$(($VeeamTenantInfo.UsedSpace | Measure -Sum).sum)</td>"
$html += "<td></td>"
$html += "<td></td>"
$html += "<td></td>"
$html += "<td></td>"
$html += "</tr>"
$html += "</table></body></html>"

$ScriptBaseName = ((gci ([string]$MyInvocation.InvocationName)).FullName) -replace "\.ps1$", ''
$html | Out-File "$($ScriptBaseName)_$(Get-date -Format yyyyMM).log.html"

try{
    if ($MailReportTo -eq $null){ throw [Exception]"No To address specified" }
    if ($MailReportSubject -eq $null) { throw [Exception]"No Subject specified" }
    if ($MailReportFrom -eq $null){ throw [Exception]"No From address specified" }
    if ($MailReportSmtpServer -eq $null) { throw [Exception]"No Smtp server specified" }
    Send-MailMessage -BodyAsHtml -Body $html -From $MailReportFrom -SmtpServer $MailReportSmtpServer -To $MailReportTo -Subject $MailReportSubject
    Write-Output "Mail message sent to $MailReportTo"
}
catch
{
    Write-Error "Error sending mail: $($_.Exception.Message)."
}

The report will look like this:

image

If you don’t want to use the html report. Use the code below to generate the report directly in the Powershell console.

Add-PSSnapin VeeamPSSnapIn
$AllVccServers = @("vccr-bs01.lab.loc","vccb-bs01.lab.loc")

$VeeamTenantInfo = @()
foreach($VccBackupServer in $AllVccBackupServers){
    Write-Output "Connecting to Veeam Cloud Connect Backup Server $($VccBackupServer)"
    Connect-VBRServer -Server $VccBackupServer

    foreach($VBRCloudTenant in (Get-VBRCloudTenant | Sort Name)){
        
        $RepositoryQuota = $([math]::Truncate($VBRCloudTenant.Resources.RepositoryQuota / 1024))
        $UsedSpace = $([math]::Truncate($VBRCloudTenant.Resources.UsedSpace / 1024))
        $UsedSpacePercentage = $VBRCloudTenant.Resources.UsedSpacePercentage
        $Repository = $VBRCloudTenant.Resources.Repository.name
        $Leaseperiod = $VBRCloudTenant.LeaseExpirationDate


        if($Repository -eq $null -and $VBRCloudTenant.ReplicaCount -ne 0){
            $UsedSpace = 0
            $Repository = 0
            $RepositoryQuota = 0
            $UsedSpacePercentage = 0
            $Repository = "n.a."
        }
        
        if($Leaseperiod -eq $null){
            $Leaseperiod = "n.a."
        }

        $VeeamTenantInfo += New-Object PSObject -Property ([ordered]@{
            User = $VBRCloudTenant.Name
            Enabled = $VBRCloudTenant.Enabled
            VMCount = $VBRCloudTenant.VMCount
            ReplicaCount = $VBRCloudTenant.ReplicaCount
            RepositoryQuota = $RepositoryQuota
            UsedSpace = $UsedSpace
            UsedSpacePercentage = $UsedSpacePercentage
            Repository = $Repository 
            LeaseExpirationEnabled = $VBRCloudTenant.LeaseExpirationEnabled
            LeaseExpirationDate = $Leaseperiod
        })
    }
    Disconnect-VBRserver
}
$VeeamTenantInfo

Powershell: Change Veeam San Snapshot Options


In the case you want to use the Storage Snapshot feature with Veeam Backup, the feature will be enabled for all the Backup jobs and will be the default option to process a backup job.
Screenshot 2016-01-22 11.53.51

We only want to enable the feature for certain jobs with a special name convention like SAN-BackupJob-01. So I created a small Powershell script to disable this feature for all the jobs without the special name convention.

The Powershell script below will return all the jobs where the job name not match the “SAN” search string. The next step is to disable the “Use storage snapshots” feature for the jobs.

Script: Disable-SanIntegrationOptions.ps1:

if((Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue) -eq $null){
    Add-PSSnapin "VeeamPSSnapIn"
}

foreach($vbrjob in (get-vbrjob | ?{$_.Name -notmatch "SAN"})){
    Write-Output "Changing job: $($vbrjob.name).."
    $SanIntegrataionOptions = $vbrjob.GetOptions()
    $SanIntegrataionOptions.SanIntegrationOptions.UseSanSnapshots = $false

    $vbrjob.SetOptions($SanIntegrataionOptions)
}

From now on only the jobs that need the SAN Snapshot feature, can utilise this feature and all the other jobs will use the default processing mode.

Veeam: End of support Veeam 6.5 in Q4 2014 with the release of v8


A quote from Gostev, in the Veeam Community Forums Digest mailing, send on august 4:

If you, or your customers are still using B&R 6.5, please keep in mind that we will stop supporting this version along with our v8 release, which is planned for early Q4. So please take the opportunity of slow summer time to perform the upgrade to v7. New releases typically increase load on our technical support team, which may in turn increase response times to handle possible upgrade issues (although frankly, we are not getting a lot of those for v7).

So if you’re still using Veeam 6.5 in production. Start working on your RFC to upgrade to Veeam v7.

Veeam v7: How to change the Job notification settings with Powershell


In an earlier post you will find a Powershell script to change the VM Notes setting in Veeam Backup. This old script worked for previous version of Veeam Backup and Replication.

image_thumb[2]

In Veeam Backup v7 the Powershell code is a little bit changed so I had to rewrite the script.  The script below will enable the VM notes for a job, if the option is disabled.

if((Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue) -eq $null){
    Add-PSSnapin "VeeamPSSnapIn"
}

foreach($vbrjob in (get-vbrjob | Sort Name)){
    $options = $vbrjob.GetOptions()
    if($options.ViSourceOptions.SetResultsToVmNotes -eq $false){
        $options.ViSourceOptions.SetResultsToVmNotes = $true
        Write-Host "Enable set results to VM notes for job $($vbrjob.Name)"    
    }
    $vbrjob.SetOptions($options)
}    

Veeam: A file level restore gets stuck in a "stopping" state.


Today a colleague of mine was trying to perform a file level restore on one of the Veeam servers. But unfortunately the job became unresponsive and got stuck in a stopping state. See the print screen below:

image

To fix this issue, you need to run a SQL query on the Veeam database to clear the locks. I have included the solution form KB1534:

Problem:

A file level restore gets stuck in a "stopping" or "starting" state.

Cause:

This issue typically occurs when the VeeamBackup database has become out of sync with Veeam and the true state of the File Level Restore is not updated in the GUI.

Solution:

To fix this you will need to run a SQL query against the VeeamBackup Database, instructions are as shown below. 
Before running this SQL query against the “VeeamBackup” Database, please make sure that there are currently no jobs running. If you are unaware of how to run a query against a DB please read the steps below, if you are aware please disregard.
1.       Open up SQL Server Management Studio and connect to the VEEAM instance.
2.       Expand “Databases”.
3.       Right-click “VeeamBackup”>New query.
4.       Paste the query below into the query window and hit either “execute” or F5.

The query:

UPDATE [ReportRestoreSessionsAndTaskSessionsView]
   SET "state" = -1 
    WHERE "initiator_name" not like 'null'

After running the query and restarting the Veeam console. My colleague was able to perform the file level restore.

Source: http://www.veeam.com/kb1534

Veeam: Host with uuid <uuid> was not found


Today I saw a new error with Veeam Backup and Replication. The error was:

Host with uuid “<uuid>” was not found

Within the Veeam console it looks like this:

image

After a quick search in the Veeam knowledge base I found the Knowledge base article with KB1063.

To fix this issue from the GUI go to Help – License – Licensed Hosts and revoke the license of the host with the new installation.

You can also remove all the licensed hosts via a MS SQL query on the de SQL Database by running the query below:

delete from [dbo].[HostsByJobs]

The reason for this error was a rebuild of the ESXi host.

Source: http://www.veeam.com/kb1063

Release: Veeam Backup & Replication 6.5


Yesterday was the release day of Veeam Backup & Replication 6.5. The first backup solution with full support for vSphere 5.1 and Windows Server 2012 Hyper-V 3.0.

An overview of the new features can be found in the this Youtube video:

I think the following features and enhancements are worth an upgrade. If you’re running a vSphere shop.

Features:

Restore from SAN snapshots
Version 6.5 also introduces Veeam Explorer for SAN Snapshots, which provides granular VMware recovery from HP StoreVirtual VSA and LeftHand snapshots. Codeveloped with HP, Explorer for SAN Snapshots lets you perform Veeam restores (Instant VM Recovery, Instant File-Level Recovery and Explorer for Exchange item
recovery) of VMware VMs directly from array-based snapshots.

You can find a short demo over here:

 

Reminder: Although SAN snapshots can provide excellent RPOs (recovery point objectives) for certain operational disasters, they cannot serve as real backups since they would be lost along with production data in the event of a storage disaster. Thus, you should never rely solely on SAN snapshots for data protection. To ensure protection against all types of disasters, continue to perform regular backup of all VMs to backup storage using Veeam backup jobs or VeeamZIP™.

vSphere 5.1 support:

Veeam Backup & Replication 6.5 provides full support for VMware vSphere 5.1.
And like vSphere 5.1, Veeam Backup & Replication 6.5 supports VMs running
Windows Server 2012 or Windows Server 8.

Enhancements:

Engine:

  • Synthetic full transformation and reversed incremental backup. Improved performance (up to
    several times, depending on backup storage).
  • Storage optimization. New storage optimization setting provides improved performance and
    resource utilization for backup jobs with backup files over 16TB in size.
  • Memory consumption. Average memory consumption by the job manager process has been
    reduced up to 3 times.
  • Network packet loss. Increased the processing engine’s tolerance to network packet loss.
  • Network traffic verification engine. New network traffic verification engine detects and automatically recovers from in-flight data corruption caused by malfunctioning network equipment and similar issues.
  • Improved NAT support. Control whether the source backup proxy server or the backup repository/
    target backup proxy server establishes network connectivity. This is helpful when deploying Veeam
    Backup & Replication in a network with NAT and firewalls.
  • Storage space notification. Added support for low disk space notification for CIFS-based backup
    repositories.
    File-level restore
  • Direct file restore. When restoring a guest file back to its original location from the backup console
    (Backup Browser), perform the restore with a single click. You no longer need to supply destination
    information, and Veeam Backup & Replication does not have to stage the file locally on a backup server
    or on a network share.
  • Dynamic disks. Extended support for file-level restores from dynamic disks to include spanned,
    striped, mirrored and RAID-5 volumes.
  • Backup Browser UI. Updated the Backup Browser’s user interface (UI) to match the new product UI
    introduced in version 6.1. Removed the hidden system partition from the volume tree. Now retrieves
    actual drive letters from restored guest OS settings (rather than simply assigning in sequential order).

Enhancements specific to VMware:

  • Improved processing performance. Significantly reduced data transfer initialization time in all
    transport modes by disabling excessive VDDK logging.
  • Direct file restore. Perform a direct file restore (described earlier) without a network connection
    between the backup server and the destination VM.

You can read about the rest of the enhancements in the What’s new PDF here.

Personally I hope that I can find some time to test the Restore from SAN snapshots feature soon. We are running a huge Lefthand shop so this feature might become handy in the near future.

Veeam: Move Backup job to a brand new Veeam Backup server


In this post I will show you how to move a Veeam Backup job to a new Veeam Backup server. You can also use this procedure to move the Backup files to a new drive and map the backup files to an existing backup job.

The short version of this procedure is:

  1. Move the backup files to the new Veeam Backup server.
  2. Create a new Backup repository and Import the existing Backup jobs.
  3. Create a new Backup job with exact the same the Virtual Machines. Select the new Backup Repository and map the backup files.
  4. Schedule or Start the backup job from the new Veeam Backup server.
  5. You’ll find the steps to take in detail for step 2 and step 3 below.

Continue reading

Veeam: Unable to install Windows 2008 R2 SP1 error 800F0A12


One of my test Veeam Backup servers was running Windows 2008 R2 without Service Pack 1. So I decided to install Service Pack 1 but all I got was the following error message:

image

To fix this error follow the next steps:

  1. Be sure there are now active Veeam Backup jobs. But I think that’s not the case during a maintenance windows.
  2. Open a command prompt and start DISKPART.
  3. Enable the automount feature via: automount enable:
    image
  4. Restart the Veeam Backup server.
  5. Install Windows 2008 R2 Service Pack 1.
  6. Restart the Veeam Backup server.
  7. Open a command prompt and start DISKPART.
  8. Disable the automount feature via: automount disable
  9. Restart the Veeam Backup server.

Source: http://blogs.technet.com