実稼働環境でターミナルサーバーユーザーをログオフ、切断、またはリセットできない


19

2008 Terminal Serverでユーザーのセッションを切断、ログオフ、またはリセットする方法に関するアイデアを探しています(完全にロックされているため、ユーザーとしてログインできません)。これは実稼働環境であるため、今のところサーバーを再起動するか、システム全体で何かを行うことは問題外です。これに役立つPowershellのトリックはありますか?

同じターミナルサーバー(タスクマネージャー、ターミナルサービスマネージャー、リソースモニターから)から直接接続を切断し、ユーザーをログオフしてセッションをリセットし、セッションのプロセスも強制終了しましたが、結果はありませんでした。

助けて!


更新:考えられる他の試みが機能しなかったため、サーバーを再起動しました。誰かがこの1つの問題についてより多くの情報を持っていることを期待して、この質問を公開したままにします。


2
Windows 2008 R2 SP1ターミナルサーバーでもまったく同じ問題が発生します。それらはランダムにハングし、ユーザーはサーバーからログオフまたはログオンできません。ローカル管理者またはドメイン管理者としてローカルにログオンできません。サーバーに接続する唯一の方法はcompmgmt.mscを使用することですが、ここでもイベントログに問題は表示されません。ある段階で、IMAサービスが応答せず、サーバーがファームから削除されたというメッセージが表示されます。これを解決する唯一の方法は、サーバーをハード再起動することです。電源をオフにしてから再びオンにします。私はこの原因を何にも絞ることができませんでした



1
今後この問題が発生した場合に役立つリンクの可能性
JohnLBevan 14

回答:


7

この同じ問題を解決するために働いたのは、ロックされたアカウントの下で実行されているすべてのプロセスをタスクマネージャーの下から強制終了することで、そのアカウントを(管理者アカウントから)簡単にログオフできました。

その後、ユーザーはアカウントでログオンし直すことができました。

再起動は不要で、サードパーティのソフトウェアをダウンロードする必要もありませんでした。


-ありがとう、サーバーの再起動から私を救った!セッションが1つスタックしているため、実際に平日の間に全員を追い出したくありませんでした。
MAW74656

これらのプロセスを強制終了しても安全ですか?私のユーザーが持っているcsrss.exedwm.exeLoginUI.exe、とwinlogon.exe。殺すwinlogon.exeとBSODが誘発されると思った…
ビンキ

6

サーバーを再起動する必要なく、アカウントのリセット方法を共有したい。まず、サーバーへの管理者アクセス権が必要です。次のログオンオプションを使用します。サーバーにアクセスするには、mstsc / v:servername / console / adminを使用します。次に、「Windows Taks Manager」で「ユーザー」タブに移動し、「ログオフ」するアカウントを右クリックして、ログオフを選択します。これにより、そのアカウントで使用されていたロックされたセッションが解放されます。


1
常にそうとは限りません。加えて、OPはすでにこれを試していると述べた。
BeowulfNode42

この問題の場合、[タスクマネージャー]→[ユーザー]の[サインアウト]ボタンは何もしません。
ビンキ

5

簡単な答えは、昇格したコマンドプロンプトを実行して「Taskmgr」と入力すると、[ユーザー]タブでセッションをログオフできるようになることです。昇格したセッションに参加しないと機能しません。


テスト済みで、そのソリューションは機能しました。
オーバーマインド

1
私ではありません。また、管理者としてtaskmanagerを使用してユーザーのプロセスを強制終了することもできません。
BeowulfNode42

3

cmdを起動し、クエリセッションを実行し、強制終了するセッションのIDを確認してから、セッションをリセットします。たとえば、クエリセッションで rdp-tcp#1というセッション名を削除したい場合、リセットセッションrdp-tcp#1を実行して強制終了できます。


ありがとう、でもそれも助けにはならなかった。
l0c0b0x

