PowerShell ISE Remote Possibilities

Normally, I think of the PowerShell ISE as a script development tool. I typically don’t think of it as a daily management tool, primarily because everything shares the same scope and if you are running scripts and aren’t careful can sometimes lead to unexpected results. But the ISE feature I really like is the ability to open a new tab with a remote connection to another server. You can even specify alternate credentials.

Normally you can accomplish this by going to File – New Remote PowerShell tab or using the keyboard shortcut Ctrl+Shift+R. But if you want to open multiple remote tabs, say to key servers you want to manage, this gets a little tedious. Or perhaps you’d like to open multiple remote tabs in your PowerShell ISE profile script? We need a better way.

Fortunately, the PowerShell ISE has a scriptable object model. A remote tab is simply another PowerShell tab that has executed Enter-PSSession. Creating a new tab is pretty simple.

Once the tab is open you can use the Invoke() method to run a command in it.

If you need alternate credentials adjust the command. You can even change the tab’s display name.

The new remote tabThe new remote tab (Image Credit: Jeff Hicks)

But there are a few things to watch out for. First, it takes time to open a new tab and you have to wait for it to be ready to invoke commands. You might need to use a short Do loop.

And every time you open a new PowerShell tab, you are opening a new PowerShell session which means your profile scripts run as well. If you are like me, this adds a little overhead that is completely unnecessary since the remote tab won’t be using anything in my profile. So I need a way to open the tab without running any profiles. Fortunately, this can be done, but it is not something exposed in the ISE. But thanks to fellow PowerShell MVP Tobias Weltner, I now have some code that digs into the ISE internals and turns off the option to load profiles.

To re-enable, I can run the last line and set the value to $False.

And of course, I’ve tried to make this easier for you to use by creating a function for the PowerShell ISE called New-ISERemoteTab. You can find the source code on GitHub.

In addition to creating a new remote tab, my function also runs a few commands after the remote connection is established. I prefer a clean slate so I like to at least run Clear-Host. You can invoke commands in the remote tab from new tab object you created.

The other concession I had to make is that if you specify a credential, I have to temporarily export it to disk. Because the new tab is a new PowerShell session there’s no way that I can find to pass variables between session without writing them to disk. But at the end of the process the file is deleted.

Creating a remote tab with credentialCreating a remote tab with credential (Image Credit: Jeff Hicks)

And this is the result:

The new remote tabThe new remote tab (Image Credit: Jeff Hicks)

Feel free to modify the new tab commands. If you specify multiple computers and a credential, the same credential will be used for all connections.

But I also have an option to prompt for credentials. This will not write anything to disk and if you specify multiple computers, you can enter a different credential for different computers. I thought that could come in handy if you need to connect to workgroup-based servers.

The end result is that I can now easily create multiple remote tabs with a single command.

Creating multiple remote tabsCreating multiple remote tabs (Image Credit: Jeff Hicks)

There are a few other examples in command help.

I’ve tried to annotate the function so you can understand how it works but feel free to post questions or problem in GitHub. I’d also like to hear from you in the comments if you find this useful.

Enjoy!

UPDATE: I’m starting to see the benefit of GitHub. Since I published the original earlier today, someone has already improved it and I’ve incorporated those changes into the project.

Get Remote PowerShell Session Connections

magnifying-glass During a recent PowerShell training class we naturally covered PowerShell remoting. During the discussion I explained that a remote PSSession is essentially transparent to any currently logged on user. Unless of course you reboot the computer! One way you can identify a remote session is by the presence of the wsmprovhost process. You should see this process whenever there is a remote PSSession to the computer. So then the discussion turned to tracking who might have sessions across multiple computers which is especially helpful when dealing with disconnected sessions since you can only see your own sessions. I don’t have a perfect solution, but let’s see if this helps. Here is Get-PSRemoteSession.

This function takes a computername as a parameter. It does a quick ping to verify the computer is running. I probably should have made that optional, but I needed it at the time. The function then queries the computer using Get-CimInstance for all instances of the wsmprovhost.exe process. I’m using CIM because datetime values are automatically formatted which makes it much easier to add a custom property indicating how long the process, and presumably the remote session, have been running. I also add a custom property to get the process Owner. Due to a quirk (bug?) in the CIM cmdlets, I can even query a remote computer running PowerShell 2.0. When using a filter, the CIM cmdlets work with a v2 computer. I won’t question it but will take advantage of it.

By default, the function writes a summary object to the pipeline.

get-psremotesession-1

The one thing I have yet to figure out is a way to show what computer each session is connected from. Although even if I could make the correlation with an active network connection, I’m not sure that would help in the event of a disconnected session. Nor can I tell the state of the session from the process.

I included an option to get the full process object so you could run commands like this:

get-psremotesession-2

But I suspect for many of you the summary will suffice. Here are some examples.

get-psremotesession-3

get-psremotesession-4

get-psremotesession-5

If you kill the wsmprovhost process, that will break the PSSession so be careful. But at least now you have a way of identifying what sessions might be open. I hope you’ll let me know what you think. Enjoy!