エンドユーザーがずっと自分のコンピュータにログインしている場合、必要があれば簡単にリモートからエンドユーザーをログオフすることができます。メンテナンスをしようとしているときなどには、知っておくと特に便利です。
長期間ずっと自分のコンピュータにログインしたままのエンドユーザーがときどきいます。メンテナンスを行うとき、エンドユーザーはログアウトする必要がありますが、事前に通知してもログアウトしていないユーザーがいます。ログインしたままアイドル状態になっていることもあります。幸いなことに、他のコンピュータからリモートでエンドユーザーをログオフさせる方法があります。
PowerShell を使って、リモートの Windows コンピュータにアクセスし、誰かがログインしているかどうかを確認し、ログインしている場合はログオフさせるスクリプトを作成できます。全ユーザーをログオフさせることもできます。
まずどのユーザーがリモートコンピュータにログインしているかをチェックするところから始めましょう。いくつかの方法がありますが、ここでは quser コマンドを使います。これは PowerShell のコマンドではありませんが、PowerShell 内から簡単に使用できます。
Windows コンピュータ上でローカルに実行して、このコマンドがどう機能するかを確認できます。
PS> quser
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
>administrator console 1 Active none 9/22/2018 11:04 AM
出力された文字列は PowerShell で解析できるので、あまり気にする必要はありません。
quser コマンドは、/server スイッチを使用してリモートコンピュータにクエリできますが、PowerShell Remoting が使えるので、リモート処理は PowerShell で行い、リモートコンピュータ上で quser を実行します。
PS> Invoke-Command -ComputerName 'REMOTECOMPUTER' -ScriptBlock { quser }
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
abertram rdp-tcp#7 2 Active 7 9/26/2018 4:57 PM
ログインしているユーザーを見つける方法がわかったので、今度はユーザーをログオフする方法を考えましょう。それには logoff コマンドが利用できます。logoff コマンドも PowerShell のコマンドではありませんが、簡単にスクリプトから呼び出せます。
上の例では、セッション2で 'abertram' がリモートコンピュータにログインしています。セッションIDを引数に入れてlogoff コマンドを使えば、簡単にユーザーをログオフできます。
PS> Invoke-Command -ComputerName 'REMOTECOMPUTER' -ScriptBlock { logoff 2 }
リモートコンピュータでもう一度 quser を実行すると、リモートコンピュータには誰もログインしておらず、セッション2がログオフされたことがわかります。
PS> Invoke-Command -ComputerName 'REMOTECOMPUTER' -ScriptBlock {quser}
No User exists for *
+ CategoryInfo : NotSpecified: (No User exists for *:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : REMOTECOMPUTER
セッションIDではなくユーザー名を指定して、ユーザーアカウントをログオフするには、2つのコマンドを1つにまとめます。次のように、quser を実行し、アウトプットをユーザー名でフィルタリングし、そのアウトプットを解析してセッションIDを獲得して、それを logoff コマンドに送るスクリプトブロックを作成します。
$scriptBlock = {
$ErrorActionPreference = 'Stop'
try {
## Find all sessions matching the specified username
$sessions = quser | Where-Object {$_ -match 'abertram'}
## Parse the session IDs from the output
$sessionIds = ($sessions -split ' +')[2]
Write-Host "Found $(@($sessionIds).Count) user login(s) on computer."
## Loop through each session ID and pass each to the logoff command
$sessionIds | ForEach-Object {
Write-Host "Logging off session id [$($_)]..."
logoff $_
}
} catch {
if ($_.Exception.Message -match 'No user exists') {
Write-Host "The user is not logged in."
} else {
throw $_.Exception.Message
}
}
}
## Run the scriptblock's code on the remote computer
PS> Invoke-Command -ComputerName REMOTECOMPUTER -ScriptBlock $scriptBlock
Found 1 user login(s) on computer.
Logging off session id [rdp-tcp#10]...
Invoke-Command で、作成したスクリプトブロックをリモートコンピュータ上で実行すると、ログインしているユーザーを検出し、すぐにログオフします。
Subscribe to get all the news, info and tutorials you need to build better business apps and sites