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.

2
  • 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, 2016 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, 2016 at 9:02

3 Answers 3

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() }
3
  • 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, 2016 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, 2016 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. Dec 15, 2016 at 17:44
1

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
0

A short one (as long as you can still open at least one new PS-session).
This will work with PowerShell 7 as well as opposed to WMI.

Invoke-Command -ComputerName $RemoteServer {
    Get-Process wsmprovhost -IncludeUserName | Stop-Process -Force
}

And for a specific user...

Invoke-Command -ComputerName $RemoteServer {
    Get-Process wsmprovhost -IncludeUserName | Where UserName -like '*\USER' | Stop-Process -Force
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .