0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

リモートデスクトップ接続のユーザー情報を取得する

0
Last updated at Posted at 2026-08-16

はじめに

以前に次記事を書きました。

2024年12月からサーバー保全として全国の工場に Windows Server 2022 から順次入れ替え作業を行ないました。今回は工場によっては規模が小さいため、Windows 10 IoT をサーバー代わりに使用したいとなりました。
Windows 10 IoT ではOS制限により、同時に接続できるリモートデスクトップセッションは1台(1ユーザー)のみに固定となっています。
誰かが使用していると奪っていいのか悩んでしまいます。

リモートデスクトップの接続ユーザーを知りたい

前回は、SQLServer の CLR で実装したりしましたが、今回の DB は、PostgreSQL です。
また、Windows 10 IoT 版を作成して社内で公開したところ、NASサーバー版(Windows Server 2022)も欲しいという要望がありました。こちらには DB は何もインストールされていません。

ストアド を使わない方法をネット検索したところ、タスクスケジューラーの下記のトリガー種類が使用できることに気がつきました。

  • ユーザーセッションへの接続時:リモートデスクトップなどでセッションに接続したときに実行します。
  • ユーザーセッションからの切断時:リモートデスクトップなどのセッションから切断したときに実行します。

ユーザーセッションへの接続時

タスクスケジューラーのトリガー種類「ユーザーセッションへの接続時」で下記のPowershellスクリプトを実行させます。

C:¥RDPScripts フォルダを作成して、GetRDPClient.ps1 を配置します。そのフォルダにrdp_client.txt ファイルとしてクライアント名と日時を出力します。

GetRDPClient.ps1
$clientName = ""

$basePath = "HKCU:\Volatile Environment"

if (Test-Path $basePath) {
    Get-ChildItem $basePath -ErrorAction SilentlyContinue | ForEach-Object {
        $value = (Get-ItemProperty $_.PSPath -Name CLIENTNAME -ErrorAction SilentlyContinue).CLIENTNAME

        if ($value -ne $null -and $value.Trim() -ne "" -and $value -ne "Console") {
            $clientName = $value
        }
    }
}

if ($clientName -ne "") {
    $filePath = Join-Path $PSScriptRoot "rdp_client.txt"
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

    "$clientName,$timestamp" | Set-Content -Path $filePath -Encoding UTF8

    Write-Output $clientName
}
else {
    Write-Output ""
}

サーバー扱いなので別に気にしなくてもいいのですが、タスクスケジューラー実行時に PowerShellスクリプト の青い画面を表示させないようにしています。

ユーザーセッションからの切断時

タスクスケジューラーのトリガー種類「ユーザーセッションへの切断時」で下記のバッチを実行して、rdp_client.txt ファイルを削除させます。

RemoveRDPClient.bat
@echo off

set FILE=%~dp0rdp_client.txt

if exist "%FILE%" (
    del /f /q "%FILE%"
)

Web画面で一括表示

PostgreSQLのユーザー関数作成

Windows 10 IoT をサーバー代わりに使用している複数の工場で状態を一覧で見たいため、Web画面を ASP.NET で作成しています。
その時に、PostgreSQLのユーザー関数で rdp_client.txt ファイルを読み込み表示しています。

CREATE OR REPLACE FUNCTION GetRDPClient()
RETURNS TABLE (client_name text, update_time timestamp)
LANGUAGE plpgsql
AS $$
DECLARE
    v_line text;
BEGIN
    v_line := trim(replace(pg_read_file('C:/RDPScripts/rdp_client.txt'), chr(65279), ''));

    IF v_line IS NULL OR v_line = '' THEN
        RETURN;
    END IF;

    RETURN QUERY
    SELECT NULLIF(split_part(v_line, ',', 1), '')::text,
           NULLIF(split_part(v_line, ',', 2), '')::timestamp;

EXCEPTION
    WHEN OTHERS THEN
        RETURN;
END;
$$;

使い方

SELECT * FROM GetRDPClient()

ユーザー名と日時が返ります。

注意

PostgreSQL からファイルを読み込めるようにするため、rdp_client.txt ファイルまたはフォルダに Network Service の読み取り権限が必要です。

ファイルエクスプローラーのプロパティで設定もいいですが、次のバッチで実行できます。

icacls C:\RDPScripts\rdp_client.txt /grant "NT AUTHORITY\NETWORK SERVICE:R"

共有フォルダにアクセス

NASサーバーの場合、DBがインストールされていないため、ユーザー関数は使えません。
Web画面を ASP.NET にて共有フォルダにアクセスして rdp_client.txt ファイルを読むようにしています。
Microsoft Copilot で作成してもらいました。

try
{
    string sharePath = @"\\" + ip + @"\RDPScripts";

    using (new NetworkConnection(sharePath,ip + @$"\{username}", pw))
    {
        string filePath = Path.Combine(sharePath, "rdp_client.txt");

        if (File.Exists(filePath))
        {
            string line = File.ReadAllText(filePath).Trim();

            string[] cols = line.Split(',');

            if (cols.Length >= 2)
            {
                clientName = cols[0];
                logonTime = cols[1];
            }
        }
    }
}
catch (Exception ex)
{
    clientName = "取得失敗";
    logonTime = ex.Message;
}

最後に

最初は、SQLServer の CLR実装と似た方法で模索していたのですが、PostgreSQL からレジストリ値を取得するのは権限設定とか面倒くさい上に、PostgreSQLサービスは通常、NT AUTHORITY\NetworkService や LocalSystem として動作しているので、RDPユーザーのレジストリ(HKCU)にアクセスできなくて値が無しで返ってきてしまうのです。

タスクスケジューラーの「ユーザーセッションへの接続時」と「ユーザーセッションからの切断時」で解決できて良かったです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?