reset session 9そのコマンドを実行すると、ハングします。:私のセッションがアクティブであると表示されることなく、実行中の4つのプロセスを持ち続けcrss.exedwm.exeLogonUI.exe、とwinlogon.exei.imgur.com/cFM62RA.pngおよびquery session 9出力No User exists for 9
ビンキ

3

Win2008R2ターミナルサーバーでも同じことが今日起こったと思います。Sympthomsは次のとおりです。1.彼は「「接続」メッセージが永遠にハングする」と私に電話しました。彼は単純なユーザーなので、詳細な問題の説明は期待できません。2.セッションのログオフ/リセットを試みました(通常、このような場合に役立ちます)-動作しませんでした。セッションは、引き続き「切断」ステータスのリストでハングします。3.そのユーザーのすべてのプロセスを強制終了しました-助けにはなりませんでした。セッションは持続し、強制終了を拒否します。

解決策は、ユーザーとして接続し(パスワードをリセットするか、何らかのリモートアシスタンスを使用してコンピューターで何が起こるかを確認できる場合は資格情報でログインする)、ログオンウィンドウで何が起こるかを確認することです。接続すると、RDPクライアントの「詳細」ボタンをクリックしました-ここでは、winlogonが何か間違っていたというエラーメッセージが表示され、ユーザーが「再試行/無視/など」ボタンをクリックするのを待っていましたそのすべての奇妙な動作。

