5

I was creating a script that uses several 'Invoke-Command -asjob' on a remote server, though in testing a While-Loop ran wild and I had to stop it. However, when I now try an Invoke-Command -asjob on the target server it returns the job with state failed. When I Receive the Job it returns with this error:

The WS-Management service cannot process the request. This user has exceeded the maximum number of concurrent shells allowed for this plugin. Close at least one open shell or raise the plugin quota for this user.
+ FullyQualifiedErrorId : -2144108060,PSSessionStateBroken

When I do Get-PSSession, none are listed, so I can't use Remove-PSSession (this is Google's only suggestion so far).

This is what it executed basically:

While ($True)
    { 
    Invoke-Command -Computername $RemoteServer -AsJob {Get-ChildItem}
    }

I broke out of it and did Get-Job | Remove-Job which removed all the jobs, but I still can't start an Invoke-Command -AsJob on the remote server.

I've also restarted the WSMAN Service on the remote server (by logging into it with RDP) which didn't work.

  • Whatever your end goal is, this is not the way to go about it. You can't terminate the sessions as you've tried because they exist in a different OS session ID. However, they will time out on their own eventually. Without getting too indepth and needing to ask you tons of questions to understand what you're really trying to accomplish I can pretty much bet you'll want to try a different approach to your problem. – Colyn1337 Dec 8 '16 at 8:03
  • Yes I purposely left out what I am trying to accomplish, it would be too much to explain. I just want to know, hence the simplification, if I could close those sessions without having to wait for them to time-out. Obviously they have since timed-out and I am able to continue. But for future reference and my education, I'd like to know if its really not possible. One can't connect(?) to the other OS session ID's? – SuHwak Dec 8 '16 at 9:02
4

The remote jobs would run under a wsmprovhost.exe process per job. You should be able to brute force terminate these processes with WMI - or even remotely reboot the machine. You run the risk of killing hosted jobs for other users/activities, of course.

This would terminate all wsmprovhost.exe processes on the computer named (or array of computer names):

(gwmi win32_process -ComputerName $RemoteServer) |? 
    { $_.Name -imatch "wsmprovhost.exe" } |% 
    { $_.Name; $_.Terminate() }
  • Ah, thank you! To only stop the process on the remote server that I spawned. I'm still very much learning PS, so please be kind: $RemoteUserProcesses = Invoke-Command -ComputerName $RemoteServer -ScriptBlock {get-process -IncludeUserName | ?{$_.Name -match "wsmprovhost" -and $_.UserName -match "UserName"}} $RemoteServerProcesses = Get-WmiObject win32_process -ComputerName $RemoteServer foreach ($RemoteUserProces in $RemoteUserProcesses) { Get-WmiObject win32_process -ComputerName $RemoteServer | ?{$_.processid -eq $RemoteUserProces.Id} | %{ $_.Name; $_.Terminate() } } – SuHwak Dec 15 '16 at 14:12
  • 1
    Oh wait, can I actually invoke-command -computername $RemoteServer if I have maxed out my sessions to the $RemoteServer? Probably not so, I guess ignore the above :) But my upvote you have! – SuHwak Dec 15 '16 at 14:18
  • 1
    I was assuming you were already maxxed out on sessions. I'm not 100% certain you'll even be able to do the WMI call, but that should go to the WMI provider host which wouldn't be a dedicated process like the job would have been. – Matthew Wetmore Dec 15 '16 at 17:44
0

I know this post is kinda old. @Matthew Wetmore has a great solution to remove ALL PSSessions from a remote server. But, @SuHwak had a follow on question, of how to stop only sessions that a specific user has spawned.

To that end, I wrote a function to assist.

function Get-PSSessionsForUser
{
    param(
        [string]$ServerName,
        [string]$UserName
    )

    begin {
        if(($UserName -eq $null) -or ($UserName -eq ""))
        { $UserName = [Environment]::UserName }
        if(($ServerName -eq $null) -or ($ServerName -eq ""))
        { $ServerName = [Environment]::MachineName }
    }

    process {
        Get-CimInstance  -ClassName Win32_Process -ComputerName $ServerName | Where-Object { 
            $_.Name -imatch "wsmprovhost.exe"
        } | Where-Object {
            $UserName -eq (Invoke-CimMethod -InputObject $_ -MethodName GetOwner).User
        }
    }
}

And, to use it....

#Get, but do not terminate sessions for the current user, on the local computer.
Get-PSSessionsForUser

#Terminate all sessions for for the current user, on the local computer.
(Get-PSSessionsForUser) | Invoke-CimMethod -MethodName Terminate

<####################################>

#Get, but do not terminate sessions for a specific user, on the local computer.
Get-PSSessionsForUser -UserName "custom_username"

#Terminate all sessions for a specific user, on the local computer.
(Get-PSSessionsForUser -UserName "custom_username") | Invoke-CimMethod -MethodName Terminate

<####################################>

#Get, but do not terminate sessions for the current user, on a remote server.
Get-PSSessionsForUser -ServerName "remote_server"

#Terminate all sessions for the current user, on a remote server.
(Get-PSSessionsForUser -ServerName "remote_server") | Invoke-CimMethod -MethodName Terminate

<####################################>

#Get, but do not terminate sessions for a specific user, on a remote server.
Get-PSSessionsForUser -UserName "custom_username" -ServerName "remote_server"

#Terminate all sessions for a specific user, on a remote server.
(Get-PSSessionsForUser -UserName "custom_username" -ServerName "remote_server") | Invoke-CimMethod -MethodName Terminate

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.