AsBuiltReport did not start as a framework. It started as a single PowerShell script designed to document a VMware vSphere environment. That script became the foundation of what would eventually grow into the VMware vSphere report module, and later, the AsBuiltReport framework itself.
When I built that first script, I was largely figuring it out as I went along. There was no established process, no structured approach, and no playbook to follow. I had a clear idea of what I wanted it to produce, but how I got there was very much an exercise in trial and error. When I made the decision to turn it into a modular framework, the vSphere script largely came along for the ride. It worked, and rebuilding it from scratch alongside everything else was not a priority, so it stayed largely as it was.
As I continued to develop new report modules, it became clear that working without a defined structure was not sustainable. Each new module raised the same questions. How should it be organised? What conventions should it follow? How should the code be structured? That realisation led directly to the creation of the AsBuiltReport Developer Guide, the foundation that every new report module is now built upon. The vSphere module still exists largely in its original state today, a testament to where the project started and a reminder of why those guidelines exist.
This post covers something different from the Developer Guide. It is about the personal habits and practices I follow when developing a new module, sitting alongside those guidelines rather than replacing them.
In nearly 20 years delivering enterprise infrastructure solutions, there is a common misconception I have encountered time and again — that an as-built document is simply a design document updated to reflect what was built, a past-tense version of the original plan. It is an understandable assumption, but it is fundamentally wrong. The two documents serve entirely different purposes, capture entirely different information, and should never be confused with one another.
This distinction matters. Getting it wrong means critical information goes undocumented, environments become harder to support, and the as-built loses its value as a source of truth.
A design document is created before a single component is deployed. Its purpose is to record intent — to describe what will be built, why it will be built that way, and how the proposed solution meets the requirements of the business.
A well-structured design document will typically capture:
Business requirements and how the proposed architecture meets them
Assumptions made during the design process — for example, that a specific network segment will be available, or that a licensing tier will be in place
Constraints that influenced design decisions, such as budget limits, existing infrastructure, or compliance obligations
Design decisions and justifications — the specific choices made during the design process and the reasoning behind them, such as why a particular platform, topology, or configuration approach was selected over alternatives
Critically, a design document captures the why. Why was this platform chosen over an alternative? Why is the solution architected this way? Why were certain trade-offs made? This reasoning is invaluable for future engineers who need to understand the intent behind a system — but it belongs in the design document, not the as-built.
An as-built document is not written in advance. It is generated from the system itself, after deployment, and its sole purpose is to record reality — what was actually deployed, how it is configured, and what it looks like right now.
An as-built document does not need to explain the why. Its focus is entirely on the is.
A thorough as-built document will capture:
The actual deployed configuration of every component
Network addressing, VLANs, and routing as they exist in the environment
Storage configurations, datastores, and volume assignments
Identity and access configurations
The current state of services, roles, and features
And here is the key point that the "updated design" misconception completely misses.
A design document is authored before the environment exists. By definition, it cannot contain information that is only generated at provisioning time. Yet this is precisely the information that is most valuable in an as-built document.
Consider the following examples:
VMware environments:
- Virtual machine instance UUIDs assigned at creation
- Managed Object Reference IDs (MOREFs) for vCenter objects
- Datastore URNs
- MAC addresses assigned to virtual network adapters
Microsoft Azure:
- Resource GUIDs for every deployed resource
- Subscription and tenant IDs
- Managed identity object IDs
- Auto-generated storage account endpoints and connection strings
- Deployment correlation IDs
Active Directory and Windows:
- Security Identifiers (SIDs) for users, groups, and computer accounts
- ObjectGUIDs for directory objects
- GPO GUIDs
None of these values exist at design time. No engineer can write them into a design document, and no amount of updating a design document to past tense will produce them. They can only be captured by interrogating the live system after deployment.
This is why an as-built document must be generated from the system, not authored by hand. Manual documentation of these values is error-prone, time-consuming, and almost always incomplete.
In my previous post I shared how I came to start AsBuiltReport and my reasons for doing so. It's been a few years since its inception and some of you may be asking what does the future hold for the project?
Before I delve into what may lie ahead, let me take a moment to reflect on the project's progression so far, by extending a sincere thank you to all the contributors who have given their time and effort to this project. Whether you have contributed code, reported bugs, provided feedback, written a blog post, or simply participated in discussions, your efforts have not gone unnoticed.
Back in 2017, having worked on designing and implementing VMware solutions for almost a decade, I became frustrated with having to repeatedly produce as-built documentation for my virtualisation projects.
At the time, I was designing and implementing 2-3 VMware solutions per month. Each solution would be designed using numerous technology partners, each with their own range of compute, storage, networking and backup technologies.
My methods to create as-built documentation was arduous, time consuming and error prone. It often involved extracting information using a combination of vendor supplied tools and community developed scripts, and manually transposing information from the vCenter console into a Word document. It was tedious and often resulted in a poorly constructed and formatted document.
It was also around this time that I realised I had a strong desire to learn PowerShell after seeing many of my co-workers starting to write scripts to automate simple, repeatable tasks. Until this moment, I had never taken the time to completely understand the fundamentals of PowerShell, nor had I worked to develop and expand my knowledge in any form of scripting or automation.
As a result, I saw this as an opportunity to learn and employ PowerShell automation to ease my pain and frustrations with producing as-built documentation. And so began my mission to create AsBuiltReport!