ps私は本当にセッションを強制終了する方法を見つけることができませんでした:(


これは私のためにそれを修正しました!ユーザーが別のユーザーを切断するかキャンセルを選択するのを待っていました。キャンセルをクリックすると、タスクマネージャの[ユーザー]タブに残っていたユーザーが消えました。ありがとう!
ビンキ

これが問題だったときの私の状況は次のとおり です 。i.imgur.com / W6eO5wW.png i.imgur.com/EpPwyJc.png i.imgur.com/cFM62RA.pngまた、Windows Server 2016を使用しています
ビンキ

3

Windows Server 2008 R2リモートデスクトップサーバーでも同様の問題が発生しました。ユーザーセッションは、RDSマネージャーを表示したときに「アクティブ」と表示されましたが、関連付けられたセッションID#または接続されたデバイスは表示されませんでした(両方とも空白でした)。

上記のトリックはすべて、問題を解決しませんでした。問題のユーザーとして接続すると、ターミナルサーバーがビジーであり、後で再試行するか管理者に連絡することを示すエラーメッセージが返されました。

サーバーも再起動しました。


2

Windows Server 2016でも同じ問題が発生しました。ユーザーはログインできませんでした。

そこで、次の手順を試して、孤立したセッションを切断しました。

  1. CLIのqwinstaには、使用可能なすべてのセッション(非アクティブセッションとアクティブセッション)が一覧表示されますが、ユーザー名ではなくセッションIDのない切断セッション(スクリーンショットでは「getr」と呼ばれます)が1つあります

アクティブなセッションを表示して強制終了する

  1. セッションID(7)が1の場合。セッション7をリセットしてこのセッションを強制終了しようとしました(fyi:rwinstaはリセットセッションのエイリアスです)。

  2. 1つのセッションで機能しましたが、次回は効果がなかったため、タスクマネージャーとユーザータブを開きました。すべてのリモートデスクトップユーザーに1つの展開可能なリストが割り当てられています。1つのリストにはユーザー名がなく、実行中のタスクは4つしか表示されていません。

  3. 私は明白なものを試しました:ユーザーをログオフします。効果なし。

ユーザーをログオフしようとしています

  1. そこで、このユーザーに割り当てられたこれらの4つのタスクを終了しようとしました。いくつかのタスク、最も重要なのはcsrss.exeを強制終了すると、システムの再起動が発生するため、注意してください。私はそれらをスキップし、明らかなRDPタスクをいくつか殺しました。

Step / Try 4の後、最後にクラッシュしたセッションも強制終了され、ユーザーは再度ログインできました

  1. それでも機能しない場合は、別の質問からこの解決策を試してください。RDPクライアントに接続するときに、[詳細]ボタンをクリックします。そこでエラーが表示されるはずです。再試行または無視をクリックすることもできます。

どのプロセスを強制終了し、どのプロセスを強制終了しないかについて、より具体的に説明できますか?私はスキップすべきだと思うwinlogon.exeが、のような他の人が不明だLoginUI.execsrss.exedwm.exe
ビンキ

2番目のセッションの症状は、私のものとserverfault.com/a/176080/164429に似ています。おそらく、より完全なソリューションを試すためのステップとして「接続」を追加し、プロセスを強制終了する必要を回避することもできます。
ビンキ

@binkiは "csrss.exe"である必要があります-このプロセスを強制終了すると、システムが再起動します。
nr

1

ユーザーがAlt + Tabを使用してリモートデスクトップウィンドウの背後に隠された資格情報ポップアップボックスを持っていないことを確認する価値があります。

同僚が同じ問題を抱えていました。ログオフまたはリセットできず、彼のプロセスはすべて手動でシャットダウンされました。FROMをリモート処理しているシステムのGUIにアクセスしようとすると、リモートセッションの背後に隠れている資格情報ボックスが見つかりました。


1

私も同じ状況です。リモートデスクトップサービスを備えたWindows Server 2008 R2、セッションが非アクティブまたは3時間切断された後にユーザーをログオフするようにRDP接続が設定され、一部のセッションはロックされたままです。リモートデスクトップマネージャーとqwinsta / quserの両方でログオフしようとしましたが、成功しませんでした。

ここに私がそれを解決した方法があります:

  1. セッションIDを見つけましたqwinsta
  2. winlogon.exeのハングセッションのPIDを特定しましたquery process /ID:yourid
  3. でプロセスを終了しましたtaskkill /f /PID yourPID

行く方法。そうでなければ、これが起こらないための解決策を見つけたいです。


1

私のために働いたのは:

  • サーバーにログオンする
  • タスクマネージャーを開く
  • ユーザータブでユーザーを探します
  • 右クリックして接続し、ユーザーのパスワードを入力すると、「しばらくお待ちください」画面が表示されました
  • alt-tabを押すと、サーバーからログオフされ、ユーザーもログオフされます

1

ロックされたリモートデスクトップアプリケーションユーザーでこの問題が発生しました。このPowershellスクリプトは、スケジュールされたタスクで実行して、2分以上切断されていると表示されたユーザーをログオフするように作成しました。必要な編集は、リモートデスクトップブローカーサーバーを除外するように設定したSERVERNAMEだけですが、任意のサーバーを除外することも、まったく除外することもできません。

ちなみに、私のスクリプトはWindows Server 2012 R2用に書かれています...

スクリプトはこれを行います:

  • すべてのリモートデスクトップユーザーセッションのリストを取得します。
  • 「STATE_DISCONNECTED」と言わないセッションを無視します。
  • Broker Server(または他のサーバー)を無視します
  • 統合セッションIDのないセッションを無視します
  • 切断時間がないセッションは無視します
  • 切断時間のあるセッションでは、現在の時間をチェックし、現在と切断時間の時間差がX分(この場合は2)を超える場合、winlogonプロセスを強制終了します。
  • また、ログオフコマンドを発行しようとします(これは、winlogonプロセスが強制終了された後に失敗する可能性が高いです)。

わたしにはできる!私はそれが他の誰かを助けることを願っています!:)

CLS
$RD = Get-RDUserSession | select ServerName, UserName, SessionState, DisconnectTime, UnifiedSessionId, SessionId #Get details about the sessions
foreach ($item in $RD) {
    $UsessionID = $item.UnifiedSessionId -as [int] 
    $sessionID = $item.SessionId -as [int] 
    if ($item.SessionState -eq "STATE_DISCONNECTED" -and $item.ServerName -ne "SERVERNAME" -and $item.DisconnectTime -ne $null -and $item.UnifiedSessionId -ne $null){
        $TimeDiff = New-TimeSpan -start $item.DisconnectTime -end (Get-Date) #check time difference between disconnect time and now. If time is greater than 2 minutes....
        if ($TimeDiff.Minutes -gt 2) {
            #Kill winlogon session for the user
            Get-WmiObject -ComputerName $item.Servername -query "select * from win32_process where name='winlogon.exe'" | Where-Object {$_.SessionId -eq $SessionId} | %{$_.terminate()}
            #Log off user if session still exists (will fail if user kicked)
            Invoke-RDUserLogoff -HostServer $item.ServerName -UnifiedSessionID $UsessionID -Force -erroraction 'silentlycontinue'
            }
         }
      }

または、画面で何が起こっているかを見ることができるバージョンを好む場合:

 CLS
    $RD = Get-RDUserSession | select ServerName, UserName, SessionState, DisconnectTime, UnifiedSessionId, SessionId
    foreach ($item in $RD) {
        $UsessionID = $item.UnifiedSessionId -as [int]
        $sessionID = $item.SessionId -as [int]
        if ($item.SessionState -eq "STATE_DISCONNECTED" -and $item.ServerName -ne "SERVERNAME" -and $item.DisconnectTime -ne $null -and $item.UnifiedSessionId -ne $null){
            #On Screen Output
            write-host " Name : " $Item.UserName -ForegroundColor "yellow" -NoNewline
            write-host " Unified Session Id : " $UsessionID -ForegroundColor "darkcyan" -NoNewline
            write-host " User Session Id : " $sessionID -ForegroundColor "darkyellow" -NoNewline
            write-host " Session State : " $item.SessionState -ForegroundColor "magenta" -NoNewline
            write-host " Server : " $item.ServerName -ForegroundColor "cyan" -NoNewline
            write-host " Disconnect Time : " $item.DisconnectTime -ForegroundColor "gray" 
            #End On Screen Output
            $TimeDiff = New-TimeSpan -start $item.DisconnectTime -end (Get-Date)
            if ($TimeDiff.Minutes -lt 2) {
                write-host " Disconnected for less than 2 minutes" -ForegroundColor "Green"}
            else {
                write-host " Disconnected for more than 2 minutes" -ForegroundColor "Red" -BackgroundColor "darkyellow"
                write-host " Killing session : " $item.ServerName " ID : " $UsessionID $item.UserName -ForegroundColor "Red"
                #Kill Process "Winlogon.exe" for the user (this should kill the session)
                Get-WmiObject -ComputerName $item.Servername -query "select * from win32_process where name='winlogon.exe'" | Where-Object {$_.SessionId -eq $SessionId} | %{$_.terminate()}
                #Logout User (if session still exists)
                Invoke-RDUserLogoff -HostServer $item.ServerName -UnifiedSessionID $UsessionID -Force -erroraction 'silentlycontinue'
                Write-host " Done! " -ForegroundColor "Green" -BackgroundColor "blue"
                }
             }
          }

1

メモ帳でファイルを作成し、findsession.cmdと呼びます。コマンドQuery Session / server:servername |を配置します。/ i "%1"を見つけて、ディレクトリに保存します。resetsession.cmdという別のファイルを作成し、コマンドReset Session%1 / server:%2を入力して保存します。

コマンドプロンプトから、これらのファイルを保存したディレクトリに移動し、findsessionユーザー名(検索しようとしているユーザーのログイン)を入力します。Enterキーを押すと、ログインとセッションIDが表示されます。resetsession.cmd ID Servernameと入力すると、そのセッションがリセットされます。私はこれを毎日使用していますが、ユーザーを見つけてセッションをリセットするには非常に高速です。


テキストの書式設定オプションを使用してコマンドを強調し、読みやすくしてください。それは良い答えですが、編集してください。
マルコ

