Skip to content

Navigation Menu

Sign in
Sign up

Veeam Backup for Azure As Built Report Module #21

acgdickie started this conversation in General
Discussion options

Hi Guys,
I have already started on this for my own use, but just saw the note on the website reposting before working on this so wanted to post early.
I am happy to do the heavy lifting on this, but looking to make a Veeam Backup for Azure As Built Module that utilizes the APIs on VBA to gather required info/data.
The plan was to keep the format, structure etc very similar to the Veeam VBR and VB365 modules created by @rebelinux.
I would love to share once closer to being done or done if you guys are willing to accept it.
Thanks,
Richard

You must be logged in to vote

Replies: 1 comment 14 replies

Comment options

Hi Richard,

It's great to hear that you are wanting to contribute to AsBuiltReport. Be sure to have a look at the recently updated guide for creating a report module.

If you have any questions, be sure to reach out to myself or Jonathan.

Cheers,
Tim

You must be logged in to vote
14 replies
Comment options

Hi @acgdickie,

Your submission as well as others has highlighted that there were gaps in the Developer Guidelines which needed to be addressed. I have worked on updating those in the past week to provide more information on how report modules should be structured. Documentation for the AsBuiltReport.Chart module was also added.

I am also working on a Claude skill to help contributors build modules which align to the guidelines. Part of this is work is to provide a code review and compliance report. It would typically generate the report in Word however I have converted it to Markdown below for you.

The main issue with the report module is in the structure of the private functions. Please review the report below, as well as the updated Developer Guide to refactor your functions in alignment with these guidelines.

Code Review & Compliance Report

AsBuiltReport.Veeam.VBAZ

Module version 0.1.0 · 10 June 2026

20 Total 14 Pass 5 Warning 1 Fail

Assessed against AsBuiltReport module framework guidelines

1. Overview

This report presents the results of a code compliance review of the AsBuiltReport.Veeam.VBAZ module (v0.1.0) against the AsBuiltReport framework guidelines. 20 checks were assessed: 14 pass, 5 warnings, and 1 fail.

The single FAIL concerns the module's use of generic rendering helpers. All private report functions delegate table construction and rendering to Add-AbrVbazTable and ConvertTo-AbrVbazTableObject rather than building [ordered]@{} inline and calling Table @TableParams directly. This pattern obscures table shape and output logic and must be resolved before a pull request can be accepted.

Five WARNING findings are also identified. Two relate to the module manifest: IconUri points to a personal GitHub avatar rather than the standard AsBuiltReport icon, and ProjectUri, LicenseUri, and ReleaseNotes still reference the personal fork. Three relate to code style: charts are positioned after their related tables in Get-AbrVbazLicense and Get-AbrVbazRestorePoint rather than before; ShowTableCaptions is unconditionally suppressed for List-mode tables inside Add-AbrVbazTable; and .LINK references in all function help blocks point to the personal fork rather than the AsBuiltReport organisation repository.

2. Findings Summary

Finding Category Status
Generic table/chart rendering helpers still in use — private functions not self-contained Code Style FAIL
.LINK in all private and public functions points to personal fork (acgdickie) Code Style WARNING
Chart rendered after table in Get-AbrVbazLicense and Get-AbrVbazRestorePoint (should precede) Code Style WARNING
ShowTableCaptions suppressed for List tables in Add-AbrVbazTable Code Style WARNING
IconUri points to personal GitHub avatar, not ABR standard Manifest WARNING
ProjectUri, LicenseUri, and ReleaseNotes point to personal fork Manifest WARNING
Module subdirectory layout correct Structure PASS
All required root-level documentation files present (CODE_OF_CONDUCT.md — resolved) Documentation PASS
.github/ present with full CI scaffold Structure PASS
Tests/ present with comprehensive Pester suite Structure PASS
Samples/ present with three JSON configurations Structure PASS
Manifest required fields, CompatiblePSEditions, and Copyright correct Manifest PASS
PSM1 uses Join-Path — cross-platform path construction correct Code Style PASS
Main function has [CmdletBinding()] and correct parameter validation Code Style PASS
Private functions follow Get-AbrVbaz* naming convention Code Style PASS
$reportTranslate correctly wired throughout Code Style PASS
Error handling with try/catch/finally correct in main appliance loop Code Style PASS
CHANGELOG, CONTRIBUTING.md, and README all correct Documentation PASS
Language file correctly structured and wired Documentation PASS
Offline capture mode correctly implemented Code Style PASS

3. Detailed Findings

3.1 Code Style

Generic rendering helpers hide table shape and output logic [FAIL]
FAIL Generic rendering helpers hide table shape and output logic — private functions are not self-contained
All private report functions (Get-AbrVbazLicense, Get-AbrVbazAppliance, Get-AbrVbazRestorePoint, Get-AbrVbazProtectedItem, Get-AbrVbazJobSession, and all others) delegate table construction and rendering to Add-AbrVbazTable and ConvertTo-AbrVbazTableObject. A reviewer cannot determine what data appears in the output without cross-referencing Helpers.ps1. This is unchanged from the prior review cycle.
File: Src/Private/Report/*.ps1 · Src/Private/Helpers.ps1
Remediation steps Refactor all private report functions to build [ordered]@{} inline and call Table @TableParams directly from within the function body. Remove Add-AbrVbazTable and ConvertTo-AbrVbazTableObject as rendering wrappers. Retain utility helpers (Connect-AbrVbazApi, Initialize-AbrVbazTls, ConvertTo-AbrVbazByteSize, etc.) in Helpers.ps1. Add begin/process/end blocks. Example preferred pattern:
function Get-AbrVbazLicense { [CmdletBinding()] param () begin { Write-PScriboMessage "Collecting VBAZ license information." } process { try { if ($InfoLevel.System.License -lt 1) { return } Section -Style Heading3 $LocalizedData.Heading { $OutObj = @() foreach ($License in @($script:AbrVbazInventory.License)) { $inObj = [ordered] @{ $LocalizedData.LicenseType = $License.licenseType $LocalizedData.IsFreeEdition = $License.isFreeEdition $LocalizedData.TotalInstances = $License.totalInstancesUses } $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj) } $TableParams = @{ Name = $LocalizedData.TableHeading; List = $true; ColumnWidths = 40, 60 } if ($Report.ShowTableCaptions) { $TableParams['Caption'] = "- $($TableParams.Name)" } $OutObj Table @TableParams } } catch { Write-PScriboMessage -IsWarning "License Section: $($_.Exception.Message)" } } end {} }
.LINK in function help blocks points to personal fork [WARNING]
WARNING .LINK in all function comment-based help blocks references the acgdickie personal fork
The .LINK URL in Invoke-AsBuiltReport.Veeam.VBAZ and all Get-AbrVbaz* private functions still points to https://github.com/acgdickie/AsBuiltReport.Veeam.VBAZ. Following repository transfer to the AsBuiltReport organisation this should reference the organisation URL.
File: Src/Public/Invoke-AsBuiltReport.Veeam.VBAZ.ps1 · Src/Private/Report/*.ps1
Remediation steps Update the .LINK value in all function help blocks:
.LINK https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBAZ
Chart rendered after table — should precede related table [WARNING]
WARNING Chart is rendered after its related table in Get-AbrVbazLicense and Get-AbrVbazRestorePoint
In Get-AbrVbazLicense the Licensed Resources table is rendered before the chart call. In Get-AbrVbazRestorePoint the Restore Point Summary table precedes the chart. The AsBuiltReport convention (used in AsBuiltReport.Veeam.VBR and VB365) places the chart before the table it summarises, using a NOTOCHeading4/5 section to keep the TOC clean. Get-AbrVbazJobSession follows this correctly (chart before table).
File: Src/Private/Report/Get-AbrVbazLicense.ps1 · Src/Private/Report/Get-AbrVbazRestorePoint.ps1
Remediation steps Move the chart generation and Image call to before the table call. Wrap in a NOTOCHeading section:
Section -Style NOTOCHeading4 'Overview' { $Chart = New-AbrVbazCountChart -Title '...' -CountObjects @(...) if ($Chart) { Image -Text '...' -Align Center -Percent 100 -Base64 $Chart } } Add-AbrVbazTable -Name '...' -InputObject $Rows
ShowTableCaptions suppressed for List tables in Add-AbrVbazTable [WARNING]
WARNING Add-AbrVbazTable unconditionally suppresses captions for List-mode tables
Add-AbrVbazTable contains: if ($Report.ShowTableCaptions -and -not $List). The -not $List guard means List tables never receive captions regardless of the ShowTableCaptions setting. The AsBuiltReport standard applies ShowTableCaptions unconditionally. If a PScribo limitation prevents caption rendering on List tables, a code comment explaining the reason should be added.
File: Src/Private/Helpers.ps1 (Add-AbrVbazTable function)
Remediation steps Remove the -not $List guard:
if ($Report.ShowTableCaptions) { $TableParams['Caption'] = "- $Name" }

3.2 Manifest PSData URIs

IconUri points to personal GitHub avatar [WARNING]
WARNING IconUri set to contributor's personal GitHub avatar rather than ABR standard icon
IconUri is currently set to https://github.com/acgdickie.png. The standard AsBuiltReport icon used by all published modules should be used instead. Unchanged from prior review.
File: AsBuiltReport.Veeam.VBAZ/AsBuiltReport.Veeam.VBAZ.psd1
Remediation steps Update IconUri in the manifest PSData block:
IconUri = 'https://raw.githubusercontent.com/AsBuiltReport/.github/main/profile/images/AsBuiltReport.png'
ProjectUri, LicenseUri, and ReleaseNotes point to personal fork [WARNING]
WARNING PSData URIs reference the personal acgdickie fork rather than the AsBuiltReport organisation
ProjectUri, LicenseUri, and ReleaseNotes all point to https://github.com/acgdickie/AsBuiltReport.Veeam.VBAZ. The repository has now been transferred to the AsBuiltReport organisation, so these should be updated.
File: AsBuiltReport.Veeam.VBAZ/AsBuiltReport.Veeam.VBAZ.psd1
Remediation steps Update the three PSData URIs:
LicenseUri = 'https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBAZ/blob/master/LICENSE' ProjectUri = 'https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBAZ' ReleaseNotes = 'https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.Veeam.VBAZ/master/CHANGELOG.md'

4. Passing Checks

The following areas are fully compliant with AsBuiltReport guidelines and require no action.

✓ CODE_OF_CONDUCT.md now present (resolved from prior review)

Confirmed present at repository root alongside README.md and CHANGELOG.md. This was the Documentation WARNING from the 5 June 2026 review — now resolved.

✓ Module subdirectory layout correct

All module files (psd1, psm1, json, Language/, Src/) reside inside AsBuiltReport.Veeam.VBAZ/ at the repository root, correctly matching the Plaster-scaffolded layout.

✓ .github/ present with full CI scaffold

.github/ confirmed with a PR template, bug report and change request issue templates, PSScriptAnalyzer.yml workflow, and PSScriptAnalyzerSettings.psd1.

✓ Tests/ present with comprehensive Pester suite

The test suite covers manifest validation, module import, source file parse integrity, per-resource function layout, JSON config sample validation, localization data completeness, and PSScriptAnalyzer compliance.

✓ Samples/ present with three JSON configurations

Level1.json, Level2.json, and Level3.json are all present, well-structured, and document all Options, InfoLevel, and HealthCheck keys with inline _comment_ fields.

✓ Manifest required fields, CompatiblePSEditions, and Copyright correct

All required fields present. CompatiblePSEditions = @('Desktop', 'Core') correct. Copyright uses 'AsBuiltReport Community'. RequiredModules correctly declares AsBuiltReport.Core v1.6.4, AsBuiltReport.Chart v0.3.2, and AsBuiltReport.Diagram v1.0.7.

✓ PSM1 uses Join-Path — cross-platform path construction correct

The module loader uses Join-Path consistently. PowerShell normalises the backslash-delimited child paths cross-platform; no hardcoded OS-specific separator issues observed.

✓ Main function has [CmdletBinding()] and correct parameter validation

Invoke-AsBuiltReport.Veeam.VBAZ has [CmdletBinding()], [Parameter(Mandatory)], [ValidateNotNullOrEmpty()], and typed parameters. Credential is correctly optional to support offline capture mode.

✓ Private functions follow Get-AbrVbaz* naming convention

All data-collection and section-orchestration private functions use the Get-AbrVbaz prefix. The naming convention is correct — the failure is the delegation pattern, not the names.

✓ $reportTranslate correctly wired throughout

The main function and all sampled private functions resolve their own translation group. No hardcoded English section headings observed.

✓ Error handling with try/catch/finally correct in main appliance loop

The main appliance foreach loop is wrapped in try/catch/finally. Non-fatal errors use Write-PScriboMessage -IsWarning. The finally block correctly calls Disconnect-AbrVbazApi.

✓ CHANGELOG, CONTRIBUTING.md, and README all correct

CHANGELOG follows Keep a Changelog format. CONTRIBUTING.md is VBAZ-specific throughout. README leads with Install-Module, includes usage examples, offline capture documentation, Options reference, InfoLevel matrix, HealthCheck reference, and Section Matrix.

✓ Language file correctly structured and wired

Language/en-US/VeeamVBAZ.psd1 uses a grouped hashtable structure keyed by function name. $reportTranslate is consumed consistently. The Pester suite validates all referenced groups exist in the language file.

✓ Offline capture mode correctly implemented

Options.CapturePath is correctly checked before attempting API authentication. Import-AbrVbazCaptureInventory correctly handles both folder and ZIP sources.

5. Recommended Action Priority

Address findings in the following order before submitting a pull request to the AsBuiltReport organisation.

# Finding Action required Blocks PR?
1 Generic rendering helpers Refactor all private report functions to build [ordered]@{} inline and call Table @TableParams directly. Remove Add-AbrVbazTable and ConvertTo-AbrVbazTableObject as rendering wrappers. Retain utility helpers. Yes
2 Chart placement order Move chart generation and Image call to before the related table call in Get-AbrVbazLicense and Get-AbrVbazRestorePoint. Wrap in a NOTOCHeading section. Recommended
3 .LINK help references Update .LINK URL in all function comment-based help blocks to https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBAZ. Recommended
4 ShowTableCaptions for List tables Remove the -not $List guard in Add-AbrVbazTable caption block, or document the reason if a PScribo limitation applies. Recommended
5 IconUri personal avatar Update to: https://raw.githubusercontent.com/AsBuiltReport/.github/main/profile/images/AsBuiltReport.png Recommended
6 ProjectUri / LicenseUri / ReleaseNotes Update the three PSData URIs to AsBuiltReport org URLs now that the repository has been transferred. No
Comment options

Ah cool, sorry missed that. I will have a read and investigate them this weekend.
Thanks @tpcarman

Comment options

Ok, sorry for the delay guys, Updated and uploaded the fixes this morning. SO ready for you to review again.

Comment options

Hey Richard,

I've had a look through this and I need to flag some issues before this goes any further. The brief was readability over brevity and self-contained functions. A reviewer and/or contributor needs to be able to read the code and understand what it's doing without jumping elsewhere. The code should be self-explanatory, not something someone should have to reverse-engineer. What I see here is a lot more code, causing a lot more confusion. This code is now harder to read than before. Honestly this doesn't look like something you've had a hand in, or have properly reviewed or tested before sharing. It has clearly been generated with an AI tool.

I've just published the AI Use Policy and think it would be worth a read. The short version is you need to be able to explain whatever you submit.

I suggest going back to your original submission and working through it by hand, by removing the wrapper functions and building each table yourself so you get familiar with the pattern. Utilise AI where you get stuck, but don't hand it the whole module to build in one pass. Start by building it yourself, one function at a time.

Use the documentation for reference, but reach out to @rebelinux or myself if you need further guidance.

Tim

Comment options

Yeah sorry I did ask claude to make the changes you ask before, I will look back at it again from what we had before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /