Tocano
Enthusiast
Enthusiast

VI Connections in Multiple Tabs in PowerShellISE possible?

Jump to solution

I like to keep connections to my multiple vCenters in different console windows. I started renaming the console WindowTitle to address the challenge of keeping straight which console is connected to which server. This works, but consoles still lack the functionality and flexibility of the ISE (copy/paste, syntax highlighting, debugging commands, script variables accessible in console, etc). So I started using tabs within the ISE - each tab a different VI server - and I love how much easier and more efficient it is ... except. Every time I switch to a new tab/server, I have to reconnect. Because of the way that ISE manages global scope variables vs consoles, whenever I Connect-VIServer, the other tabs/servers lose their mind and will error with:

You have modified the global:DefaultVIServer and global:DefaultVIServers system variables. This is not allowed. Please reset them to $null and reconnect to the vSphere server.

I believe this has something to do with the difference in scoping between individual PS consoles vs the ISE - though I'm not exactly positive what/why. Global variables do not appear to actually be accessible across tabs, yet Connect-VIServer does appear to break something with regard to the global:DefaultVIServer(s) variables.

So is it even possible to have different connections in different ISE tabs or does the way PowerCLI uses the DefaultVIServers variables make that impossible?

Some things I've tried:

* Setting PowerCLI to run in Multiple Server mode

     - Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Scope AllUsers

* Setting ISE to run in Multi-thread Apartment mode

     - [launching] PowerShell_ISE.exe -mta

Neither appear to work. Any help would be appreciated.

1 Solution

Accepted Solutions
Tocano
Enthusiast
Enthusiast

Just an update to this. I opened a case with VMware who was quite prompt in confirming that this is an issue (though 'bug' may be a misnomer). It is due to the fact that PowerCLI (and specifically the connection manager) are intentionally designed to assume a single 'AppDomain' per PowerCLI instance. This works well most of the time since every individual Powershell console is its own AppDomain. However, ISE uses a single AppDomain for the entire application, even though it creates different runspaces for each PowerShell tab. Because of this, there are collisions between the Powershell tabs in ISE for VIServer connections.

They recommend that if one wishes to use ISE, then do so just for script development. Then either use multiple instances of ISE for different vCenters or actually test/execute the scripts in individual Powershell consoles.

VMware said they will mark this as an issue, though a low-priority one (thus not demanding a patch or updating older versions of PowerCLI), and will seek to rework this area to fix the issue in an upcoming release.

Thank you LucD for helping me confirm this issue.

View solution in original post

10 Replies
LucD
Leadership
Leadership

Did you already check out Jeffery's article PowerShell ISE Remote Possibilities

That might work


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tocano
Enthusiast
Enthusiast

I had not. However, that seems specific to customizing new ISE basic tabs as "Remote tabs" using Remote PSSessions and avoid loading the PS_ISE profile or not. I don't see anything in there that applies to what I'm seeing with the Connect-VIServer or that speaks to global variables - likely because it doesn't appear that the PSSessions use global variables the way PowerCLI uses the global:defaultviserver(s).

I'm currently trying to figure out what - if anything - Connect-VIServer in my current tab changes in the global:defaultviserver(s) variables in another tab. It's a stretch, but we'll see.

But this isn't something strange with my setup right? Others have the same issue?

  1. [Open ISE]
  2. > Connect-VIServer [vCenterServer1]
  3. > $allVMs = Get-VM
    1. Should succeed
  4. ['File' -> 'New Powershell Tab']
  5. > Connect-VIServer [vCenterServer2]
  6. > $allVMs = Get-VM
    1. Should Succeed
  7. [return to Tab 'Powershell 1']
  8. > $allVMs = Get-VM
    1. **ERROR**
0 Kudos
LucD
Leadership
Leadership

That was not what I was trying to point at.

If you open a new tab with $newtab = $psise.powershelltabs.Add(), the new tab will be a new PS session.

As a consequence the $global:defaultViServers there is empty.

You can connect to another vSphere server in the new tab.

Just tested that, and it works without an issue, one tab with a connection to vCenter1 and a second tab with a connection to vCenter2.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tocano
Enthusiast
Enthusiast

Right. As I noted in my original post, it appears that each tab has its own set of global variables. And when I use Connect-VIServer in two different tabs to two different servers, each tab has its own $global:DefaultVIServer variable seemingly set to the appropriate server - as one would expect.

However, as soon as I try to actually execute anything (i.e. Get-VM), the error occurs on the oldest invocation of Connect-VIServer while the newest execution always works just fine.

Just to confirm, when you say you tested this and it all works for you, you did try steps 9 and 10 in my reproduction steps and execute something (i.e. Get-VM) in each tab and those both work, right? You didn't just confirm the values in the $global:DefaultVIServer(s)?

0 Kudos
Tocano
Enthusiast
Enthusiast

Not sure if this is really relevant, but just noticed the following:

In a single PS Console, every Connect-VIServer invocation after the first (to the same server with same credentials), instead of taking 4-5 seconds, takes about 0.1 seconds (measure-command says about 105-110ms). So I assume that this isn't actually reconnecting to the vCenter server and is instead just recognizing that an existing session to that server with those credentials exists and so just returns that object.

In fact, after the first connection, I can completely Remove-Variable the DefaultVIServer(s) variables, rerun the Connect-VIServer, and it still takes only ~100ms. So this makes me think that it's keeping track of server connections elsewhere besides the $global:DefaultVIServer(s) variables.

EDIT: Though I realize I could be wrong and it is actually contacting the vCenter server, who sees an existing session, and maybe just returns that already-built session - just all in lightning fast time.

0 Kudos
LucD
Leadership
Leadership

I see your point.

Did some further testing, the global scope in each ISE tab is not shared.

Easily tested, create a global variable in one ISE tab, it is not visible in the other ISE tabs.

I agree with you that PowerCLI must be getting that connection info from somewhere else, and hence generate that error message.

Which imho is a bad practice.

I tend to consider this a PowerCLI bug, or at least not working as expected from the PS point of view.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tocano
Enthusiast
Enthusiast

Right, certainly odd.

Of course, the next question is why it behaves differently in multiple ISE tabs vs multiple PS Consoles. :smileyconfused:  My guess would be that it has something to do with the fact that (as I understand it) each individual PS console is a completely separate process whereas each ISE tab is (again, I believe) just a different thread within a single ISE process.

I wonder if the Connect-VIServer code has some type of PID lookup/check when a new invocation is executed.

0 Kudos
Tocano
Enthusiast
Enthusiast

Noticed something interesting with this. ISE tabs to not APPEAR to share PSDrives. In tab 1 I can create and access a PSDrive that I cannot (directly) see or access in tab 2. I can also create a PSDrive in tab 2 with the same name as one created in tab 1 with either the same or different mapping. Each tab appears to be completely distinct and separate runspaces for PSDrives - as is consistent with variables, functions, modules, etc.

However, in secondary ISE tabs, when I load the PowerCLI module, I get a small error:

> Import-Module VMware.VimAutomation.Core

The specified mount name 'vmstores' is already in use.

The specified mount name 'vis' is already in use.

>

So I started looking at mount points and PSDrives for the tabs. On tab 1, after importing the VMware module, it lists a few VMware specific PSDrives - Get-PSDrive lists 'vi','vis','vmstore', and 'vmstores'. However, in tab 2, after importing the module (and getting the above referenced errors), looking at Get-PSDrive lists no such PSDrives.


Yet, if I connect to [vCenterServer1] in tab 1 and [vCenterServer2] in tab 2, while the $global:DefaultVIServers in each tab lists only that tab's respective vCenterServer, if I go to tab 1 (where the PSDrives were actually listed) and do a > ls vis: I get BOTH vCenterServers:


> ls vis:

Name                 Type     Id            

----                 ----     --            

[vCenterServer1]@443 VIServer /VIServer=...

[vCenterServer2]@443 VIServer /VIServer=...

So it appears that the VMware module seems to use both a global variable (that is unique per PS tab/runspace) as well as a PSDrive (regardless of PS tab/runspace) that is created via a method that prevents it from being recreated in other runspaces in order to track vCenter Connections.

Could this be using some low-level .Net library to create the mount points and thus is somehow ignoring the PS tab/runspaces?

Let me know if you need more explicit steps/details on this.

0 Kudos
Tocano
Enthusiast
Enthusiast

Just an update to this. I opened a case with VMware who was quite prompt in confirming that this is an issue (though 'bug' may be a misnomer). It is due to the fact that PowerCLI (and specifically the connection manager) are intentionally designed to assume a single 'AppDomain' per PowerCLI instance. This works well most of the time since every individual Powershell console is its own AppDomain. However, ISE uses a single AppDomain for the entire application, even though it creates different runspaces for each PowerShell tab. Because of this, there are collisions between the Powershell tabs in ISE for VIServer connections.

They recommend that if one wishes to use ISE, then do so just for script development. Then either use multiple instances of ISE for different vCenters or actually test/execute the scripts in individual Powershell consoles.

VMware said they will mark this as an issue, though a low-priority one (thus not demanding a patch or updating older versions of PowerCLI), and will seek to rework this area to fix the issue in an upcoming release.

Thank you LucD for helping me confirm this issue.

View solution in original post

LucD
Leadership
Leadership

Thanks for sharing that info.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos