Active Directory休眠アカウントの棚卸しをClaudeで進める手順
ADの出力CSVと人事の在籍名簿をClaudeに突合させ、休眠・退職済み残存・共有アカウント候補に分ける手順。無効化は人が決める線引きと、氏名を渡さないCSVの作り方も示します。
Active Directoryの休眠アカウントは、ADの出力CSVと人事の在籍名簿をClaudeに突合させると、確認すべき行だけが絞れます。ただし、Claudeが出すのは「無効化の候補と根拠」までです。無効化の実行は、人が候補を見て決めます。
この記事では、CSVの出し方、氏名を渡さずに突合する下ごしらえ、プロンプト、結果の検算、無効化に進む前の線引きを順に説明します。ADとの接続やSSOの設定は扱いません。手元のCSVを読ませるだけの、閉じた作業です。
休眠アカウントの棚卸しで、Claudeに任せる範囲
棚卸しの作業は、大きく3つに分かれます。
棚卸しの流れ
- 1
ADからCSVを出す
休眠の一次判定はAD側のコマンドで済ませます。
- 2
在籍名簿と突合する
ここがClaudeの出番です。行数が多く、複数の列を組み合わせて分類する作業です。
- 3
無効化する人を決める
候補の根拠を見て、システム管理者と人事が決めます。
突合をClaudeに頼むのは、人手だと次の点でつらいからです。在籍区分・退職日・パスワード失効の設定といった複数の列を組み合わせて、数百行を1行ずつ分類し、根拠まで書く必要があります。さらに、休職者・出向者・共有アカウントのように「古いが消してはいけない」行が混ざります。なお、ADと名簿で氏名の表記が違う問題は、Claudeに渡す前に手元で名寄せします。
一方で、無効化の判断は渡しません。理由は単純で、最終ログオンが古いことと、不要であることは別だからです。年1回しか使わない決算用のアカウントも、90日以上ログオンがありません。
手順1: Search-ADAccountで休眠候補のCSVを出す
休眠アカウントの一次抽出には、Active Directoryモジュールの Search-ADAccount コマンドレットを使います。-AccountInactive を付けると、指定した期間または日時以降にログオンしていないアカウントを返します。期間は -TimeSpan、特定の日時は -DateTime で指定します。
Search-ADAccount -AccountInactive -UsersOnly `
-TimeSpan 90.00:00:00 |
Select-Object SamAccountName, Enabled, LastLogonDate, `
PasswordNeverExpires, DistinguishedName |
Export-Csv ad_inactive.csv -NoTypeInformation -Encoding UTF8-TimeSpan の書式は [-]D.H:M:S.F です。90日なら 90.00:00:00 と書きます。-UsersOnly を付けると、コンピューターアカウントは対象外になります。コンピューターの棚卸しをしたい場合は、-ComputersOnly で別に出すと列が混ざりません。
Select-Objectで出す列は、環境に合わせて調整してください。最終ログオンの列名は、取得方法によって LastLogonDate や lastLogonTimestamp になります。列名は、出力したCSVの1行目で確かめます。
最終ログオンの値には、同期間隔ぶんのずれがある
lastLogonTimestamp は、ユーザーがドメインにログオンするたびに更新されるわけではありません。ログオン時に属性を読み、値が「現在時刻から msDS-LogonTimeSyncInterval を引いた時刻」より古い場合にだけ更新されます。ドメイン機能レベルを上げた直後の最初の更新は、14日から、5日を上限とするランダムな割合を引いた日数で計算されます。
つまり、この値は同期間隔ぶん古いことがあります。更新が起きる最初の基準は、14日から最大5日ぶんの割合を引いた日数ですから、実際のログオンより二週間弱前の値が残る場面があります。「30日ログオンなし」のような短い閾値で切ると、実際にはログオンしている人が候補に入ります。90日以上など、同期間隔より十分長い期間で抽出するのが安全です。
もう1つ、-AccountInactive は、ドメインがWindows Server 2003のドメイン機能レベル以上のときだけ使えます。それより古いレベルのドメインでは動きません。
共有・サービスアカウントの手がかりも同じCSVに載せる
先ほどの例には PasswordNeverExpires の列を入れました。パスワードが失効しない設定のアカウントは、共有アカウントやサービスアカウントである可能性があります。Search-ADAccount -PasswordNeverExpires で別に抽出しても構いません。この列は断定の材料ではなく、Claudeが「共有アカウント候補」を挙げるときの根拠の1つとして使います。
手順2: 氏名を渡さずに突合できるCSVへ加工する
ここが、この作業で一番気を使う箇所です。ADの出力にはログオン名や所属のOUが、人事名簿には氏名や退職日が含まれます。突合に氏名そのものは要りません。両方に入っている共通のキーがあれば足ります。
この手順は、人事名簿に SamAccountName の列があるか、社員番号とAD側の属性(employeeID など)が対応している前提です。表記ゆれで共通のキーが無い場合は、先に手元で名寄せして SamAccountName の列を名簿に足します。氏名の突き合わせは、Claudeへ渡す前の工程です。
Claudeへ渡す前に、次の3点を済ませます。
- 氏名・メールアドレス・電話番号などの列を落とす
- 突合のキーになる
SamAccountNameを、ADと名簿の両方で同じ連番のIDに置き換える - 置き換えの対応表は、手元に残してアップロードしない
PowerShellでの置き換え例を示します。名簿は roster.csv で、SamAccountName・在籍区分・退職日の列があるものとします。
$ad = Import-Csv ad_inactive.csv
$roster = Import-Csv roster.csv
# 両方のキーを集めて、重複なしで連番を振る
$keys = @($ad.SamAccountName) + @($roster.SamAccountName) |
Sort-Object -Unique
$i = 0
$map = @{}
foreach ($k in $keys) { $i++; $map[$k] = 'U{0:0000}' -f $i }
# 対応表は手元にだけ残す
$map.GetEnumerator() |
Select-Object @{n='Id';e={$_.Value}}, @{n='SamAccountName';e={$_.Key}} |
Export-Csv id_map_LOCAL.csv -NoTypeInformation
# アップロード用: キーをIdに置き換え、氏名などの列は出さない
$ad | Select-Object @{n='Id';e={$map[$_.SamAccountName]}}, Enabled,
LastLogonDate, PasswordNeverExpires |
Export-Csv ad_inactive_anon.csv -NoTypeInformation -Encoding UTF8
$roster | Select-Object @{n='Id';e={$map[$_.SamAccountName]}},
在籍区分, 退職日 |
Export-Csv roster_anon.csv -NoTypeInformation -Encoding UTF8id_map_LOCAL.csv は手元に置いたままにします。アップロードするのは ad_inactive_anon.csv と roster_anon.csv の2つだけです。連番化しても、元の表と照らせば個人が分かります。連番化したCSVも、個人情報に準じて扱います。
アップロードできるファイルの条件
CSVは、Claudeにアップロードできる文書形式の1つです。ヘルプセンターの「Upload files to Claude」では、チャットへのアップロードが1ファイル500MBまで、1チャットあたり最大20ファイルと案内されています。Projectのファイルは1ファイル30MBまでで、内容全体がClaudeのコンテキストウィンドウに収まる必要があります。
Excel(XLSX)で名簿を持っている場合は注意が必要です。XLSXのアップロードには、アカウントでコード実行とファイル作成を有効にしておく条件があります。条件を満たさないなら、名簿をCSVに書き出してから渡すのが手っ取り早い方法です。
また、PDFを除く文書は、テキストだけが抽出されます。名簿の備考欄に画像が貼ってあっても、Claudeには読めません。
手順3: 3種類の候補に分けるプロンプト
CSVの用意ができたら、2つのファイルを添付して依頼します。出力の形を先に決めておくと、後の検算が楽になります。
添付の2つのCSVを突合してください。
- ad_inactive_anon.csv: ADの休眠候補(90日以上ログオンなし)
- roster_anon.csv: 人事の在籍名簿(Id, 在籍区分, 退職日)。照合用です
ad_inactive_anon.csv の各行を、次の4分類のどれか1つに入れてください。
roster_anon.csv にだけある Id は、分類せず出力にも含めないでください。
A 休眠: 名簿に在籍あり、最終ログオンが古い
B 退職済み残存: 名簿で退職済み、またはADにあるのに名簿にない
C 共有・サービス候補: PasswordNeverExpiresがTrueで、名簿に個人として出てこない
D 判断保留: 上のどれとも言い切れない
各行に、分類・根拠にした列と値・確信度(高/中/低)を付けて
CSVで出してください。無効化の指示はしないでください。
最後に、各分類の件数と、ad_inactive_anon.csv の総行数を書いてください。プロンプトのポイントは3つあります。
- 休眠候補の全行を分類させる: 「怪しい行を挙げて」と頼むと、挙がらなかった行の扱いが不明になります。ad_inactive_anon.csvの全行を分けさせると、漏れが件数で見えます。名簿側の行は照合に使うだけで、分類の対象にしません。
- 根拠の列と値を書かせる: 後で人が確かめるとき、なぜその分類なのかを辿れます。
- Dを用意する: 分類を強制すると、判断材料が足りない行まで無理に振り分けます。保留の逃げ道があるほうが、誤分類は減ります。
手順4: 出力を検算してから、人が確認する
Claudeの出力は、そのまま採用しません。数分の検算を挟むと、事故の大半は防げます。
件数が合っているか
プロンプトで、ad_inactive_anon.csvの総行数と分類ごとの件数を書かせました。A〜Dの合計がこのCSVの行数に一致するかを、手元のPowerShellで確かめます。
(Import-Csv ad_inactive_anon.csv).Count
(Import-Csv claude_result.csv | Group-Object 分類 |
Select-Object Name, Count)数が合わないときは、Claudeが行を落としているか、重複させています。行数が数千を超える場合は、Claudeに分類の「ルール」をスクリプトとして書かせ、手元で実行する方法もあります。ルールを書かせると、同じ入力から同じ結果が出るので、翌月に再実行するときも結果がぶれません。CSVの集計や突合の基本はClaude CSV分析の使い方で扱っています。
B(退職済み残存)は全件を人事に戻す
分類のうち、最も影響が大きいのはBです。ここには「名簿に載っていない」という理由の行も入ります。名簿は在籍者の一覧であって、業務委託・派遣・グループ会社の出向者が載っていないことがあります。名簿に無いだけで退職済みと決めつけず、人事に件数分を戻して確認します。
C(共有・サービス候補)は、使っているシステム側の担当者に聞く
共有アカウントとサービスアカウントは、止めると業務が止まります。PasswordNeverExpiresがTrueという手がかりだけでは、用途は分かりません。OUの名前やアカウントの説明欄を見て、運用している担当者へ問い合わせます。
無効化の前に引く、人と機械の線引き
Claudeの出力が「候補一覧」であることを、運用のルールにしてしまうのが一番確実です。
| 分類 | Claudeがやること | 人が決めること |
|---|---|---|
| A休眠 | Claudeがやること根拠付きで挙げる | 人が決めること長期休職・年次処理用でないかの確認 |
| B退職済み残存 | Claudeがやること名簿との不一致を示す | 人が決めること人事への照会、無効化の可否 |
| C共有・サービス候補 | Claudeがやること手がかりの列を示す | 人が決めること用途の確認、止めてよいかの判断 |
| D判断保留 | Claudeがやること保留の理由を書く | 人が決めること追加調査をするか |
実際の無効化は、承認済みのリストを手元に作ってから、管理者がコマンドで行います。ADのモジュールには、アカウントを無効にする Disable-ADAccount と、戻す Enable-ADAccount があります。削除ではなく無効化にしておけば、問い合わせが来たときに戻せます。Claudeの出力をそのままスクリプトに流し込む運用は避け、承認済みのIdを元の SamAccountName に戻す作業も、手元の対応表で人が行います。
入退社のITアカウント申請を起票側から自動化する方法は、Freshserviceで入退社のITアカウント申請を会話から起票するにあります。入社と退社の起票が回っていれば、棚卸しで見つかる「退職済み残存」自体が減ります。
つまずきやすい点
ADの最終ログオンだけでは、使われていないと言い切れない: サービスアカウントは、人が対話的にログオンしない形で使われることがあります。無効にする前に、使っているシステムの側から確かめます。
名簿の更新が遅れている: 退職日が名簿に入る前に抽出すると、退職直後の人がAの「休眠」に混ざります。抽出する日と、名簿の最終更新日を揃えます。
閾値を変えるたびに結果が変わる: 90日と180日では候補の数が大きく違います。閾値と抽出日はCSVのファイル名か、Claudeへの依頼文に書いておきます。後で「前回はなぜ入っていなかったか」を辿れます。
IdP側のアカウントは別に棚卸しする: この手順で見るのは、ADのアカウントだけです。Entra IDのSSOやSCIMでClaudeに連携している場合、組織側のIdPのユーザーは別の一覧になります。連携の設定はClaude Entra ID SSO設定を参照してください。
まとめ
ADの休眠アカウント棚卸しで、Claudeに任せて効果が大きいのは、2つの表の突合と、根拠を付けた分類です。逆に、無効化の判断と実行は任せません。最終ログオンの値にはずれがあり、名簿も完全ではないからです。
作業の順番は、AD側で90日などの長い閾値で一次抽出、氏名を連番に置き換えたCSVを作成、全行を分類させて件数を検算、人事と担当者の確認を経て無効化、です。氏名を含む元データはアップロードせず、対応表は手元に残します。次の棚卸しでも同じ手順で回せるよう、プロンプトと閾値を記録しておくと、翌回の比較に使えます。