Custom PowerShell Prompt: Display Connected vCenter Servers

2 minute read

Several people that I work with have custom bash prompts that they use to visually indicate which Git branch they are in, and the state of that branch. It occurred to me that this would be very useful in PowerCLI; I often avoid connecting to more than one vSphere endpoint at a time because I’m afraid of the consequences of a forgotten -Server argument.

With this inspiration, I decided to implement a PowerShell prompt that shows the hostnames of all connected PowerCLI endpoints. Here’s an example of the prompt I achieved:

prod-vc dr-vc nyc-esxi-099 PowerShell>

This prompt shows that I’m connected to the prod-vc and dr-vc vCenter servers, as well as an ESXi host, nyc-esxi-099. I also shortened the present working directory indication to be just the name of the lowest directory in the hierarchy, bash-style. This keeps the prompt short, leaving lots of room for way-too-long one-liner PowerShell commands. (I typically use C:\Users\pjorg\Documents\Scripts\PowerShell as my working directory, thus PowerShell is shown above.)

The key to achieving this is in the global:prompt function in PowerShell. This function is called every time the prompt is drawn, so overwriting the default with your own code allows you to modify what is printed. Here’s mine:

# Modify the prompt function to change the console prompt.
# Save the previous function, to allow restoring it back.
$originalPromptFunction = $function:prompt
function global:prompt{
# change prompt text
if(Test-Path variable:global:defaultviservers) {
$global:DefaultVIServers | %{ Write-Host $_.Name.Split('.')[0].Trim() -NoNewLine -foregroundcolor green;Write-Host ' ' -NoNewLine }
}
Write-Host (Get-Location).Path.Split("\")[-1] -NoNewLine
return "> "
}

Pretty simple, really. To break it apart:

# Modify the prompt function to change the console prompt.
# Save the previous function, to allow restoring it back.
$originalPromptFunction = $function:prompt

Some initial comments to explain what we’re doing, and save the preexisting prompt function into a variable for safekeeping.

# change prompt text
if(Test-Path variable:global:defaultviservers) {
$global:DefaultVIServers | %{ Write-Host $_.Name.Split('.')[0].Trim() -NoNewLine -foregroundcolor green;Write-Host ' ' -NoNewLine }
}

Check if the $global:DefaultVIServers variable is set (this contains all connected vSphere endpoints). If it is, then iterate through each member of the array and print the part of the hostname prior to the first dot in green, then add a space afterward. Don’t append a newline character to the end of the string (by default, Write-Host does).

Write-Host (Get-Location).Path.Split("\")[-1] -NoNewLine
return "> "
}

Finally, print the portion of the current working directory path that is after the last backslash to the screen. Again, no newline. Finish up with the greater-than symbol, for tradition.

You can run this ad-hoc to overwrite the default prompt every time you open a PowerCLI session, but a better way might be to drop it into C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCLIEnvironment_Custom.ps1, which the PowerCLI session setup process runs every time you start it.

Now, the list of vCenter Servers that you are connected to will always be clearly visible. Still, don’t forget that -Server argument…