PowerShell script exchange
Post Reply
Lord_Gaav
Novice
Posts: 4
Liked: never
Joined: Jul 02, 2012 10:32 am
Contact:

Retrieving a complete VBRBackup object using C#

Post by Lord_Gaav »

I've been trying to retrieve information about VBRBackup objects using PowerShell, so I can integrate it into a WCF SOAP service. So far I've been successful, but the resulting code is really slow. The reason for this, is that I have to call Get-VBRBackup four times to retrieve all the information I want. In normal PowerShell I can simply do:

Code: Select all

$obj = Get-VBRBackup -Name server.name.com
$storages = $obj.GetStorages()
$storages.Info
$storages.Stats
The above code only calls the (slow) Get-VBRBackup function once. The other function and field calls are instant. Total runtime is about 4 seconds in my setup.

The corresponding C# code is:

Code: Select all

Pipeline getVbrBackup = PowerShellHost.createPipeLine();
Command GetVbrBackup = new Command("Get-VBRBackup");
GetVbrBackup.Parameters.Add("Name", Name);
getVbrBackup.Commands.Add(GetVbrBackup);

Collection<PSObject> backups = PowerShellHost.invoke(getVbrBackup);

if (backups.Count == 0)
{
    return null;
}

Pipeline getStorages = PowerShellHost.createPipeLine();
getStorages.Commands.AddScript("$backup = Get-VBRBackup -Name '" + Name + "'");
getStorages.Commands.AddScript("$storages = (Get-VBRBackup -Name $backup.Name).GetStorages()");
getStorages.Commands.AddScript("$storages");

Collection<PSObject> storages = PowerShellHost.invoke(getStorages);

Pipeline getInfo = PowerShellHost.createPipeLine();
getInfo.Commands.AddScript("$backup = Get-VBRBackup -Name '" + Name + "'");
getInfo.Commands.AddScript("$info = (Get-VBRBackup -Name $backup.Name).GetStorages() | % { $_.Info }");
getInfo.Commands.AddScript("$info");

Collection<PSObject> infos = PowerShellHost.invoke(getInfo);

Pipeline getStats = PowerShellHost.createPipeLine();
getStats.Commands.AddScript("$backup = Get-VBRBackup -Name '" + Name + "'");
getStats.Commands.AddScript("$stats = (Get-VBRBackup -Name $backup.Name).GetStorages() | % { $_.Stats }");
getStats.Commands.AddScript("$stats");

Collection<PSObject> stats = PowerShellHost.invoke(getStats);

return VBRBackup.fill(backups[0], storages, infos, stats);
PowerShellHost is a static class that handels the connection to the Remote PowerShell instance on the VEEAM server, and the invoke method throws PowerShell errors as Exceptions. As you can see, in this C# approach I have to call Get-VBRBackup four times to retrieve all information. I have been unable to extract the information I want from the first call in "backups". I have tried to cast the PSObject that Get-VBRBackup returns as a CBackup, by including the Veeam.Core.Model DLL. However, even though the PSObject that Get-VBRBackup returns in PowerShell seems to be a CBackup, I cannot cast it as such in C#.

Can anyone tell me if I've missed something obvious, or if a better approach exists to retrieve all the information in a VBRBackup using C#?

Sethbartlett
Expert
Posts: 282
Liked: 26 times
Joined: Nov 10, 2010 6:51 pm
Full Name: Seth Bartlett
Contact:

Re: Retrieving a complete VBRBackup object using C#

Post by Sethbartlett »

A CBackup object is actually from Veeam.Backup.Core.dll. Veeam.Backup.Core.CBackup is the full path to the class. Give me a few and I will test a few things in Visual Studio.
Skype: Sethbartlett88 - Make sure to label who you are and why you want to add me ;)
Twitter: @sethbartlett
If my post was helpful, please like it. Sometimes twitter is quicker to hit me up if you need me.

Sethbartlett
Expert
Posts: 282
Liked: 26 times
Joined: Nov 10, 2010 6:51 pm
Full Name: Seth Bartlett
Contact:

Re: Retrieving a complete VBRBackup object using C#

Post by Sethbartlett » 1 person likes this post

Add Veeam.Backup.Common.dll and Veeam.Backup.Core.dll to your project, skip powershell and you can do the following:

Code: Select all

Veeam.Backup.Core.CBackup[] MyBackups = Veeam.Backup.Core.CBackup.GetAll();
From here, MyBackups is an array of all of your backups and you can do as you need with them, I'm sure you can figure it out from there ;) If you have any problems, let me know.
Skype: Sethbartlett88 - Make sure to label who you are and why you want to add me ;)
Twitter: @sethbartlett
If my post was helpful, please like it. Sometimes twitter is quicker to hit me up if you need me.

Lord_Gaav
Novice
Posts: 4
Liked: never
Joined: Jul 02, 2012 10:32 am
Contact:

Re: Retrieving a complete VBRBackup object using C#

Post by Lord_Gaav »

How would I go about doing this if my C# project isn't on the same server as VEEAM? We have multiple VEEAM servers, and I can't deploy it on all the servers. I need to be able to retrieve them remotely, which is why I turned to Remote PowerShell.

Sethbartlett
Expert
Posts: 282
Liked: 26 times
Joined: Nov 10, 2010 6:51 pm
Full Name: Seth Bartlett
Contact:

Re: Retrieving a complete VBRBackup object using C#

Post by Sethbartlett »

Why not just do the $Storages line and then reference $Storages multiple times rather than doing Get-VBRBackup again?
Skype: Sethbartlett88 - Make sure to label who you are and why you want to add me ;)
Twitter: @sethbartlett
If my post was helpful, please like it. Sometimes twitter is quicker to hit me up if you need me.

Lord_Gaav
Novice
Posts: 4
Liked: never
Joined: Jul 02, 2012 10:32 am
Contact:

Re: Retrieving a complete VBRBackup object using C#

Post by Lord_Gaav »

Could you give an example of that in C#? The way I tried it caused an error saying the pipeline had already been invoked. I didn't seem to be able to reference a variable from an earlier pipeline in a later one.

Sethbartlett
Expert
Posts: 282
Liked: 26 times
Joined: Nov 10, 2010 6:51 pm
Full Name: Seth Bartlett
Contact:

Re: Retrieving a complete VBRBackup object using C#

Post by Sethbartlett »

That's the beauty of the runspace you have open :)

Your invokes need to change so it looks like:

Code: Select all

Pipeline getStorages = PowerShellHost.createPipeLine();
getStorages.Commands.AddScript("$backup = Get-VBRBackup -Name '" + Name + "'");
getStorages.Commands.AddScript("$storages = (Get-VBRBackup -Name $backup.Name).GetStorages()");
getStorages.Commands.AddScript("$storages");

Collection<PSObject> storages = getStorages.invoke();
In your next piece of code you could do the following:

Code: Select all

Pipeline getInfo = PowerShellHost.createPipeLine();
getInfo.Commands.AddScript("$Info = $storages.Info);
getInfo.Commands.AddScript("$Info");

Collection<PSObject> Info= getInfo.invoke();
Skype: Sethbartlett88 - Make sure to label who you are and why you want to add me ;)
Twitter: @sethbartlett
If my post was helpful, please like it. Sometimes twitter is quicker to hit me up if you need me.

Lord_Gaav
Novice
Posts: 4
Liked: never
Joined: Jul 02, 2012 10:32 am
Contact:

Re: Retrieving a complete VBRBackup object using C#

Post by Lord_Gaav »

Aha, that works. I was wondering how I could access variables from previous pipelines, this explains it. My function went from an execution time of 16 secs to <1 secs.

Sethbartlett
Expert
Posts: 282
Liked: 26 times
Joined: Nov 10, 2010 6:51 pm
Full Name: Seth Bartlett
Contact:

Re: Retrieving a complete VBRBackup object using C#

Post by Sethbartlett »

Awesome! Glad I could help :)
Skype: Sethbartlett88 - Make sure to label who you are and why you want to add me ;)
Twitter: @sethbartlett
If my post was helpful, please like it. Sometimes twitter is quicker to hit me up if you need me.

Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests