Tag Archives: WinRM

Determine If There’s a Current PowerShell Remoting Session

Ever need to reboot a server and worry someone else may be actively logged on? In this situation, you can either check Task Manager > Users, or use the quser.exe command-line tool. If you’re not familiar with the command-line tool quser.exe, it can be used against a remote computer, as in the example below.

PS> quser.exe /server DC01
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
 adminbob                                  2  Disc      2+01:17  1/29/2016 8:58 PM

You can use this command-line tool on a local computer, as well, in order to see if anyone else is logged on. All you need to do is enter quser.exe (drop the /server switch [which indicates the remote server to query]), and the remote computer name. Since quser.exe is located in C:\Windows\System32, you don’t even need to include the .exe. The Path variable, $env:PATH, will assist in correctly determining the executable.

The problem is that this command-line tool, and Task Manager, don’t tell us if anyone has a current PowerShell Remoting session to the server. That’s where the Get-WSManInstance cmdlet can help. Here’s an example of using this cmdlet to check our DC01 server — the same server as in the example above.

PS> Get-WSManInstance -ComputerName DC01 -ResourceURI Shell -Enumerate
PS>

Because it didn’t return any information, we can safely assume there are no active PS Remoting sessions on DC01. Had there been, it would have returned something like the results below.

PS> Get-WSManInstance -ComputerName DC01 -ResourceURI Shell -Enumerate

rsp             : http://schemas.microsoft.com/wbem/wsman/1/windows/shell
lang            : en-US
ShellId         : AB4D6A3B-213B-20F6-A61C-9CCAG41A1C2E
Name            : Session1
ResourceUri     : http://schemas.microsoft.com/powershell/Microsoft.PowerShell
Owner           : MYDOMAIN\adminbill
ClientIP        : 10.10.10.20
ProcessId       : 10192
IdleTimeOut     : PT7200.000S
InputStreams    : stdin pr
OutputStreams   : stdout
MaxIdleTimeOut  : PT2147483.647S
Locale          : en-US
DataLocale      : en-US
CompressionMode : XpressCompression
ProfileLoaded   : Yes
Encoding        : UTF8
BufferMode      : Block
State           : Connected
ShellRunTime    : P0DT0H0M6S
ShellInactivity : P0DT0H0M4S
MemoryUsed      : 70MB
ChildProcesses  : 0

The default properties are much more than I need. Here’s a filtered down version of the cmdlet’s properties using the Select-Object cmdlet. In my opinion, these properties are the ones that include the most desirable information.

PS> Get-WSManInstance -ComputerName DC01 -ResourceURI Shell -Enumerate |
>>> Select-Object Name,Owner,ClientIP,State

Name         Owner                  ClientIP        State
----         -----                  --------        -----
Session1     MYDOMAIN\adminbill     10.10.10.20     Connected

It seems I have a difficult time remembering the required parameters in this command; therefore, I wrapped the whole thing in a function and placed it in my profile. This, in order to make sure that I’ll never remember them. My function also allows me to run this command against multiple remote computers at nearly the same time. The -ComputerName parameter of Get-WSManInstance only accepts a single computer per execution, so wrapping this cmdlet in a Foreach construct (within the function), allows us to work around this behavior. Take a look at the function and the example below, as the function runs against three different computers.

Function Get-PSRemotingSession {
    Param(
        [string[]]$ComputerName
    )

    Foreach ($Computer in $ComputerName) {
        Get-WSManInstance -ComputerName $Computer -ResourceURI Shell -Enumerate |
            Select-Object -Property @{N='ComputerName';E={$Computer}},Name,Owner,ClientIP,State
    }
}
PS> Get-PSRemotingSession -ComputerName DC02,WEB01,DC03

ComputerName : DC02
Name         : Session1
Owner        : MYDOMAIN\admindave
ClientIP     : 10.10.10.22
State        : Connected

ComputerName : DC03
Name         : Session1
Owner        : MYDOMAIN\admindave
ClientIP     : 10.10.10.22
State        : Connected

These results indicate that two of the three computers have active PS Remoting sessions. In this case, the two sessions were initiated by MYDOMAIN\admindave. The IP is not the remote computer’s IP, such as DC02 and DC03, but instead the IP from the connecting computer (Dave’s computer).

Keep this cmdlet in mind when you’re doing anything that will restart the WinRM service, to include restarting the server. Restarting this service on a computer where there’s an active PS Remoting session, will instantly break the remoting session.