Powershell: Veeam B&R – Get total days before the license expires


So it’s time for a new post with some “traditional” Powershell so no snappins from VMware or Veeam. But first some background info. I am working for a Veeam ProPartner  with a Service Provider partner program. in this program Veeam only supplies “temporary licenses” so you have to deal with an expiration date of the license. This also applies to the Veeam NFR licenses for vExperts, VCP, MVP, etc. But how do you get notified when the license is about to expire? Well I don’t know if there is an option for that, maybe in the Enterprise Portal but as far as I know will it only display an error when the license key is expired.

I decided to dive under the hood and tried to find the places where Veeam B&R holds the license information. I couldn’t find the license info with the Veeam Powershell Toolkit. So the next step was to find the info inside the Veeam Backup Database but I couldn’t find it either inside the database. The last step was the right one. The license information is kept inside the Windows registry in the following key:

HKLM\SOFTWARE\VeeaM\Veeam Backup and Replication\license

But the info is saved in a REG_BINARY so it’s harder to extract. But lucky me Tim Dunn wrote a simple one-liner to extract this data. So I added this to my script:

$regBinary = (Get-Item 'HKLM:\SOFTWARE\VeeaM\Veeam Backup and Replication\license').GetValue('Lic1')
$veeamLicInfo = [string]::Join($null, ($regBinary | % { [char][int]$_; }))

The $regBinary variable gets the data from the registry key. The $veeamLicInfo variable converts the $regBinary into human readable lines of text. So now we extracted the license info, we only need write a RegEx to extract the info we need to create a notification e-mail. So take a look at the $pattern variable which will search for:
“EXPIRATION DATE=MM/DD/YYYY”

The $expirationDate variable will execute the RegEx and it saves the first match via [0]. After that the match will be splitted and the the value after the “=” character will be used as the expiration date.

So now we have the expiration date but how do we calculate the remaining days. Well that’s exactly what the code, that fills the $totalDaysLeft variable does.

So here you will find the complete script:

Warning: this script is only tested on Veeam Backup & Replication version 5. So I don’t know if the script will work on version 6 too.

Update: If you want to use the following script with Veeam Backup & Replication v6. You only have to change the $pattern variable to: $pattern = expiration date\=\d{1,2}\/\d{1,2}\/\d{1,4}

Update 2: It’s possible to read the version from the executable. So I created an updated version of the script that works with Veeam v5 and Veeam v6.x.

#http://blogs.msdn.com/b/timid/archive/2011/06/17/stupid-tricks-with-reg-binary-registry-data.aspx <- $regBinary trick
#http://stackoverflow.com/questions/622902/powershell-tips-tricks-for-developers <- regex

$returnStateOK = 0
$returnStateWarning = 1
$returnStateCritical = 2
$returnStateUnknown = 3

$veeamExe = Get-Item 'C:\Program Files\Veeam\Backup and Replication\Veeam.Backup.Manager.exe'
$regBinary = (Get-Item 'HKLM:\SOFTWARE\VeeaM\Veeam Backup and Replication\license').GetValue('Lic1')
$veeamLicInfo = [string]::Join($null, ($regBinary | % { [char][int]$_; }))

if($veeamExe.VersionInfo.ProductVersion -match "6"){
    $pattern = "Expiration date\=\d{1,2}\/\d{1,2}\/\d{1,4}"
}
else{
    $pattern = "EXPIRATION DATE\=\d{1,2}\/\d{1,2}\/\d{1,4}"
}

$expirationDate = [regex]::matches($VeeamLicInfo, $pattern)[0].Value.Split("=")[1]
$totalDaysLeft = ((Get-Date $expirationDate) - (get-date)).Totaldays.toString().split(",")[0]
$totalDaysLeft = [int]$totalDaysLeft

if($totalDaysLeft -gt "14"){
    Write-Host "The Veeam License will expire in $($totalDaysLeft) days"
    exit $returnStateOK 
}
elseif($totalDaysLeft -ge "7"){
    Write-Host "The Veeam License will expire in $($totalDaysLeft) days"
    exit $returnStateWarning 
}
elseif($totalDaysLeft -lt "7"){
    Write-Host "The Veeam License will expire in $($totalDaysLeft) days" 
    exit $returnStateCritical 
}
else{
    Write-Host "Something went wrong...."
    exit $returnStateUnknown 
}

You can change the parameters of the Send-MailMessage and schedule a task op your Veeam server to report the total times left before the license will expire.

Veeam: Module Snapshot poweron failed. Unable to retrieve the current working directory


After performing an Instant Recovery you might get the following error when the VM is trying to power on:

image

After a quick search on the Veeam Forums I found the following topic: http://www.veeam.com/forums/ about the same issue. In this topic I found the following solution to this issue:


Well, finally i get the issue fixed. I think it could be considered a bug. Let me explain.
If i set “F:\” as a vPower NFS destination, the error shows up. But if i set “F:\any_directory”, then all runs perfect!.
Well i write this here to help anybody with the same issue.

So vPowerNFS cannot be pointed directly to the drive letter of a partition. To change this setting you can use registry editor and your mouse, but you can also run the following Powershell script to change this setting:

$vPowerNFSDir = "D:\vPowerNFS\"

if((Test-Path $vPowerNFSDir) -eq $false){
    New-Item $vPowerNFSDir -type directory
}

If((Get-ItemProperty "HKLM:\Software\VeeaM\Veeam Backup and Replication" -name "NFSDefaultRootPath").NFSDefaultRootPath -ne $vPowerNFSDir){
    Set-ItemProperty "HKLM:\Software\VeeaM\Veeam Backup and Replication" -name "NFSDefaultRootPath" -value $vPowerNFSDir
}

if((Get-Service -DisplayName "Veeam Backup Service").Status -eq "Running"){
    Restart-Service -displayname "Veeam Backup Service"
}

if((Get-Service -DisplayName "Veeam vPower NFS Service").Status -eq "Running"){
    Restart-Service -displayname "Veeam vPower NFS Service"
}

The only thing you have to change in this script is the $vPowerNFSDir variable to the correct location of your Veeam Backup & Recovery Server. This script will check if the folder exists, If this is not the case it will create the folder. The next step is to check the Registry key for the correct location. If this is not the case the script will change the Registry for you. The last step is to restart the Veeam Backup Service and the Veeam vPower NFS Service.

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

PowerCLI: Error 1406. Could not write value InstallPath to key….


Today I wanted to install PowerCLI on a new installed Windows 2008 R2 server. But I ended up with the following warning:

image

To fix this, you have to delete the following Registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\VMware, Inc.

And press retry. The PowerCLI setup will finish without errors.

 

Source: http://www.annoying.dk

Windows Update error code 80244019


image

On a fresh installed Windows Server 2008 X64 VM, a received the following error when I want to search for new Windows Updates:

image

The solution in my case was to delete the following registry key: 

HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate

 

Source: http://social.technet.microsoft.com/Forums/en-US/itprovistasetup/thread/e788027e-9292-47c0-891e-90309cf13367

VMware Tools Registry settings


image

@vmdavinci asked the following on Twitter:

image 

These are the registry settings you can change:

If you want to disable the notify if upgrade is available warning:

[HKEY_CURRENT_USER\Software\VMware, Inc.\VMware Tools]
@=dword:00000000

If you want to hide the Tools icon change the following registry key:

[HKEY_CURRENT_USER\Software\VMware, Inc.\VMware Tools]
"ShowTray"=dword:00000001

Or

[HKEY_LOCAL_MACHINE\Software\VMware, Inc.\VMware Tools]
"ShowTray"=dword:00000001

How to easily read the username instead of SID on a TS/Citrix server


image

I found this little trick in my RSS feeds and I must say this is really a KISS (keep it simple stupid) solution that everybody in a TS / Citrix environment can use.

I wanted to walk through the registry of a specific terminal server user. So I logged onto that terminal server too (using my own credentials) and opened up regedit… And then it hit me (again). I need to know the SID of the user to open his part of the registry.

To prevent having to get a SID ever again I implemented the earlier mentioned trick. I launched the RES PowerFuse console, went to Powerlaunch; User Registry and added a new String Value directly under HKEY_CURRENT_USER. I named the String "Username" and entered "%username%" as the value.

In the original blog post this will be done with PowerFuse. If you don’t use PowerFuse you can set this registry setting via your logon script.

If you’re running a logon script via Kix, you can add the following line:

WriteValue("HKEY_CURRENT_USER","UserID","@Userid","REG_SZ")   

Or if you’re running a batch script, you can add the following line:

REG ADD "HKCU" /v "UserID"  /d "%Username%" /t REG_SZ /f 

When the user runs the logon script, the registry setting will be imported and you can browse through the registry without knowing the SID of al your users.

image

Source: http://resinside.blogspot.com/2009_05_01_archive.html#6904219593671371315

Event ID: 1505


Gisteren kreeg ik de melding binnen dat het inloggen op de Citrix XenApp / Terminal Server niet meer lukte. Tijdens het inloggen verscheen de volgende error:

Windows cannot load the user’s profile but has logged you on with the default profile for the system. Detail: Insufficient system resources exist to complete the requested service.

In de Applicationlog van de server stond de onderstaande Event gelogt:

image

Nadat ik deze in google had geschoten kwam KB935649 naar voren en daar stond de volgende oplossing:

To resolve this problem, modify the registry to increase the PoolUsageMaximum value and the PagedPoolSize value. To do this, follow these steps:

1. Click Start, click Run, type regedit, and then click OK.

2. Locate and then click the following registry subkey:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management

3. On the Edit menu, point to New, and then click DWORD Value.

4. In the New Value #1 box, type PoolUsageMaximum, and then press ENTER.

5. Right-click PoolUsageMaximum, and then click Modify.

6. In the Value data box, type 60, and then click OK.

7. If the PagedPoolSize registry entry exists, go to step 8. If the PagedPoolSize registry entry does not exist, create it. To do this, follow these steps:

a.  On the Edit menu, point to New, and then click DWORD Value.

b. In the New Value #1 box, type PagedPoolSize, and then press ENTER.

8. Right-click PagedPoolSize, and then click Modify.

9. In the Value data box, type ffffffff, and then click OK.

10. Exit Registry Editor, and then restart the computer.

Je kunt ook de volgende regkey importeren op de terminal server KB935649.reg:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management]
“PagedPoolSize”=dword:ffffffff
“PoolUsageMaximum”=dword:00000060

Helaas zijn de nieuwe settings pas van kracht nadat de server opnieuw is opgestart. De error heeft geen invloed op de bestaande sessies. Ik heb daarom op de Server de logins tijdelijk uitgeschakeld en deze na het herstarten van de server weer ingeschakeld. Daarna was het probleem ook verholpen.