コマンドが非常に短く、とにかくそれらに引数を渡す必要がある場合、バッチファイルを
記述する意味はありませ

1
  1. でセッションIDを見つけますqwinsta
  2. taskkill /FI "SESSION eq 1" /Fqwinstaから返される終了したいセッションIDが1であると仮定して、セッション下のすべてのプロセスを強制終了します。

これはServer 2012バージョン6.2ビルド9200で機能しましたが、すべてのバージョンのWindowsで機能すると期待しています。


1

このpower-shellスクリプトは、私にとってはうまくいきました。すてきなログファイルも提供します。ここから入手しました。:他の回答には多くの前提条件があり、私には役に立たなかったため、これが他の人の助けになることを願っています。

    # .SYNOPSIS
    #   Checks for disconnected sessions and logs off the disconnected user sessions.

    #.DESCRIPTION
    #   Checks for disconnected sessions and logs off the disconnected user sessions.

    #.NOTES
    #   File Name: Logoff-DisconnectedSession.ps1
    #   Author   : Bart Kuppens
    #   Version  : 1.1

    #.EXAMPLE
    #   PS > .\Logoff-DisconnectedSession.ps1


    function Ensure-LogFilePath([string]$LogFilePath)
    {
     if (!(Test-Path -Path $LogFilePath)) {New-Item $LogFilePath -ItemType directory >> $null}
    }

    function Write-Log([string]$message)
    {
       Out-File -InputObject $message -FilePath $LogFile -Append
    }

    function Get-Sessions
    {
       $queryResults = query session
       $starters = New-Object psobject -Property @{"SessionName" = 0; "UserName" = 0; "ID" = 0; "State" = 0; "Type" = 0; "Device" = 0;}
       foreach ($result in $queryResults)
       {
          try
          {
             if($result.trim().substring(0, $result.trim().indexof(" ")) -eq "SESSIONNAME")
             {
                $starters.UserName = $result.indexof("USERNAME");
                $starters.ID = $result.indexof("ID");
                $starters.State = $result.indexof("STATE");
                $starters.Type = $result.indexof("TYPE");
                $starters.Device = $result.indexof("DEVICE");
                continue;
             }

             New-Object psobject -Property @{
                "SessionName" = $result.trim().substring(0, $result.trim().indexof(" ")).trim(">");
                "Username" = $result.Substring($starters.Username, $result.IndexOf(" ", $starters.Username) - $starters.Username);
                "ID" = $result.Substring($result.IndexOf(" ", $starters.Username), $starters.ID - $result.IndexOf(" ", $starters.Username) + 2).trim();
                "State" = $result.Substring($starters.State, $result.IndexOf(" ", $starters.State)-$starters.State).trim();
                "Type" = $result.Substring($starters.Type, $starters.Device - $starters.Type).trim();
                "Device" = $result.Substring($starters.Device).trim()
             }
          } 
          catch 
          {
             $e = $_;
             Write-Log "ERROR: " + $e.PSMessageDetails
          }
       }
    }

    Ensure-LogFilePath($ENV:LOCALAPPDATA + "\DisconnectedSessions")
    $LogFile = $ENV:LOCALAPPDATA + "\DisconnectedSessions\" + "sessions_" + $([DateTime]::Now.ToString('yyyyMMdd')) + ".log"

    [string]$IncludeStates = '^(Disc)$'
    Write-Log -Message "Disconnected Sessions CleanUp"
    Write-Log -Message "============================="
    $DisconnectedSessions = Get-Sessions | ? {$_.State -match $IncludeStates -and $_.UserName -ne ""} | Select ID, UserName
    Write-Log -Message "Logged off sessions"
    Write-Log -Message "-------------------"
    foreach ($session in $DisconnectedSessions)
    {
       logoff $session.ID
       Write-Log -Message $session.Username
    }
    Write-Log -Message " "
    Write-Log -Message "Finished"  

編集:
私はもともとこのスクリプトを使用して、すべての「切断された」セッションをログオフして閉じました。多くのユーザーと制限付きライセンスを持つターミナルサーバーアプリケーションがいくつかあります。切断されたセッションは非常に長い間開いたままになり、場合によっては無期限に開いたままになることがありました。その結果、未使用のセッションがライセンスの一部を占有し、結果として他のユーザーが接続できなくなりました。

  • スケジュールされたタスクを使用してスクリプトを実行し、
    一部のサーバー上のセッションを定期的にチェックおよび切断します。
    対話を必要とせずに自律的に動作します。
  • Windows 2008 R2 ServerおよびWindows 2012 R2 Serverオペレーティングシステムで使用します。
  • 切断されたセッションのみを閉じます。
  • 切断したユーザーまたはセッションで「ログ」ファイルを更新します。

それが何をするのか説明してもらえますか?
コンラッドガジェウスキ

1
こんにちはコンラッド、答えを少し編集し、スクリプトが何をするのかを説明してくれることを願っています。基本的に、スクリプトは、リモートユーザーがサーバーから切断した後も開いたままであるすべての切断されたセッションを閉じます。
9953-div-37

0

まだ実行中のプロセスがあり、ログオフプロセスをブロックしている可能性があります。影響を受けるユーザーのまだ実行中のプロセスを確認します。次に、プロセスを1つずつ強制終了して、1つが問題を引き起こしていることを確認します。

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run必要なプロセスのみが開始されるレジストリキーも確認してください。64ビットではHKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run


0

Microsoftから「Process Explorer」ツールをダウンロードし、それを使用して問題を解決できます。セッションIDがある場合は、それぞれのプロセスを見つけることができます。その後、ユーザーセッションが切断された場合、Process Explorerを使用してプロセスを強制終了できます。


0

まったく同じ環境(2012r2があります)ではありませんが、Hyper-V仮想マシン管理サービス(VMMS)を再起動すると接続が解放されました。


0

プロセスをクリックして、すべてのユーザーからプロセスを表示する必要があります。その後、切断できます。

リモートデスクトップセッションホストの構成の下でセッションポリシーを作成しないのは、特定の間隔の後、切断されたセッションまたはアイドルセッションです。


0

私の修正:コンピューター管理ツールを介して問題のサーバーに接続した別のネットワークサーバーで、開いているセッションですべての開いているファイルを右クリックして閉じ、mstscを介して接続できました


0

あなたは常にローカルマシンからpowershellを使用し、リモートでそれを行うことができます

Invoke-command -computername <servername> -Credential (get-credential) { 
    $session = ((quser | ? { $_ -match <username> }) -split ' +' )[2]
    logoff $session
} 

回答をさらに便利にするために、このコマンドがどのように機能するかの基本的な説明を提供すると役立ちます。誰もがPowerShellを十分に理解しているわけではありません。貢献してくれてありがとう。
私は

-1

残念ながら。ユーザーセッションが切断されました。タスクマネージャーは、ユーザーとして実行されているプロセスを表示しませんでした。ユーザーをタスクマネージャーからログオフできませんでした。セッションIDのリセットコマンドを試してみましたが、同様にフリーズしました。管理者として別のセッションでログインし、アカウントを削除して新しいアカウントを再作成する必要がありました。


-1

リモートデスクトップサービスマネージャーからユーザーをログオフしようとしましたか?[管理ツール]-> [リモートデスクトップサービス]-> [リモートデスクトップサービスマネージャー]に移動し、セッションからログオフします。うまくいくかもしれません。


-1

開始ウィンドウに移動し、名前をクリックします

こちらのサンプルをご覧ください


私は、これは(というより詳述されているほとんどが)ここでは他の回答のいくつかの繰り返しだと思う-例えばserverfault.com/a/804638/402709。何らかの文脈とあなた自身の経験でそれを拡大することはあなたの答え改善するのに役立つかもしれません。
iwaseatenbyagrue

そうは思いませんが、楽しんでください。
syb
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.