Monthly Archives: September 2025

VCF 9 in Detail – why it’s a genuine step forward for customers

Title Image

Hugo, the Cloud Admin

Hugo stands in for many of our customers: he’s responsible for a platform that must be secure, compliant, and agile all at once.
But his everyday reality is full of real obstacles. Four typical examples:


1. The Ticket Desert

A developer needs a new subnet. The request passes through three departments, each reviewing, approving, and forwarding it.
By the time the VLAN is ready, the sprint is already over – and the planned feature is scrapped.
The result: shadow IT and growing frustration in the team.

Ticket Desert

2. Shared Network, Shared Pain

All teams share a single IP range.
One duplicate hostname is enough, and monitoring collapses for everyone.
Suddenly developers, NetOps, and admins are firefighting together – and tripping over each other in the process.

Shared Network

3. Roles Without Boundaries

NetOps, vSphere admins, and developers all run their own scripts.
But no one has the full picture. A firewall port stays open – unnoticed until compliance shows up at audit time.
The risk is always present.

Roles Without Boundaries

4. No Guardrails, Full Risk

“Just a bit more CPU” – and suddenly a cluster consumes everything it can get.
The finance department’s database suffers, the ESXi farm runs at the limit, alarms are firing.
Without clear guardrails, the platform loses its stability.

No Guardrails

What VCF 9 Really Changes

vSphere Namespaces

Namespaces are more than mere technical isolation – they give customers something like a mini data centre.
A project team gets its own resources, shielded from the rest of the infrastructure, with quotas and policies that cannot be exceeded.
That ensures no one can monopolise the platform – while the VI admin still retains full control.

Namespaces

VM Operator

The VM Operator makes VMs declarative.
A developer writes in YAML what sort of VM they need – and it spins up in seconds.
This means VMs can also be used like containers for short-lived, one-off tasks, instead of going through the full, imperative lifecycle of a traditional VM.
It changes how we think about VMs: they are no longer just “pets” but can be used as dynamically as Kubernetes workloads.

VM Operator

Virtual Private Clouds (VPCs)

With VPCs, VCF 9 allows customers to act as service providers themselves.
Teams can build complex network architectures in self-service – isolated, secure, and scalable.
This solves two classic problems of private clouds: the lack of multi-tenancy and the difficulty of network integration.
For organisations delivering multi-tenant services to internal or external customers, it’s a real breakthrough.

VPCs

Fleet Management with VCF Automation

With VCF Automation (vRA), clarity returns: clusters can be run at scale and consistently.
Business logic is built directly into platform operations – whether for updates, rollouts, or compliance checks.
That reduces manual effort and enables customers to manage their fleets in the same way as modern public cloud platforms.

Automation

Multi-AZ Topologies

Multi-AZ is not just an architectural feature – it changes the developer’s perspective.
For the first time, they see the actual topology of the infrastructure and can design their applications to be topology-aware.
That makes the platform more cloud-native, enabling developers to create availability models similar to those used in hyperscaler regions.
For us, Multi-AZ topologies are the step that brings VMware closest to the region models of major providers – and there’s more to come.

Multi-AZ1
Multi-AZ2
Multi-AZ3

Upstream Alignment

One of the key strengths of VKS: it stays very close to upstream Kubernetes.

A Venn diagram explains it well:

  • In real multi-cloud environments, the lowest common denominator of features often dictates what’s possible.
  • Many abstraction layers set that bar so low that valuable platform features are lost.

With VKS, it’s different:

  • Customers can use the full native features of vSphere and NSX whenever they need them.
  • At the same time, they can always fall back to the unified subset of Kubernetes when portability across platforms takes priority.
  • Unlike distribution-based approaches that over-abstract, here the choice remains with the customer.

That makes VKS a Kubernetes service that integrates seamlessly into the VMware world – while remaining open and CNCF-compliant.

Upstream Alignment

My Talk

I recently gave a talk on exactly these themes: how VCF 9 and VKS work together to make complex realities simpler and safer.

Talk

Watch on-demand


Conclusion

Session Cover

VCF 9 delivers the very features that move customers forward in day-to-day operations – not as buzzwords, but in concrete terms:

  • Namespaces for safety and freedom.
  • VM Operator for declarative, dynamic VMs.
  • VPCs for real multi-tenancy.
  • VCF Automation for consistent fleet management.
  • Multi-AZ for cloud-native designs, close to the region model of the hyperscalers.
  • Upstream alignment for portability, without having to forgo native features.

That’s why, for me, VCF 9 is a genuine step forward.

