PowerShell script exchange
Post Reply
Pudster
Novice
Posts: 5
Liked: never
Joined: Nov 19, 2020 3:02 pm
Full Name: Christopher Puddy
Contact:

List all Incomplete jobs and locations

Post by Pudster »

Hello All,

I am fairly new to powershell and and the forum, however I have been tasked with trying to find/build a script to pull via Powershell to be run via task scheduler.
I have already found this powershell-f26/powershell-script-to-lis ... 49222.html forum post however any attempts at trying to bend it to what we need has failed so i had kind of had to resort to building my own.

Here's the code I have cobbled together using the other forum post as a reference whilst trying to understand what's going on with each part so I can learn more, whilst I fulfil the task. The end result will go out to CSV/Email at the end in order for it to be added to our tracking system, I have the CSV bit working in my version so have omitted that from here, VM name changes have also taken place.

The main areas i need to show are the affected Vm's, the Date of the backup, the state is incomplete, location and which repository it sits in. At the minute the focus is on just standard Repo's but there are plans to make use of SOBR's which I suspect and from reading around this type of script could be a problem.

I am still working on the script (still working out how to link and name repo's) but I have currently hit my limit, as I am struggling to work out how to output the "Filepath" from the $mybackups.getallstorages() section as part of the final output.. if I use my variable $mybackupstest i get the "creation time" and "filepath", however like in my Code below if I use the $myrestorepoints I get all three but not the "filepath".

Code: Select all

$mybackups = get-vbrbackup | ?{$_.JobType -eq "BackupSync"}
$myrestorepoints = $mybackups | Get-VBRRestorePoint | ?{$_.IsConsistent -eq $false}

foreach ($myRestorepoint in $myrestorepoints) {
        foreach ($mybackupstest in $mybackups.getallstorages()) {
        $myCompare = $myrestorepoints | ?{$_.BackupId -eq $mybackups.Id -and $myrestorepoints.IsConsistent -eq $false}
        }
      }

$myrestorepoints = $myrestorepoints | Sort-object -Property BackupId
$myrestorepoints | select -Property VmName,CreationTime,IsConsistent,FilePath | Fortmat-table

VmName      CreationTime        IsConsistent FilePath
------      ------------        ------------ --------
vmname1     05/08/2020 22:46:31        False         
vmname2     05/08/2020 22:33:38        False         
vmname3     05/08/2020 22:39:24        False         
vmname4     05/08/2020 22:41:52        False         
       
Any advice or assistance would be greatly appreciated.

oleg.feoktistov
Veeam Software
Posts: 664
Liked: 236 times
Joined: Sep 25, 2019 10:32 am
Full Name: Oleg Feoktistov
Contact:

Re: List all Incomplete jobs and locations

Post by oleg.feoktistov »

Hi Christopher and Welcome to The Forums!

First, I don't see that $myCompare variable is used at any point. Maybe I don't see the whole script, but if I do, this variable can be deleted as it bears no sense.

Second, I'd like to help you get rid of excessive looping. Instead of foreach ($mybackupstest in $mybackups.getallstorages()) you can apply GetStorage() method on each restore point leaving yourself without false necessity of retrieving all storages for all backups each loop. It's not only time consuming, but useless.

Now, about your question. If you want to use values from different variables all in one, you need to write a custom hashtable for select statement, which turns into a property. The syntax is @{n='PropertyName';e={$variableName.ValueName}}. The whole script would look something like that:

Code: Select all

$mybackups = get-vbrbackup | ?{$_.JobType -eq "BackupSync"}
$myrestorepoints = $mybackups | Get-VBRRestorePoint | ?{$_.IsConsistent -eq $false}

foreach ($restorepoint in $myrestorepoints) {
        $storage = $restorepoint.GetStorage()
        $restorepoint | select VmName, CreationTime, IsConsistent, @{n='File Path';e={$storage.FilePath}} | ft

  } 
It can get tricky with SOBR if you want to retrieve the whole storage path, but as long as partial path is required, it's ok.

If you have any questions, fire away. Glad to help you.

Best regards,
Oleg

Pudster
Novice
Posts: 5
Liked: never
Joined: Nov 19, 2020 3:02 pm
Full Name: Christopher Puddy
Contact:

Re: List all Incomplete jobs and locations

Post by Pudster »

Hello Oleg,

Thank you for the reply and for the explanations.. with regards to my script I pasted in what I had managed to achieve so yeah there were some extra variables that I hadn't made use of and by the looks of your script i didn't need at all.

with regards to SOBOR at some point we will need to understand where the files are, so anything useful would be handy at this point.
I have tried tinkering with your script to try and get things working the way i needed however i seem to be missing something obvious, I have tried to match the output of what I have been requested to gather but I suspect I need to do something more to get all the results in a single CSV/email.

As the request is essentially... a table of all incompletes.. which your script currently gives however we need to know the job names and if possible the repository name where this file is located as well as everything else.. I tried several versions but this one gave me the closest result but it seems to be pulling the "PartialPath" and listing it as a string rather than matching it. I'll have a play more but I suspect the string I am seeing is because I am not filtering it anywhere so as the foreach runs it lists each job it run's through and see's the "PartialPath" as an line that matches everything.

I have added a "or" statement to pick out both Bakcups and Backup Copyjobs as it was missed in my original post.


Idea of table layout either CSV or email

Code: Select all

VmName      CreationTime      Backuptype  IsConsistent Backupjobname(PartialPath) Repositoryname(Not found this property yet)     File Path   
Vmname1    Datetime stamp       BCJ           False          Backup Job name1                Reponame1                          Directory location
Vmname2    Datetime stamp       Backup        False          Backup Job name2                Reponame3                          Directory location



Code: Select all

Add-PsSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

$mybackups = get-vbrbackup | ?{$_.JobType -eq "BackupSync" -or $_.Jobtype -eq "backup" }
$myrestorepoints = $mybackups | Get-VBRRestorePoint | ?{$_.IsConsistent -eq $false}

foreach ($restorepoint in $myrestorepoints) {
        $storage = $restorepoint.GetStorage()
        $restorepoint | select VmName, CreationTime, IsConsistent, @{n='File Path';e={$storage.FilePath}} , @{n='Partial Path';e={$mybackups.PartialPath}} 

  } 

  $restorepoint | select VmName, CreationTime, IsConsistent, @{n='Partial Path';e={$mybackups.PartialPath}}, @{n='File Path';e={$storage.FilePath}} | ConvertTo-Csv -Delimiter "," > "c:\$((Get-Date).ToString("yyyyMMdd_HHmmss"))_export.csv"
Thank you
Pudster

Pudster
Novice
Posts: 5
Liked: never
Joined: Nov 19, 2020 3:02 pm
Full Name: Christopher Puddy
Contact:

Re: List all Incomplete jobs and locations

Post by Pudster »

Hello Oleg,

ok so have been playing around with this a bit more and kept struggling trying to get a CSV output from your code so sort of went back to the drawing board a bit and have ventured down this route again which does allow me to output to a CSV without too many issues however I am still stuck with the "JobName" object throwing all the answers for the property PartialPath, which isn't helpful, I think I know why but not sure I know how to rectify it so for now I just leave the "JobName" out of the main script but thought i'd update you here.

I am still trying to work out how to list out the repositories and somehow get them linked so I know for certain where the files are and that they are correct. I am currently looking at the "Get-VBRBackupRepository" command to find the answer but it's early days so far.

Code: Select all

Add-PsSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

$mybackups = get-vbrbackup | ?{$_.JobType -eq "BackupSync" -or $_.Jobtype -eq "backup" }
$myrestorepoints = $mybackups | Get-VBRRestorePoint | ?{$_.IsConsistent -eq $false}
$storage=@()
$allRestorePoints=@()

foreach ($restorepoint in $myrestorepoints) {
       foreach ($storage in $restorepoint.GetStorage()){
                $allRestorePoints += New-Object -TypeName psobject -Property @{
                JobName=$Mybackups.PartialPath;
                Vmname=$restorepoint.DisplayName;
                Date=$Storage.CreationTime;
                Incomplete=$restorepoint.IsConsistent;
                Filepath=$storage.FilePath;
                }
        }
  } 

  $allrestorepoints | select -property VmName, Date, Incomplete, FilePath , Jobname | ConvertTo-Csv -Delimiter "," > "c:\$((Get-Date).ToString("yyyyMMdd_HHmmss"))_export.csv"

  
If i am taking myself down the wrong path let me know so i can change course.

Kind regards
Pudster

oleg.feoktistov
Veeam Software
Posts: 664
Liked: 236 times
Joined: Sep 25, 2019 10:32 am
Full Name: Oleg Feoktistov
Contact:

Re: List all Incomplete jobs and locations

Post by oleg.feoktistov »

Hi Christopher,

First, about SOBRs. It is a virtual instance with several extent as its members. So, besides figuring out the repo name itself, you'd need to determine extent name and backup location there. With regards to this, I'd build a separate object for repos of SOBR type. Also, we cannot get precise location of a storage on object storage repository as there is simply no file system there and files are merely blocks kept together. They construct a restore point as per metadata upon download/restore calls. The only marker, which could lead us to understanding the tier our data is kept on is ExternalContentMode property of CStorage object ($storage). If it reads internal - the storage is on performance tier, if external - on capacity. But it works only if the storage was moved to capacity tier, not copied.

Then, about JobName and PartialPath. Backup name almost always refers to Job name, so you can use either $backup.Name or $backup.JobName to reflect it. To parse correct job name for each restore point, you'd need to place your loop over restore points inside a loop over each backup.

Finally, getting the repository is quite simple. I use $rp.FindChainRepositories() to determine SOBR extent and $rp.FindRepository() to obtain a regular repo. So, at last, the code would look something like that:

Code: Select all

 Add-PsSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

$mybackups = get-vbrbackup | ?{$_.JobType -eq "BackupSync" -or $_.Jobtype -eq "backup" }
$allRestorePoints=@()
foreach ($backup in $mybackups) {
   $myrestorepoints = $backup | Get-VBRRestorePoint | ?{$_.IsConsistent -eq $true}
foreach ($restorepoint in $myrestorepoints) {
       $repo = $restorepoint.FindRepository()
       foreach ($storage in $restorepoint.GetStorage()){
            if ($repo.GetType().Name -eq 'CExtendableRepository') {
                $extent = $restorepoint.FindChainRepositories()
                $allRestorePoints += New-Object -TypeName psobject -Property @{
                JobName=$backup.JobName;
                JobType=$backup.JobType;
                Vmname=$restorepoint.DisplayName;
                Date=$Storage.CreationTime;
                Repository=$repo.Name;
                Extent=$extent.Name;
                IsConsistent=$restorepoint.IsConsistent;
                Filepath="$($extent.FriendlyPath)\$($backup.PartialPath)\$($storage.FilePath)";
                }
             }

            else {
                $allRestorePoints += New-Object -TypeName psobject -Property @{
                JobName=$backup.JobName;
                JobType=$backup.JobType;
                Vmname=$restorepoint.DisplayName;
                Date=$Storage.CreationTime;
                Repository=$repo.Name;
                IsConsistent=$restorepoint.IsConsistent;
                Filepath="$($repo.FriendlyPath)\$($backup.PartialPath)\$($storage.FilePath)";
            }
          }
      }
  } 
}

  $allrestorepoints | select -property VmName, Date, Incomplete, FilePath , Jobname | ConvertTo-Csv -Delimiter "," > "c:\$((Get-Date).ToString("yyyyMMdd_HHmmss"))_export.csv"
Of course, it takes additional modifications if one of your extents/regular repos is linux, SMB share or else to comply with file path format,
but I hope you get the idea.

Thanks,
Oleg

Pudster
Novice
Posts: 5
Liked: never
Joined: Nov 19, 2020 3:02 pm
Full Name: Christopher Puddy
Contact:

Re: List all Incomplete jobs and locations

Post by Pudster »

Hello Oleg,

Thank you for this script.. I had no where near this in my attempts.. i have added a couple of extra filters as during my testing i found that the GUi was reporting incompletes but the above script wasn't showing it..

so I made a few edits..
This:

Code: Select all

$myrestorepoints = $backup | Get-VBRRestorePoint | ?{$_.IsConsistent -eq $true}
changed to this:

Code: Select all

$myrestorepoints = $backup | Get-VBRRestorePoint | ?{$_.IsConsistent -eq $false -or $_.IsCorrupted -ne $False}
This added to both parts of the IF statement:

Code: Select all

Iscorrupted=$restorepoint.IsCorrupted;
I also fixed the Final Select properties to pickup the correct objects so now this pushes out the information we are after.. I am just testing this scripts functionality (still yet to try this on a scale out setup). I am awaiting feedback from the team to see if there is anything else they want from this however the only thing I suspect they will want is the ability to have this emailed.. but i think i know how to do this.

Here's the current code:

Code: Select all

 Add-PsSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

$mybackups = get-vbrbackup | ?{$_.JobType -eq "BackupSync" -or $_.Jobtype -eq "backup" }
$allRestorePoints=@()
foreach ($backup in $mybackups) {
   $myrestorepoints = $backup | Get-VBRRestorePoint | ?{$_.IsConsistent -eq $false -or $_.IsCorrupted -ne $False}
foreach ($restorepoint in $myrestorepoints) {
       $repo = $restorepoint.FindRepository()
       foreach ($storage in $restorepoint.GetStorage()){
            if ($repo.GetType().Name -eq 'CExtendableRepository') {
                $extent = $restorepoint.FindChainRepositories()
                $allRestorePoints += New-Object -TypeName psobject -Property @{
                JobName=$backup.JobName;
                JobType=$backup.JobType;
                Vmname=$restorepoint.DisplayName;
                Date=$Storage.CreationTime;
                Repository=$repo.Name;
                Extent=$extent.Name;
                IsConsistent=$restorepoint.IsConsistent;
                Iscorrupted=$restorepoint.IsCorrupted;
                Filepath="$($extent.FriendlyPath)\$($backup.PartialPath)\$($storage.FilePath)";
                }
             }

            else {
                $allRestorePoints += New-Object -TypeName psobject -Property @{
                JobName=$backup.JobName;
                JobType=$backup.JobType;
                Vmname=$restorepoint.DisplayName;
                Date=$Storage.CreationTime;
                Repository=$repo.Name;
                IsConsistent=$restorepoint.IsConsistent;
                Iscorrupted=$restorepoint.IsCorrupted;
                Filepath="$($repo.FriendlyPath)\$($backup.PartialPath)\$($storage.FilePath)";
            }
          }
      }
  } 
}

  $allrestorepoints | select -property VmName, Date, IsConsistent, IsCorrupted, Jobname, FilePath  | ConvertTo-Csv -NoTypeInformation -Delimiter "," > "c:\$((Get-Date).ToString("yyyyMMdd_HHmmss"))_export.csv"
Thank you for the help thus far.

Kind regards
Chris Puddy

oleg.feoktistov
Veeam Software
Posts: 664
Liked: 236 times
Joined: Sep 25, 2019 10:32 am
Full Name: Oleg Feoktistov
Contact:

Re: List all Incomplete jobs and locations

Post by oleg.feoktistov »

Hi Chris,

The script looks good. Let me know if you need any further help.

Best regards,
Oleg

Pudster
Novice
Posts: 5
Liked: never
Joined: Nov 19, 2020 3:02 pm
Full Name: Christopher Puddy
Contact:

Re: List all Incomplete jobs and locations

Post by Pudster »

Hey Oleg,

Will do I am just trying to get my hands on some SMTP details from the customer to test and make sure the sending to email option works, it was requested.. once done I'll post up the final script, unless I get asked for something else... I've been hearing some rumblings about doing a check to ensure associated backups are not running at the time the incompletes are being checked via this script, thus taking out any false positive's.. but currently they've not landed on my desk sooo not currently my focus.

Thank you for all the help thus far.

Cheers
Pudster

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests