My setup actually uses remote SQL, but I think I happen to have sqlcmd installed due to some other reasons so I get your point. In all honesty I was just being lazy using Invoke-Sqlcmd. You can easily modify the script to use the .NET Framework Data Provider for SQL Server which, as far as I know, has no other dependencies. I'm not as familiar with it, and it takes more lines of code, but below is an example that I hacked together and it worked for me. I tested it on a fresh Windows 2008R2 install with nothing but Veeam v8 Patch 1 installed and it worked just fine.
BTW, the code below has this little magic:
Code: Select all
[Veeam.Backup.Core.CBackupRepositoryEx]::SyncSpaceInfoToDb($r, $true)
This forces Veeam to refresh the current space information for the specific repository and is an internal call that has changed at least once very recently. When V8 Patch 1 was released it added a second parameter so I had to modify that. It was a very simple modification, but that is one of the risk when calling directly into the underlying code. The user that I originally developed the entire "repo free space" code for wasn't actually using this call so that's why I didn't remember it, he was just living with the fact that pulling from the database wasn't 100% accurate in real time. It's up to you whether you consider it valuable enough. My concern was that a large job can run a long time and consume a lot of space before it is updated in the DB, but if you have a lot of jobs running all the time this may not be much of an issue since there will always be jobs ending and updating the data.
I guess the supported way to do this would be to do something like:
Code: Select all
Get-VBRBackupRepository -Name "Name of repository" | Rescan-VBREntity -Wait
But as I mentioned in the first post that's pretty heavy as it rescans the entire repo and can take quite a long time for a large repo with many jobs/restore points. I'm actively looking for an alternative method to trigger this.
Interestingly the REST API does offer free/total space information, but it's also not real time and even calling the above code does not update it immediately. But perhaps that's also an alternative, should be pretty easy to make the REST call from Powershell, although I've never really tried it.
Once again, feedback is welcome and thanks for the discussion. Here is the modified code using System.Data.SqlClient instead of Invoke-Sqlcmd:
Code: Select all
function Get-vPCRepoInfo {
[CmdletBinding()]
param (
[Parameter(Position=0, ValueFromPipeline=$true)]
[PSObject[]]$Repository
)
Begin {
$dbServer = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication').SqlServerName
$dbInstance = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication').SqlInstanceName
$dbName = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication').SqlDatabaseName
$outputAry = @()
function Build-Object {param($name, $path, $free, $total)
$repoObj = New-Object -TypeName PSObject -Property @{
Target = $name
storepath = $path
StorageFree = [Math]::Round([Decimal]$free/1GB,2)
StorageTotal = [Math]::Round([Decimal]$total/1GB,2)
FreePercentage = [Math]::Round(($free/$total)*100)
}
return $repoObj
}
}
Process {
foreach ($r in $Repository) {
if ($r.GetType().Name -eq [String]) {
$r = Get-VBRBackupRepository -Name $r
}
# Force refresh of free space in repo
# Setup SQL server connection
[Veeam.Backup.Core.CBackupRepositoryEx]::SyncSpaceInfoToDb($r, $true)
# Grab Total/Free space from DB
$sqlConn = New-Object System.Data.SqlClient.SqlConnection
$sqlConn.ConnectionString = "Server=$dbServer;Database=$dbName;Integrated Security=True"
$sqlConn.Open()
$sqlCmd = New-Object System.Data.SqlClient.SqlCommand
$sqlCmd.Connection = $sqlConn
$sqlCmd.CommandText = "SELECT total_space, free_space from [dbo].[BackupRepositories] where id = '$($r.id.ToString())'"
$sqlReader = $sqlCmd.ExecuteReader()
while ($sqlReader.Read()) {
$totalspace = $sqlReader["total_space"]
$freespace = $sqlReader["free_space"]
}
$sqlConn.Close()
$outputObj = Build-Object $r.Name $r.Path $freespace $totalspace
$outputAry = $outputAry + $outputObj
}
}
End {
$dbInstance
$outputAry
}
}