In PowerCLI 5.0.1 a handy feature that showed the connected vSphere Servers in the title bar of the PowerCLI window was apparently removed.
In a PowerCLI Community thread some users found this a useful feature that they would like to have back.
I’m sure the PowerCLI Team will listen to their users and fix this problem in the coming PowerCLI version.
But while we are waiting for a new PowerCLI build that brings back the title bar text, you can fix this for yourself thanks to the proxy cmdlet feature.
Proxy cmdlets is (another) handy feature in PowerShell which allows you to modify and extend existing cmdlets. You can add parameters, change the output and do other crazy things. In the Extending and/or Modifing Commands with Proxies post from Jeffrey Snover you can find all the details.
In that same post you can also find the MetaProgramming module which makes it a breeze to customise cmdlets.
You just call the New-ProxyCommand and redirect the output to a .ps1 file, which you can then use to write your customisations for the cmdlet.
In this case I did that for the Connect-VIServer and Disconnect-VIServer cmdlets as follows
1 2 3 |
New-ProxyCommand Connect-VIServer > .\Connect-VIServer.ps1 New-ProxyCommand Disconnect-VIServer > .\Disconnect-VIServer.ps1 |
The resulting .ps1 files can now be edited to introduce our customisations to these cmdlets.
My Connect-VIServer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
function Connect-VIServer{ [CmdletBinding(DefaultParameterSetName='Default')] param( [Parameter(ParameterSetName='Default', Mandatory=$true, Position=0)] [ValidateNotNullOrEmpty()] [System.String[]] ${Server}, [Parameter(ParameterSetName='Default')] [ValidateNotNull()] [ValidateRange(0, 65535)] [System.Int32] ${Port}, [Parameter(ParameterSetName='Default')] [ValidateSet('http','https')] [System.String] ${Protocol}, [Parameter(ParameterSetName='Default', ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [System.Management.Automation.PSCredential] ${Credential}, [Parameter(ParameterSetName='Default', ValueFromPipeline=$true)] [Alias('Username')] [System.String] ${User}, [Parameter(ParameterSetName='Default')] [System.String] ${Password}, [Parameter(ParameterSetName='Default')] [System.String] ${Session}, [Parameter(ParameterSetName='Default')] [switch] ${NotDefault}, [Parameter(ParameterSetName='Default')] [switch] ${SaveCredentials}, [Parameter(ParameterSetName='Default')] [switch] ${AllLinked}, [Parameter(ParameterSetName='Menu', Mandatory=$true)] [switch] ${Menu}) begin { try { $outBuffer = $null if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) { $PSBoundParameters['OutBuffer'] = 1 } $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Connect-VIServer', [System.Management.Automation.CommandTypes]::Cmdlet) $scriptCmd = {& $wrappedCmd @PSBoundParameters } $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin) $steppablePipeline.Begin($PSCmdlet) } catch { Throw } } process { try { $steppablePipeline.Process($_) } catch { Throw } switch($defaultVIServers.Count){ 0 { $text = "Not Connected" } 1 { $text = "Connected to " + $defaultVIServers[0].Name + " as " + $defaultVIServers[0].User } Default { $text = "Connected to " + $defaultVIServers.Count + " servers: " $text += [string]::Join(',',($defaultVIServers | %{$_.Name})) } } (Get-Host).UI.RawUI.WindowTitle = $text } end { try { $steppablePipeline.End() } catch { Throw } } <# .ForwardHelpTargetName Connect-VIServer .ForwardHelpCategory Cmdlet #> } |
Annotations
Line 1,107: We make this a function
Line 78,90: The code we add to the original cmdlet. This will place the text in the title bar.
My Disconnect-VIServer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
function Disconnect-VIServer{ [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='High')] param( [Parameter(Position=0, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [VMware.VimAutomation.ViCore.Types.V1.VIServer[]] ${Server}, [switch] ${Force}) begin { try { $outBuffer = $null if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) { $PSBoundParameters['OutBuffer'] = 1 } $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Disconnect-VIServer', [System.Management.Automation.CommandTypes]::Cmdlet) $scriptCmd = {& $wrappedCmd @PSBoundParameters } $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin) $steppablePipeline.Begin($PSCmdlet) } catch { Throw } } process { try { $steppablePipeline.Process($_) } catch { Throw } switch($defaultVIServers.Count){ 0 { $text = "Not Connected" } 1 { $text = "Connected to " + $defaultVIServers[0].Name + " as " + $defaultVIServers[0].User } Default { $text = "Connected to " + $defaultVIServers.Count + " servers: " $text += [string]::Join(',',($defaultVIServers | %{$_.Name})) } } (Get-Host).UI.RawUI.WindowTitle = $text } end { try { $steppablePipeline.End() } catch { Throw } } <# .ForwardHelpTargetName Disconnect-VIServer .ForwardHelpCategory Cmdlet #> } |
Annotations
Line 1,65: We make this a function
Line 36,48: The code we add to the original cmdlet. This will place the text in the title bar.
Usage samples
First you will need to dot-source the .ps1 files with the customised versions of both cmdlets.
1 2 3 |
. ./Connect-VIServer.ps1 . ./Disconnect-VIServer.ps1 |
We now have a function and a cmdlet for both.
1 2 3 |
Get-Command Connect-VIServer Get-Command Disconnect-VIServer |
But PowerShell will use a function before a cmdlet when both have the same name. Exactly what we need !
If you want to learn more about these precedences, do a
1 |
Get-Help About_command_precendence |
Now we are ready to use our customised cmdlets. When we do a first connect
1 |
$vc = Connect-VIServer -Server MyVC |
the PowerCLI window will show
When we connect an additional vSphere Server
1 |
$esx = Connect-VIServer -Server MyEsx1 -User root -Password MyPswd |
the PowerCLI window will show.
When we disconnect from one of the vSphere Servers, the title bar will be updated as well.
1 |
Disconnect-VIServer -Server $vc |
The title bar will show
There are of a couple of open problems
- The initial PowerCLI window shows “Not connected“. This could eventually be solved by adapting the PowerCLI initialisation script, but I didn’t want to change that script
- The Disconnect-VIServer cmdlet also accepts a [string] for the Server argument. The proxy cmdlet doesn’t accept that, you will have to give it a VIServer object on the Server parameter.
Enjoy !