如何关闭孤立的 PowerShell 会话?

如何关闭孤立的 PowerShell 会话?

我正在创建一个在远程服务器上使用多个“Invoke-Command -asjob”的脚本,但在测试 While-Loop 时,它运行不正常,我不得不停止它。但是,当我现在在目标服务器上尝试 Invoke-Command -asjob 时,它返回状态为失败的作业。当我收到作业时,它返回此错误:

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

当我执行 Get-PSSession 时,没有列出任何内容,因此我无法使用 Remove-PSSession(这是 Google 迄今为止唯一的建议)。

它基本上执行了以下操作:

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

我摆脱了它并执行了 Get-Job | Remove-Job 删除了所有作业,但我仍然无法在远程服务器上启动 Invoke-Command -AsJob。

我还重新启动了远程服务器上的 WSMAN 服务(通过使用 RDP 登录),但没有起作用。

答案1

远程工作将在执行程序每个作业一个进程。您应该能够使用 WMI 强制终止这些进程 - 甚至远程重启机器。当然,您冒着终止其他用户/活动托管作业的风险。

这将终止所有执行程序计算机上的进程名称(或计算机名称数组):

(gwmi win32_process -ComputerName $RemoteServer) |? 
    { $_.Name -imatch "wsmprovhost.exe" } |% 
    { $_.Name; $_.Terminate() }

答案2

我知道这篇文章有点老了。@Matthew Wetmore 有一个很好的解决方案来删除全部来自远程服务器的 PSSession。但是,@SuHwak 有一个后续问题,即如何仅停止特定用户生成的会话。

为此,我编写了一个函数来协助。

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
        }
    }
}

并且,使用它......

#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

答案3

简短一点(只要您仍然可以打开至少一个新的 PS 会话)。
这将适用于 PowerShell 7,并且与 WMI 相对应。

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

对于特定用户...

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

相关内容