Hi Stephan,
You're very welcome! Glad it worked and thank you for the kind words :3
As for your questions, will split them into two sections:
Backup File Location:
First, some terminology:
Backup: Logical construct representing the top-level of what makes a "backup" in the UI. Includes info like VBM location, repository information, etc.
Restore Point: Logical construct representing point in time of a given object in backup.
Storage: The actual backup files on repository (VBK/VIB/V..), inside of which are the actual data blocks and metadata to make up a backup.
For storages not stored on a Scale-out Backup Repository (SOBR), fetching the path from CStorage objects is as simple as checking FilePath.
For SOBRs, you need to "build" the path from a few other locations, and I'll just share from my notes document:
Scale-out Repositories (SOBR) and non-SOBR repos have different paths
Non-SOBR use full path on system and can be retrieved with just the path for the Storage Object
SOBR uses relative paths for the Storage and need to be constructed with:
Extent.GetPath()
MetaPath property†
Storage Name (Storage = backup file, e.g., vbk/vib/vrb)
† You can also use the Job.Name property but this will fail for imported backups on a SOBR as well as Orphaned, so it's better to use the MetaFile Path
SOBR requires a metafile for Backups when adding an extent, so it's safe to assume this will be here. Backups on SOBR that somehow have a NULL or empty meta file path should be treated as exceptions and do not need special handling; by definition it is a problem with the environment and it needs to be fixed, not handled by code
Note: the bolded part I'm talking about image based backups (VMware/HV, Agents, etc) -- I'm not sure how it works with Plugin backups, but for image based backups that should be true
The script does this automatically, and builds it from the Extent path (Repository Path set in the Repository wizard in the UI), the MetaPath (represents the job folder name on the repository, may differ from what you see in the UI), and then the actual storage file name.
Why 0'd UUID in the script?
Good eye for noticing this

It's to allow the script in its current form to process Imported and Orphaned backups, which will have a 0'd UUID for the JobID property. In looking again at the script, I don't remember why I made an if statement there; I want to say imported/orphaned behave differently and you need to check a different property, but it's entirely possible I was just in a rush and needed a quick fix for a case at that time and forgot to go back and check it

Probably it can be optimized, but I think it's pretty fast still.