Lazy VCF Token Refresh

If you use many VKS supervisors, your access tokens expire quickly and you end up logging in to every cluster again. The VCF CLI can handle this for you. The following PowerShell script walks through every saved context and refreshes the tokens automatically.

<#
.SYNOPSIS
  Refresh (and if needed re-auth) all VCF CLI contexts non-interactively.

.NOTES
  - No TMC special-casing here; treats all contexts the same.
  - Fixes the bug where $Args conflicted with PowerShell’s automatic $args.

.PARAMETER Password
  SecureString password for this run (no storage).

.PARAMETER PromptForPassword
  Prompt for the password securely (no storage).

.PARAMETER SaveCredential
  Prompt once and save password securely for reuse (DPAPI file; Credential Manager if available).

.PARAMETER UseSavedCredential
  Load previously saved password (DPAPI file or Credential Manager).

.PARAMETER ClearCredential
  Remove any stored credential and exit.

.PARAMETER CredTarget
  Name for the stored credential (if Credential Manager is used). Default: VCF-SSO.
#>

[CmdletBinding()]
param(
  [Parameter(ParameterSetName='Direct', Mandatory=$false)]
  [SecureString]$Password,

  [Parameter(ParameterSetName='Prompt', Mandatory=$true)]
  [switch]$PromptForPassword,

  [Parameter(Mandatory=$false)]
  [switch]$SaveCredential,

  [Parameter(Mandatory=$false)]
  [switch]$UseSavedCredential,

  [Parameter(Mandatory=$false)]
  [switch]$ClearCredential,

  [Parameter(Mandatory=$false)]
  [string]$CredTarget = 'VCF-SSO'
)

# ---------- Secure storage (DPAPI; optional Windows Credential Manager) ----------
$AppDir   = Join-Path $env:APPDATA 'VcfCli'
$CredFile = Join-Path $AppDir 'vcf_sso_cred.xml'

function ConvertTo-PlainText([SecureString]$Secure) {
  if (-not $Secure) { return $null }
  $bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($Secure)
  try { [Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr) }
  finally { [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr) }
}

function Save-Password([SecureString]$Secure, [string]$Target) {
  if (-not (Test-Path $AppDir)) { [void](New-Item -Type Directory -Path $AppDir -Force) }
  $cred = New-Object System.Management.Automation.PSCredential ('vcf', $Secure)
  $cred | Export-Clixml -Path $CredFile

  $cm = Get-Module -ListAvailable -Name CredentialManager | Select-Object -First 1
  if ($cm) {
    try {
      Import-Module CredentialManager -ErrorAction Stop | Out-Null
      $plain = ConvertTo-PlainText $Secure
      if ($plain) { New-StoredCredential -Target $Target -UserName 'vcf' -Password $plain -Persist LocalMachine | Out-Null }
    } catch { }
  }
}

function Load-Password([string]$Target) {
  $cm = Get-Module -ListAvailable -Name CredentialManager | Select-Object -First 1
  if ($cm) {
    try {
      Import-Module CredentialManager -ErrorAction Stop | Out-Null
      $stored = Get-StoredCredential -Target $Target
      if ($stored -and $stored.Password) { return ($stored.Password | ConvertTo-SecureString -AsPlainText -Force) }
    } catch { }
  }
  if (Test-Path $CredFile) {
    try {
      $cred = Import-Clixml -Path $CredFile
      if ($cred -and $cred.Password) { return $cred.Password }
    } catch { }
  }
  return $null
}

function Clear-Password([string]$Target) {
  if (Test-Path $CredFile) { Remove-Item $CredFile -Force -ErrorAction SilentlyContinue }
  $cm = Get-Module -ListAvailable -Name CredentialManager | Select-Object -First 1
  if ($cm) {
    try {
      Import-Module CredentialManager -ErrorAction Stop | Out-Null
      Remove-StoredCredential -Target $Target -ErrorAction SilentlyContinue
    } catch { }
  }
}

if ($ClearCredential) {
  Clear-Password -Target $CredTarget
  Write-Host "Stored credential cleared." -ForegroundColor Yellow
  return
}

# ---------- Determine password ----------
$SecurePwd = $null
switch ($PSCmdlet.ParameterSetName) {
  'Prompt' { $SecurePwd = Read-Host 'Enter VCF password' -AsSecureString }
  'Direct' { $SecurePwd = $Password }
  default {
    if ($UseSavedCredential) {
      $SecurePwd = Load-Password -Target $CredTarget
      if (-not $SecurePwd) { throw "No saved credential found. Run with -SaveCredential or -PromptForPassword." }
    } elseif ($SaveCredential) {
      $SecurePwd = Read-Host 'Enter VCF password to save (hidden)' -AsSecureString
      Save-Password -Secure $SecurePwd -Target $CredTarget
      Write-Host "Credential saved securely." -ForegroundColor Green
    } else {
      $SecurePwd = Load-Password -Target $CredTarget
      if (-not $SecurePwd) { $SecurePwd = Read-Host 'Enter VCF password (not stored)' -AsSecureString }
    }
  }
}
$PlainPwd = ConvertTo-PlainText $SecurePwd
if (-not $PlainPwd) { throw "No password available." }

# ---------- CLI wrapper (avoid $args conflict; support PS5/PS7) ----------
function Invoke-Vcf {
  param([string[]]$ArgList)
  # Prefer native invocation with array splatting (PS7+). For PS5, fall back to cmd.exe
  if ($PSVersionTable.PSVersion.Major -ge 7) {
    $out = & vcf @ArgList 2>&1
  } else {
    $quoted = $ArgList | ForEach-Object { if ($_ -match '[s"]') { '"' + ($_ -replace '"','"') + '"' } else { $_ } }
    $cmd = 'vcf ' + ($quoted -join ' ')
    $out = & cmd /c $cmd 2>&1
  }
  $code = if ($LASTEXITCODE -ne $null) { $LASTEXITCODE } else { 0 }
  [pscustomobject]@{ ExitCode = $code; Output = ($out -join "`n") }
}

function Get-VcfContexts {
  # Primary attempt
  $res = Invoke-Vcf @('context','list')
  if ($res.ExitCode -ne 0) { throw "Failed to list contexts:`n$($res.Output)" }

  # If we somehow got top-level help, don’t parse it as contexts.
  if ($res.Output -match 'Usage:s+vcfb' -or $res.Output -match 'Available command groups:') {
    throw "CLI returned help text instead of contexts. Ensure 'vcf context list' works in this shell."
  }

  $names = @()
  foreach ($line in ($res.Output -split "`n")) {
    if ($line -match '^s*$' -or $line -match '^s*(NAME|CURRENT|-+)b') { continue }
    # Extract the first token (context name), but only if it looks like a context (lowercase/colon/digit/._-)
    if ($line -match '^s*(?<name>[a-z0-9][a-z0-9._:-]*)b') {
      $n = $Matches['name']
      if ($n -ne 'vcf' -and $n -ne 'usage') { $names += $n }
    }
  }
  $names = $names | Sort-Object -Unique
  if (-not $names) { throw "No contexts parsed from 'vcf context list'. Raw:`n$($res.Output)" }
  return $names
}

function Try-Refresh([string]$ctx) { Invoke-Vcf @('context','refresh', $ctx) }

# ---------- Main ----------
Write-Host "Collecting contexts..." -ForegroundColor Cyan
$contexts = Get-VcfContexts
$env:VCF_CLI_VSPHERE_PASSWORD = $PlainPwd  # non-interactive auth for Supervisor/VKS

$failed = @()

try {
  Write-Host "Found contexts:" -ForegroundColor Cyan
  $contexts | ForEach-Object { Write-Host " - $_" }

  foreach ($ctx in $contexts) {
    Write-Host "`n[$ctx] Refresh..." -ForegroundColor Yellow
    $r = Try-Refresh $ctx
    if ($r.ExitCode -eq 0) {
      Write-Host "[$ctx] OK (refreshed or token still valid)." -ForegroundColor Green
      continue
    }

    Write-Warning "[$ctx] refresh failed (ExitCode=$($r.ExitCode)). Trying 'use'..."
    $u = Invoke-Vcf @('context','use', $ctx)
    if ($u.ExitCode -eq 0) {
      Write-Host "[$ctx] Re-auth via 'use' OK." -ForegroundColor Green
      $r2 = Try-Refresh $ctx
      if ($r2.ExitCode -eq 0) { Write-Host "[$ctx] Final refresh OK." -ForegroundColor Green }
    } else {
      Write-Host "[$ctx] Could not re-auth without an interactive terminal. Check endpoint trust/credentials." -ForegroundColor Red
      $failed += $ctx
    }
  }
}
finally {
  $env:VCF_CLI_VSPHERE_PASSWORD = $null
  $PlainPwd = $null
}

if ($failed.Count) {
  Write-Host "`nManual follow-up required for:" -ForegroundColor Magenta
  $failed | ForEach-Object { Write-Host " - $_" }
}
Script output with multiple contexts
More output with additional contexts
Secure password prompt in PowerShell

Why this script is handy

  • no typing for each cluster
  • enter the password once or store it securely for reuse
  • cleans up the environment after running
  • suitable for lab setups and production installations

Happy lazy logins!

“Preparing Windows for VCF CLI and Kubectl”

Who this is for

Windows-based vSphere/VCF administrators or Platform Engineers who want to use VMware Cloud Foundation (VCF) CLI and Kubernetes tools on a Windows machine.

This guide walks through setting up a Windows admin workstation with all necessary tooling for managing vSphere Kubernetes Service (VKS) on VCF (9).


What you’ll set up

  1. Install prerequisites (.NET 4.8 for the VCF CLI).
  2. Install PowerShell tooling: Chocolatey, VCF CLI, kubectl, etc.
  3. Enable auto-completion and aliases for CLI commands.
  4. (Optional) Install helpers like PSKubeContext and k9s.
  5. Verify your environment is ready for VCF and Kubernetes commands.

1) Install .NET 4.8 (required for VCF CLI)

Open PowerShell as Administrator and run:

$DownloadUrl = "https://go.microsoft.com/fwlink/?linkid=2088631"  # .NET 4.8 installer
$OutputFile = "C:\ndp48-x86-x64-allos-enu.exe"
Invoke-WebRequest -Uri $DownloadUrl -OutFile $OutputFile -UseBasicParsing -ErrorAction Stop
Start-Process -FilePath $OutputFile -ArgumentList "/quiet","/norestart" -Wait

 • Installs silently in the background.
 • Once complete, reboot your machine (required for .NET to finalize).

2) Prepare PowerShell & Chocolatey

After reboot, open PowerShell (Administrator) again.

Create a PowerShell profile (Skip if you got one or we will overwrite yours)

New-Item -ItemType File -Path $PROFILE -Force

This creates (or resets) your PowerShell profile (where aliases & completions live).

Install Chocolatey (Windows package manager)

Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

• If PATH isn’t updated immediately, restart PowerShell.


3) Install VCF CLI and kubectl

VCF CLI via Chocolatey

choco install vcf-cli -y

Manual installation (if Chocolatey package unavailable)

$vcfRoot = "C:\Program Files\VCF\"
$vcfVersion = "v9.0.0"
$arch = "amd64"
$url = "https://packages.broadcom.com/artifactory/vcf-distro/vcf-cli/windows/$arch/$vcfVersion/vcf-cli.zip"

if (Test-Path $vcfRoot) { Remove-Item -Recurse -Force $vcfRoot }
$tmp = Join-Path $env:TEMP 'vcf-bootstrap'
if (Test-Path $tmp) { Remove-Item -Recurse -Force $tmp }
New-Item -ItemType Directory -Path $tmp | Out-Null

$zip = Join-Path $tmp 'vcf-cli.zip'
Invoke-WebRequest $url -OutFile $zip -UseBasicParsing
Expand-Archive $zip -DestinationPath $tmp -Force

New-Item -ItemType Directory -Path $vcfRoot -Force | Out-Null
Copy-Item (Join-Path $tmp 'vcf-cli-windows_amd64.exe') -Destination (Join-Path $vcfRoot 'vcf.exe') -Force

$currentPath = [Environment]::GetEnvironmentVariable('Path','Machine')
if ($currentPath -notlike "*$vcfRoot*") {
    [Environment]::SetEnvironmentVariable('Path', "$currentPath;$vcfRoot", 'Machine')
}
Remove-Item -Recurse -Force $tmp
Write-Host "VCF CLI installed to $vcfRoot. Restart PowerShell or run 'refreshenv'."

Install kubectl

choco install kubernetes-cli -y

Check with:

kubectl version --client

Optional tools

choco install k9s -y      # Kubernetes TUI
choco install vscode -y   # VS Code for YAML editing

4) Enhance PowerShell with Auto-Completion & Aliases

Install PSReadLine

Install-Module -Name PSReadLine -Force -SkipPublisherCheck

Enable VCF CLI completion

vcf completion powershell | Out-String | Invoke-Expression
vcf completion powershell | Out-File -Append -Encoding ascii $PROFILE

Enable kubectl alias (k) + completion

Set-Alias -Name k -Value kubectl -Option AllScope

$kubeComp = kubectl completion powershell | Out-String
$kubeComp = $kubeComp -replace "CommandName 'kubectl'", "CommandName @('kubectl','k')"
Invoke-Expression $kubeComp

$marker = '# >>> kubectl-alias-and-completion'
$profilePath = $PROFILE

if (-not (Select-String -Path $profilePath -SimpleMatch $marker)) {
    $persistBlock = @"
$marker
Import-Module PSReadLine
Set-Alias -Name k -Value kubectl -Option AllScope
$($kubeComp.TrimEnd())
# <<< kubectl-alias-and-completion
"@
    Add-Content -Path $profilePath -Value $persistBlock
}

Optional: PSKubeContext (kubectx/kubens equivalents)

Install-Module -Name PSKubeContext -Scope CurrentUser -Force

Add to profile

kubectx/kubens shortcuts and completion

Import-Module PSKubeContext
Set-Alias kubens  Select-KubeNamespace
Set-Alias kns     Select-KubeNamespace
Set-Alias kubectx Select-KubeContext
Set-Alias kctx    Select-KubeContext
Register-PSKubeContextComplete

Reload profile:

. $PROFILE

5) Verify Your Environment

VCF CLI

vcf --help

Try tab completion: vcf context

kubectl & alias

kubectl version --client
k version --client

Try:

k get <Tab><Tab>
kubectx -h
kubens -h

Test k9s

k9s

(Will show UI if a kubeconfig context is configured.)

Welcome to > /dev/null

This space is dedicated to exploring the intersection of platform engineering,
Kubernetes, and enterprise infrastructure
— with a special focus on vSphere
Kubernetes Service (VKS)
.

I started this blog because so much of what we do in the field never makes it
into official documentation or polished marketing decks. The real value often
lies in the lessons learned under pressure, the automation tricks that save
hours, and the architectural decisions that make or break a platform.

What to Expect

Here’s what you can expect here:

  • Deep dives into VKS: from networking and storage to automation and
    lifecycle management.
  • Stories from the field: real challenges, and how they were solved (or
    not).
  • Ecosystem insights: tools like ArgoCD, Fleet
    automation, and more.
  • Opinion pieces: what works, what doesn’t, and where platform engineering
    is heading.

If you’re a platform engineer, architect, or just curious about how enterprises
actually run Kubernetes at scale, this blog is for you.

This is just the beginning—thanks for joining me.

About the Author

I’m Constantin, living just outside Frankfurt in Bad Nauheim with my girlfriend, enjoying life’s many small pleasures. When I’m not helping teams ship platforms, I’m usually building robots of questionable usefulness, 3D-printing parts, wiring up motor drivers, or hacking on code. I also love mountain biking, hiking, a bit of track racing, and piloting a very polite electric boat that tops out at ~5 knots.

What I do (in plain words)

Since 2025 I’m the Specialist for vSphere Kubernetes Service (VKS) in DACH at Broadcom—an SME/evangelist role. I help customers and colleagues make sense of Kubernetes on vSphere, from VKS fundamentals to platform automation with tools like VCF Automation, Shell and Python, Argo CD, Docker and everything around day-2 operations, networking, and guardrails.

I’m at my best when I’m translating between classic infrastructure teams and cloud-native folks—getting everyone aligned on outcomes, not buzzwords.

Where I come from

  • Modern Apps BU (VMware/Broadcom): Architect and later SE on strategic accounts (SAP, Siemens, DHL).
  • VCF & Automation: Previously Staff Consultant focused on VCF automation; designed and migrated thousands of VMs onto new private clouds for a leading automotive.
  • Global Instructor (EMC/VMware): Taught storage & virtualization (Symmetrix, Centera, Celerra, vSphere, vBlock) in 38 countries. Love turning complex tech into clear mental models.

Along the way I picked up a few badges (e.g., CKA, VCP-DCV/NV, VCAP-CMA)—useful, but what really matters is shipping reliable platforms people enjoy operating.

Things I tinker with

  • Robotics & automation: ROS, motor controllers, sensor fusion; 3D printing & CNC
  • Platform experiments: GitOps, cluster lifecycle, secure supply chains
  • Weekend stuff: Bikes, trails, travel, occasional golf, and the “why does this even work?” kind of side projects

Quick facts

  • Role: VKS (vSphere Kubernetes Service) Specialist, DACH @ Broadcom (since Jul 2025)
  • Strengths: Platform architecture, automation, Kubernetes on vSphere, “infra ↔ dev” translation
  • Based in: Bad Nauheim (near Frankfurt)
  • Languages: German (native), English (C2)
  • Approach: Pragmatic, approachable, obsessed with clear docs and smooth day-2 ops

Find me online

How do I look like?

Consti headshot