VCAP-DCV Design Attempt #2

About a year and a half ago, I sat the VCAP-DCV Design  6.5 exam. I failed it on my first try. I needed a 300 to pass and I scored a 284. So, it would seem, I likely missed passing by one or two questions.

The VCAP Design is well known as a difficult exam that takes many people more than one try to pass. I wanted to retake it, but at that time I was too broke to pay for a second exam, and I got buried in work.

I started a new job last August doing a mix of design and implementation work, and back in March of this year, I got Covid-19. Now, I didn’t get that sick, but I was forced to self-isolate for a couple of weeks. Once I was feeling better enough, I started studying again for the VCAP-DCV 6.5 Design exam.

After I was out of self-isolation, my company adopted a policy allowing telecommuting, so I was able to spend more time in the evenings studying, and in April I was thrilled to see that Pearson-Vue was offering proctored VMware exams online. I registered for the exam and continued preparing.

This morning I sat the exam, and aside from some minor technical difficulties on getting signed in (of course the home internet dropped briefly about 15 minutes before the scheduled exam!), I was out of the gates.

It took me about an hour to navigate through the questions. I didn’t really feel like there were any gotcha questions, and I felt very confident once I’d reviewed the marked questions. I clicked Finish, and immediately saw that I had passed. I may have startled the proctor with my triumphant shout…

I scored a 332. It’ll do.

To prepare for the exam I used the following resources

I suppose this makes me a VCIX-DCV 6.5. I’ll post the badge when I get it.

What’s next? I’ve committed to my employer to become more network savvy this year. So, you’ll probably see more design posts and some network oriented posts too.


Principles of Good Design – Putting it All Together

So, now that we have defined Requirements, Constraints, Assumptions, and Risks (RCARs), I want to provide some helpful tips around putting those together in a design.

  • Derive all requirements from the customer’s stated requirements. Some of these will require little translation into technical requirements. Most will require you to ask additional questions. For instance, their requirement might be stated as, “We need high availability.” You then need to clarify what high availability is. Is it 3 9s of uptime? 5 9s? Quick and automated failover?
  • Ask all relevant stakeholders to weigh in on Requirements and Constraints.
  • Think through every assumption.
  • Think through all of the possible risks. Then think through ways to mitigate those risks.
  • Validate all assumptions!
  • Organize RCARs into a logical format with tables. Give each item a relevant tag, such as R-001.002 for a requirement, or RK-01 for a risk.
  • Your whole design flows from RCARs. Word them and organize them in such a way as to make them easy to refer back to.

Principles of Good Design – Risks

It has been a crazy few weeks since I last wrote! But you know, roll with the punches!

The last basic category of design elements I wrote about was Assumptions. In this post, I’m going to introduce Risk.

A Risk is any uncertain thing that could negatively impact the completion of a project, or its functionality. It is your job as the designer to think through every possible risk.

For instance, going back to my bathroom example, a risk in the design was that I’d have to replace more of the subfloor than I anticipated, which would have increased costs as more plywood would have needed to be bought.

An example of a risk in IT is

It is possible that there will be a shortage of the necessary DDR4 memory at the time the order is placed, which may increase price and lengthen delivery time.

The goal here, in designing a solution is to recognize the Risks, determine their impact, and think through a way of mitigating them.

The example above, regarding DDR4 memory, would have the impact of increasing the price of the solution (supply drives price, sometimes), and would lengthen the delivery time. This risk, would then create additional risks if it’s not mitigated. A lengthened delivery time might, if the memory in the risk is being used in a new server to replace an old one, cause the old server to lose support leaving a window of usage where there is no OEM support. Or, if the memory is being added to an existing server because of environmental growth, it could constrain growth or cause unacceptable performance impacts.

So, recognizing that, this risk, like all risks, must be mitigated.

What are some ways we could do that? Well, we could consider buying our additional memory through a different VAR, who may have that memory in stock in a warehouse. Maybe, we consider buying the additional memory from a different OEM (make sure the alternate OEM is supported by the server OEM, or you have just introduced another risk!).

Every project has risks, and not all risks can be mitigated completely. But, all risks can be at least partially mitigated.

Another word on assumptions; if you do not validate your assumptions, they become risks.

Principles of Good Design – Assumptions

When talking about requirements and constraints, there are always factors that haven’t yet been quantified or proven. These are called Assumptions.

Going back to the bathroom renovation, an assumption I had approaching that project was,

The subfloor under the toilet will need to be replaced as it has partially rotted.

I knew the toilet would rock back and forth if you leaned too far to one side, and this seemed to be a reasonable assumption.

An assumption you may have with an IT project is,

There is sufficient bandwidth, compute power, and storage to replicate data to a second site.

Once you have identified the assumptions over the project, and the assumptions you bring to the project, you must then quantify whether those are valid or not. If you don’t prove out your assumptions and validate them, they become risks.

In the bathroom instance, I validated the presence of a rotten subfloor by going into my basement, and shining a light up to the underside of the floor and observing evidence of rot. In the IT instance above, you would probably consider how much data is being replicated to the “second site,” how much that data changes every day (deltas), and what the compute requirements are. Once you have that in mind, you can then calculate what sort of bandwidth is needed using an online calculator.

Now, let’s say you don’t validate those assumptions.

When I replaced my bathroom floor, had I not validated that the subfloor only needed to be replaced under the toilet, I may have spent extra money buying subfloor panels I didn’t need.

In the design example, your client will be very angry if you design a solution for them and they discover they need to order a lot of extra bandwidth to replicate your solution to their second site!

Always validate your assumptions.

You know what happens when you assume…

Principles of Good Design – Constraints

In the last post, we reviewed Requirements. We said that requirements are specific things required in the solution, or what the solution must be able to do.

The solution must enable the organization to recover its own data with minimal loss in the event of hardware or logical failure

Constraints are sometimes called nonfunctional requirements. They limit choices in the design; they constrain our options. Whereas requirements (aka Functional Requirements) tell us what the solution must be able to do, constraints usually tell us how the solution should do it.

In my previous example of replacing my bathroom floor last November, a constraint on the design of the floor could be, “The new floor must make use of gray tile.” See? That constraint instantly rules out brown, or white, or black tile.

In the IT Design world, an example of a constraint might be,

The solution will use Fibre Channel as the storage networking protocol

See? With that constraint, other storage connectivity options like iSCSI have just been ruled out.

The requirements and constraints allow us to begin building a design. They act as guard-rails in a way, as the final design must adhere to the requirements and constraints.

Next up, we will look as Assumptions and Risks!

Principles of Good Design – Requirements

Anytime you approach a project from the design phase, you need to gather the requirements. Anytime a project is handed to you by a Project Manager or a consultant, you need to refer to the requirements.

Most simply, requirements are specific things required in the solution. More specifically, requirements are what a solution must do.

I replaced my bathroom floor about 8 months ago. An example of a requirement for that project is, “The new floor must provide a water-resistant surface over the subfloor.” Another example might be, “The new floor must be easy to clean.”

Some IT examples might include,

The solution must enable the organization to recover its own data with minimal loss in the event of hardware or logical failure.

It is important to identify requirements before moving on to any other phase of design. The requirements are the guiding principles upon which the whole design relies.

Requirements will usually align with the design factors; Availability, Manageability, Performance, Recoverability, Security, and Cost.

Who do you get the requirements from? Normally the stakeholders in the project. That might be the CTO overseeing the initiative, the CIO, the IT Manager, the Systems Engineers, the Software Engineers, etc. You may need to translate requirements as mentioned into business language.

Requirements usually don’t mention specific technologies or technical solutions.

Next time we will talk about Constraints!

Principles of Good Design

I am going to start a new series on this blog to outline what constitutes Good Systems Design, and give some examples I’ve seen or even built myself (in the old days) of Bad Systems Design.

In this series, I’ll cover the following areas:

  1. Requirements, Constraints, Assumptions, and Risk – What are they? Why do they matter?
  2. AMPRS (Availability, Manageability, Performance, Recoverability, and Security) – the Big Design Qualities. I’ll also mention Cost, as that is often a design quality as well.
  3. Conceptual vs Logical vs Physical Design
  4. Real World Examples!


Stay tuned!

Enforcing Storage Policies with PowerCLI

Storage Policy Based Management (SPBM) is a tool in vSphere to use policies to manage storage.

It is a must-use in environments with vSAN, as it’s the tool used to define RAID policies and striping policies.

What can happen over time, however, is that as Virtual Machines are created by different administrators, storage policies may be applied inconsistently, which could cause unexpected behavior during failures of vSAN Components.

To fix this, and use scripting to enforce Storage Policies, I created the following script. Feel free to use it.

#SPBM Enforcement 1.0
#Created by vWebster

#Input the name of your vSAN Datastore
$VMlist = get-datastore “” | get-vm
#Input the name of your desired storage policy.
$StoragePolicy = “”
foreach ($VM in $VMlist)
Get-VM -Name $VM | Set-SpbmEntityConfiguration -StoragePolicy $StoragePolicy

Happy scripting!

VMXNET3 and DirectPath I/O

I recently discovered that vSphere 6.x (6.0 and 6.5) has a minor bug in the vSphere Web Client that is applicable when:

-A Virtual Machine is provisioned with a VMXNET3 network adapter.

-DirectPath I/O is enabled by default, even if the administrator does not select the checkbox to enable it.

Now, DirectPath I/O has specific use cases, of course, but most admins don’t use it as the use cases are very specific.

So now for the impact.

If you don’t have DirectPath I/O configured in your environment, then it is probably inconsequential. However, it could cause issues if you have DirectPath I/O set up. Either way, it’s better to disable it unless you really want to use it.

VMware has a KB that explains this behavior ( KB # 2145889 ).

Thanks to Roman over at Virtual Nomad I found a PowerCLI script to quickly obtain a list of the VMs that have DirectPath I/O enabled. This script will output to a .csv.

# File name: Get-DirectPathIOStatus.ps1
# Description: VMXNET3 – Network DirectPath I/O Status
# VMware KB:
# 06/07/2018 – Version 1.1
# – Added the PowerCLI version check
# – Improved the host connection block
# – Added an export to CSV
# 26/04/2017 – Version 1.0
# – Initial Release
# Author: Roman Dronov (c)
# Initial variables
$outputCollection = @()
$newModule = “VMware.PowerCLI”
$oldModule = “VMware.VimAutomation.Core”
# Check the PowerCLI module availability
Write-Host “`n Checking if the VMware PowerCLI modules are loaded…`r”
if ($(Get-InstalledModule | ? {$_.Name -like $newModule}) -eq $null) {
if ($(Get-Module | ? {$_.Name -like $oldModule}) -eq $null -and $(Get-Module -Name $oldModule -ListAvailable -ErrorAction Ignore) -eq $null) {
Write-Host “`n You need to install the VMware PowerCLI module to run this script. Exiting…`r” -ForegroundColor Yellow
else {
Import-Module -Name $oldModule -ErrorAction Ignore -WarningAction Ignore
$moduleVersion = $(Get-Module -Name $oldModule).Version
Write-Host “`n The VMware PowerCLI module version $moduleVersion is loaded successfuly.`r” -ForegroundColor Green
else {
$moduleVersion = $(Get-InstalledModule -Name $newModule).Version
Write-Host “`n The VMware PowerCLI module version $moduleVersion is detected.`r” -ForegroundColor Green
# Set the VIServer connection mode to Multiple
$connectionMode = $(Get-PowerCLIConfiguration -Scope Session).DefaultVIServerMode
if ($connectionMode -like ‘Single’) {
Set-PowerCLIConfiguration -Scope Session -DefaultVIServerMode Multiple -Confirm:$false | Out-Null
# Connect to the host(s)
function Enter-Credentials {
$defaultUser = $env:USERDOMAIN + “\” + $env:USERNAME
if ($(Read-Host “`n Username [default: $($defaultUser)]”) -eq ”) {
$viUser = $defaultUser
else {
$viPassword = Read-Host ” Password” -AsSecureString
$script:viCredential = New-Object System.Management.Automation.PSCredential ($viUser,$viPassword)
function Verify-ViServer {
$viServer = Read-Host -Prompt “`n Input the host name and then press Enter”
Write-Host “`n Checking connection to “”$viServer””…” -ForegroundColor Green
while ($(Test-Connection -ComputerName $viServer -Count 2 -ErrorAction Ignore) -eq $null) {
Write-Host “`n Host “”$viServer”” is not reachable.” -ForegroundColor Yellow
$viServer = Read-Host -Prompt “`n Input the correct host name and then press Enter”
$script:viServer = $viServer
if ($global:DefaultVIServers.Count -ne ‘0’){
Write-Host “`n Connection has already established with the following host(s):”
$vcsaConnections = $global:DefaultVIServers
foreach ($vcsaServer in $vcsaConnections) {
Write-Host “`t* $vcsaServer`r” -ForegroundColor Yellow
$userAnswer = Read-Host “`n Would you like to continue using current connection(s)? [Yes/No]”
while (“Yes”,”No” -notcontains $userAnswer) {
$userAnswer = Read-Host “`n Please choose correct answer [Yes/No]”
if ($userAnswer -eq ‘No’) {
Write-Host “`n Connecting to “”$viServer””…” -ForegroundColor Green
Connect-VIServer -Server $viServer -Credential $viCredential -ErrorAction Ignore -WarningAction Ignore | Out-Null
else {
else {
Write-Host “`n Connecting to “”$viServer””…” -ForegroundColor Green
Connect-VIServer -Server $viServer -Credential $viCredential -ErrorAction Ignore -WarningAction Ignore | Out-Null
# Read all VMs that have VMXNET3
$vmNetworks = Get-VM | Get-NetworkAdapter | Where-Object {$_.Type -eq ‘Vmxnet3’}
# Get information about the network card
for ($i=0; $i -lt $vmNetworks.Count; $i++) {
$vm = $vmNetworks[$i].Parent
$vmNetworkName = $vmNetworks[$i].NetworkName
$vmNetworkAdapter = $vmNetworks[$i].ExtensionData.DeviceInfo.Label
$vmNetworkAdapterDPIOStatus = $vmNetworks[$i].ExtensionData.UptCompatibilityEnabled
if ($vmNetworkAdapterDPIOStatus -ne ‘True’) {
$dpioStatus = “Disabled”
else {
$dpioStatus = “Enabled”
$properties = @{‘Virtual Machine’ = $vm.Name;
‘HW Version’ = $vm.Version;
‘Network Adapter’ = $vmNetworkAdapter;
‘Network Name’ = $vmNetworkName;
‘DPIO Status’ = $dpioStatus}
$object = New-Object –TypeName PSObject –Property $properties
$outputCollection += $object
# Disconnect from the host(s) and clear the screen
Disconnect-VIServer * -Confirm:$false
# Print out the results
$dpioResults = $outputCollection | Sort-Object -Property “Virtual Machine” | select Virtual*,*Version,*Adapter,*Name,*Status
Write-Host “`n DirectPath I/O status`r”
# Save results to CSV
$csvPath = $env:TEMP + “\DPIOStatus-” + $(Get-Date -Format ‘ddMMyyyy’) + “.csv”
$dpioResults | Export-CSV -Path $csvPath -NoTypeInformation -Force -Confirm:$false
Invoke-Item $csvPath

Now you have a list of VMs that are affected. How do you disable DirectPath I/O on those machines? You could do it with the GUI, which I suppose wouldn’t take too long if you only have a couple of machines to remediate. But, if you have more than a few machines, you could be looking at a time-consuming, and potentially error-prone morning or afternoon of pointing and clicking.

Or you could use a script to save time.

Thanks to the PowerCLI community, and LucD, I was able to create a script that disables DirectPath I/O on a list of VMs that is fed to it.

So, you can take the machines called out in the .csv that the first script you ran created, save them to a text file, and feed that into this script.

#DirectPath I/O Disable Script

#Use the network adapter name for the $nicName variable
$nicName = ‘Network Adapter 2’
$directPath = $false # or $true to enable Direct Path IO
$vmlist = Get-VM -Name (Get-Content C:\Temp\VmList.txt)

foreach($vm in $vmlist){
$nic = Get-NetworkAdapter -VM $vm -Name $nicName
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$dev = New-Object VMware.Vim.VirtualDeviceConfigSpec
$dev.Operation = [VMware.Vim.VirtualDeviceConfigSpecOperation]::edit
$dev.Device = [VMware.Vim.VirtualDevice]$nic.ExtensionData
$dev.Device.UptCompatibilityEnabled = $directPath
$spec.DeviceChange += $dev

Run that script, and it will disable DirectPath I/O on the VMs you call out in your list.