Veeam Powershell Toolkit: Changing the Processing Mode

Before I start with the actual post I want to start with a little tip. Before you can run Veeam Powershell Toolkit scripts, you need to add the VeeamPSSnapin. You can do this via the following code:

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

So now you’re able to load the snapin, you can run your Veeam Powershell Toolkit scripts. In this post I want to show how to change the Processing Mode. You probably know the three modes:


You can find the Processing Mode options via the following Powershell script:

$vbrjobname = "Production"
$vbrjob = Get-VBRJob | Where {$_.Name -eq $vbrjobname}

So now you know which modes there are, but how do you change this option with Powershell? Well you can do this with the next script:

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

$vbrjobname = "Production"
$vbrjob = Get-VBRJob | Where {$_.Name -eq $vbrjobname}
$DirectSAN = "san;nbd"
$VirtualAppliance = "hotadd;nbd"
$Network = "nbd"

$mode = $VirtualAppliance

if($ -ne $mode){
    $vddk = $vbrjob.GetOptions()
    $vddk.VDDKMode = $mode
    Write-Host "VDDK mode changed to $mode" -ForegroundColor Green
    Write-Host "Nothing to change" -ForegroundColor Yellow

Just save the script and change the $mode parameter to the option you want to use. The script will give you the following output:


Reconfigure DNS settings and add vSphere hosts to Windows DNS

I needed to change the DNS setup in our vSphere environment. Instead of doing this by hand on every host I decided to create a script. First I needed a script to add the A and PTR records to the Windows DNS servers. I remembered a post by the scripting guys so I took their function and added it to my script. The final step is to change de vSphere host DNS configuration. This one is easy with PowerCLI and a simle for loop.

Warning! If you are using vSphere 4.1 and the vSphere hosts are joined to a Windows domain. You are not able to change the DNS settings!

From the Hey Scripting Guy post I quote the following about the new-dnsrecord function:

I’ve written various scripts in the past to work with individual record types, and I’ve found that each class has slightly different syntax and requirements. This makes life awkward when you want to start automating this process, because you have to have a different script or function for each record type. I decided I wanted a universal script for creating records so that I could create multiple records at the same time from minimal information. The following script shows the function that I came up with to create A, PTR, MX, and CNAME records—these being the most common ones I have to deal with. We will be using the MicrosoftDNS_ResourceRecord class with varying inputs.

I have combined the new-dnsrecord function with some PowerCLI code to accomplish my goal of migrating the DNS settings of all the vSphere hosts and to add all the hosts to the DNS servers. I did this task by running the following script:

Continue reading “Reconfigure DNS settings and add vSphere hosts to Windows DNS”

Working with the Veeam Powershell toolkit

After the short introduction of the Veeam Powershell toolkit in my earlier post, It was about time to play with the Toolkit. In this post I will show you how to create a Backup Job and how to add VM’s to the backup job.

Lets start to add a new Veeam and Replication backup job called “Production” and add the following VM’s: DC01, VC01 and MC01:

$vbrserver = Get-VBRServer | Where {$_.Type -eq "Local"}
$vbrjobname = "Production"
$vbrfolder = "C:\veeam\production\"
$vbrfile = "production.vbk"
$vbrobjects = "DC01","VC01","MC01"

Add-VBRBackupJob -Name $vbrjobname -Type VDDK -Server $vbrserver `
-Folder $vbrfolder -FileName $vbrfile -Objects $vbrobjects

The backup job is created and the following output will be generated on the console:


You can verify the Job settings and the selected VM’s inside the GUI:


If you want to add an extra VM to the backup job. You can run the following code to add a VM called NAGIOS:

$vbrjobname = "Production"
$vbrjob = Get-VBRJob | Where {$_.Name -eq $vbrjobname}
$vbrserver = Get-VBRServer | Where {$_.Type -eq "VC"}
$vbrobjects = "NAGIOS"

Add-VBRJobObject -Job $vbrjob -Server $vbrserver -Object $vbrobjects

Annotation: the $vbrserver parameter is different than the first script in this post. When you want to add an Object to an existing job, you need to use the vCenter server as the backup source instead of the Veeam Backup server because you need to add an object from vCenter server to the backup job. See help for more info:

get-help Add-VBRJobObject -Detailed

The output from the command:




    Add VMs or VM containers to the existing job.


    Add-VBRJobObject [-Job] <CBackupJob> [-Server] <CHost> [-Objects] <String[]

    > [-WarningAction <ActionPreference>] [-WarningVariable <String>] [<CommonP


    Add-VBRJobObject [-Job] <CBackupJob> [-Server] <CHost> [-Entities] <CEntity

    []> [-WarningAction <ActionPreference>] [-WarningVariable <String>] [<Commo



    Add VMs or VM containers to the existing backup, replication or copy job.


    -Job <CBackupJob>

        Provide an object of the existing backup, replication or copy job.

    -Server <CHost>

        Provide an object of the ESX/ESXi server on which VMs or VM containers


    -Objects <String[]>

        Provide objects of VMs or containers of VMs that you want to back up, r

        eplicate or copy.

When the command completed successfully you will see the following output:


To be continued…

Veeam Backup PowerShell Toolkit

We start with some information from the user guide veeam_backup_5_0_user_guide_pg.pdf :

Veeam Backup & Replication 5.0 comes with PowerShell extension — a snap-in to Microsoft Windows PowerShell 2.0. Windows PowerShell is a powerful command-line tool that allows administrators to automate some Veeam Backup & Replication activities. Veeam extends functionality of Windows PowerShell 2.0, and now administrators may use PowerShell to automate Veeam backup, replication and copy job creation and editing, VMs restores, replica failover and other operations.

Before installing Veeam PowerShell snap-in, make sure that Microsoft Windows PowerShell 2.0 is installed on the Veeam Backup & Replication console. To download Microsoft Windows PowerShell, use the following link:

PowerShell uses cmdlets — simple single-function commands that can be run in the command-line shell. Cmdlets are specialized .NET classes that implement specific actions. Veeam PowerShell provides a set of its own cmdlets which correspond to actions you can perform via Veeam Backup & Replication UI. Please keep in mind that actions performed with PowerShell have the same force as actions performed via Veeam Backup & Replication 5.0 — for example, if you delete some job with PowerShell scripts, the job will be removed from the VeeamBackup database, and you will not be able undo changes.

To start the Veeam Backup PowerShell Toolkit, open Veeam Backup and Replication to Tools –> PowerShell:image

The Veeam Backup PowerShell Toolkit starts:


There are 75 cmdlets. You can verify this via:



If you need more information about a cmdlet you can use the get-help cmdlet:

Get-Help Add-VBRBackupJob
Get-Help Add-VBRBackupJob -Full


More information about the Veeam Backup PowerShell Toolkit can be found on page 164 of the veeam_backup_5_0_user_guide_pg.pdf user guide,

You can expect some more posts about the Veeam Backup PowerShell Toolkit in the coming weeks.

Powershell: Using SCHTASKS in Powershell


In this post you will see how powerful powershell is in combination with external applications like SCHTASKS.exe.

First you have to create a CSV file like this:


The following one-liner imports the CSV file and creates a task on every server which is saved in the CSV file:

# Create a scheduled task on all the servers in *.csv
import-csv ".\*.csv" | % { schtasks /create 
/S $_.Name /SC DAILY /TN "Task_Name" 
/TR "program_or_script" /ST time /RU account}

The next one-liner imports the CSV file and will modify a scheduled task on every server which is saved in the CSV file:

# Change a scheduled task on all the servers in *.csv
import-csv ".\*.csv" | % { schtasks /change 
/TN "Task_Name" /S $_.Name 
/TR "program_or_script" /ST 23:05 /RU System }

The last one-liner imports the CSV file and will delete a scheduled task on every server which is saved in the CSV file:

# Delete a scheduled task on all the servers in *.csv
import-csv ".\*.csv" | % { schtasks /delete 
/tn "Task_Name" /f /s $_.Name }

More info about how to use SCHTASKS.exe can be found here: KB814596

PowerCLI: Set Custom Fields


Last week I posted a script to add Notes to a VM. After posting this script there was a little discussion on Twitter with @vmdoug, @gabvirtualworld if the Notes field is the right field to add this kind of information. So @vmdoug introduced me to the world of Custom Fields.

So I changed my CSV file and added the Field entry. This Field entry will be de name of your custom field. In my case I called it Description.

DC01,Description,Domain Controller
VC01,Description,vCenter Server

The following one-liner will fix this for you:

"D:\*.csv" | % { Get-VM $_.VMName |
Set-CustomField -Name $_.Field -Value $_.Note -Confirm:$false }

After running the script you will see the Description field with a new entry:


This one-liner will run very slow on a Large environment. So if you have large environment you should definitely check out LucD post on Alan Renouf’s Blog:

PowerCLI: Add Notes To Multiple VM’s


My colleague asked me to add some notes to the VM’s so he knows what this VM is doing. So this is a nice job for PowerCLI 🙂 . In this post you will see how powerful PowerCLI /Powershell is.  With only one line of code (one-liner),  you are able to achieve this job.

First you have to create a CSV file with the following entry’s:

VM1,Domain Controller
VM2,Database Server

The second step is to run this one-liner. The one-liner will add the Notes:

Import-Csv "D:\*.csv" | % { Set-VM $_.VMName -Description $_.Note -Confirm:$false}

When the one-liner is ready, you will find the Notes in the vSphere Client:


Note: This script will overwrite the existing Notes, so use it at your own risk!

Powershell: Working with Excel and error HRESULT: 0x80028018


If you want to use Microsoft Excel in your Powershell scripts.

$Excel = New-Object -Com Excel.Application
$Excel.visible = $True
$Excel = $Excel.Workbooks.Add()


You can run into the following error:


The work around for this issue was changing the Regional Options back to United States International.


Microsft created a work around. More info can be found in in: KB320369

guillermooo has created a port to Powershell. Just copy the following code and you should be able to open Excel and create a new workbook.

I didn’t test this script block so let me know if it works 😉

$ci = new-object system.globalization.cultureinfo "en-US"

$e = New-Object -COM "Excel.Application"
$e.Visible = $True
$e.UserControl= $True
$books = $e.Workbooks
$books.PSBase.GetType().InvokeMember( `
       "Add", `
       [system.reflection.bindingflags]::InvokeMethod, `
       $null, $books, $null, $ci)


PowerCLI: Generate an Excel sheet with VM info


The following script is part of another script but I wanted to show you some nice Powershell stuff in combination with Microsoft Excel.

This script will generate an Excel sheet with some VM information. It will color the cell red if the Powerstate equals to NotRunning.

$vCenter = Read-Host "Enter your vCenter servername"

Connect-VIServer $vCenter

$xlCSV = 6
$xlXLS = 56
$csvfile = "C:\beforeHWchange.csv"
$xlsfile = "C:\beforeHWchange.xls"

$Excel = New-Object -ComObject Excel.Application
$Excel.visible = $True
$Excel = $Excel.Workbooks.Add()

$Sheet = $Excel.Worksheets.Item(1)
$Sheet.Cells.Item(1,1) = "Status"
$Sheet.Cells.Item(1,2) = "VMName"
$Sheet.Cells.Item(1,3) = "VMHostname"
$Sheet.Cells.Item(1,4) = "IPAddress"
$Sheet.Cells.Item(1,5) = "MacAddress"
$Sheet.Cells.Item(1,6) = "TotalNics"
$Sheet.Cells.Item(1,7) = "vNicType"
$Sheet.Cells.Item(1,8) = "NetworkName"
$Sheet.Cells.Item(1,9) = "vNicConnected"
$Sheet.Cells.Item(1,10) = "ToolsVersion"
$Sheet.Cells.Item(1,11) = "ToolsStatus"
$Sheet.Cells.Item(1,12) = "ToolsRunningStatus"
$Sheet.Cells.Item(1,13) = "OS"
$Sheet.Cells.Item(1,14) = "ESXHost"

$intRow = 2

$WorkBook = $Sheet.UsedRange
$WorkBook.Interior.ColorIndex = 19
$WorkBook.Font.ColorIndex = 11
$WorkBook.Font.Bold = $True

#$vms = Get-Folder Lab | Get-VM
$vms = Get-VM

foreach($vm in $vms){

  $vmnic = Get-NetworkAdapter -VM $vm
  $vmview = get-VM $vm | Get-View

if($vm.Guest.State -eq "NotRunning"){
  $Sheet.Cells.Item($intRow, 1) = [String]$vm.Guest.State
  $Sheet.Cells.Item($intRow, 1).Interior.ColorIndex = 3
elseif($vm.Guest.State -eq "Unknown"){
  $Sheet.Cells.Item($intRow, 1) = [String]$vm.Guest.State
  $Sheet.Cells.Item($intRow, 1).Interior.ColorIndex = 48
  $Sheet.Cells.Item($intRow, 1) = [String]$vm.Guest.State
  $Sheet.Cells.Item($intRow, 1).Interior.ColorIndex = 4

$Sheet.Cells.Item($intRow, 2) = $vmview.Name 
$Sheet.Cells.Item($intRow, 3) = $vmview.Guest.HostName
$Sheet.Cells.Item($intRow, 4) = [String]$vm.Guest.IPAddress
$Sheet.Cells.Item($intRow, 5) = $vmnic.MacAddress
$Sheet.Cells.Item($intRow, 6) = $vmview.Guest.Net.Count
$Sheet.Cells.Item($intRow, 7) = [String]$vmnic.Type
$Sheet.Cells.Item($intRow, 8) = $vmnic.NetworkName 
$Sheet.Cells.Item($intRow, 9) = $vmnic.ConnectionState.Connected

if($vmview.Config.Tools.ToolsVersion -eq "8193"){
  $Sheet.Cells.Item($intRow, 10) = [String]$vmview.Config.Tools.ToolsVersion
  $Sheet.Cells.Item($intRow, 10).Interior.ColorIndex = 4
  $Sheet.Cells.Item($intRow, 10) = [String]$vmview.Config.Tools.ToolsVersion
  $Sheet.Cells.Item($intRow, 10).Interior.ColorIndex = 3

if($vmview.Guest.ToolsStatus -eq "toolsNotInstalled"){
  $Sheet.Cells.Item($intRow, 11) = [String]$vmview.Guest.ToolsStatus
  $Sheet.Cells.Item($intRow, 11).Interior.ColorIndex = 48

elseif($vmview.Guest.ToolsStatus -eq "toolsNotRunning"){
  $Sheet.Cells.Item($intRow, 11) = [String]$vmview.Guest.ToolsStatus
  $Sheet.Cells.Item($intRow, 11).Interior.ColorIndex = 3    
elseif($vmview.Guest.ToolsStatus -eq "toolsOld"){
  $Sheet.Cells.Item($intRow, 10) = [String]$vmview.Config.Tools.ToolsVersion
  $Sheet.Cells.Item($intRow, 10).Interior.ColorIndex = 45
  $Sheet.Cells.Item($intRow, 11) = [String]$vmview.Guest.ToolsStatus
  $Sheet.Cells.Item($intRow, 11).Interior.ColorIndex = 45    
  $Sheet.Cells.Item($intRow, 11) = [String]$vmview.Guest.ToolsStatus
  $Sheet.Cells.Item($intRow, 11).Interior.ColorIndex = 4

if($vmview.Guest.ToolsRunningStatus -eq "guestToolsRunning"){
  $Sheet.Cells.Item($intRow, 12) = $vmview.Guest.ToolsRunningStatus
  $Sheet.Cells.Item($intRow, 12).Interior.ColorIndex = 4
  $Sheet.Cells.Item($intRow, 12) = $vmview.Guest.ToolsRunningStatus
  $Sheet.Cells.Item($intRow, 12).Interior.ColorIndex = 3

$Sheet.Cells.Item($intRow, 13) = $vmview.Guest.GuestFamily
$Sheet.Cells.Item($intRow, 14) = $vm.Host.Name

$intRow = $intRow + 1}


sleep 5


Disconnect-VIServer -Confirm:$false


The output will look like this: