はじめに
Windows Hello for Business の顔認証を採用している環境で、認証させたくないタイミングで、顔認証されてしまって困ったことはありませんか?
通常の動作
既定では、最後に使った認証方法が優先されるため、顔認証 を使ったあとは 次回の認証は 顔認証 が優先されます。
1台のPCを占有して、常に顔認証で使っている場合は、便利に使えますが、共用 PC や、ユーザーを切り替えて使いたい場合に、顔認証が優先された状態だと、ちょっと困るシーンが出てくるのです。
本記事で解決できること
この記事で紹介する方法を使うと、以下のようなシーンに対応することができます。
- Windows のサインイン方法を“強制的に”制御
- Windows Hello の誤認証を防ぐ
- パスキーなどの指定した認証器を常に優先させる
私個人の活用事例
私は、自分の PC へ この仕組みを仕込んで、パスキー が優先されるようにしています。
WHfB の 顔認証が採用されていると、勝手に顔を読み取って認証してしまうので、それを防止できます。
認証の際は、パスキーを挿すか、手動で 顔 に切り替えて認証させるようにしています。この方法を使えば、顔認証の後であっても、再起動後は パスキー の認証に戻っています。
このようにしておくと、PC を起動したあとに、以下のような際の 誤認証を防ぐことが可能になります。
・ 離れた場所から画面を見たら、認証されてしまった
・ ユーザー切替したかったのに、認証されてしまった
Microsoft 公式見解(既知の問題)
以下の FAQ では、Windows Hello 顔認証が先に動いてしまって、セキュリティキーの認証をしたいのに、じゃまになる場合についての見解が示されていますが、「顔認証を無効しろ」と言っています。
※ これは「Windows Hello が Credential Provider の優先順位で上位にいる場合」に発生する問題です。
公開情報:Windows Hello Face が高速すぎて、これが既定のサインイン メカニズムであるため、ユーザーが FIDO2 セキュリティ キーを使用してサインインできない
https://learn.microsoft.com/ja-jp/entra/identity/authentication/howto-authentication-passwordless-troubleshoot?wt.mc_id=MVP_407731#known-issues
(上記の URL より抜粋)

これでは 併用ができないですね。
まさに、このようなシーンに対して、本記事の解決策が役立つと思います。
実は Windows には、サインイン方法の優先順位を制御する仕組みが存在します。
このようなシーンにも対処可能な方法をお知らせしたいと思います。
ソリューション
Windows の認証を行う際に、どの認証方法 を優先で利用するのかを制御することができます。
この制御を行うためには、以下の2種類の設定値を理解しておく必要があります。
①:GPO/既定の情報プロバイダーを割り当てる (DefaultCredentialProvider)
②:レジストリ/UserTile
① と ② のいずれも、認証方法 を制御しているのですが、目的が違うため、両者の組み合わせによって、振る舞いが違ってきます。
- 初回ログオンの既定値を決めたい → ① GPO
- ユーザーごとの最終選択を強制したい → ② UserTile
- 常に特定の方法を使わせたい → ①+②削除の組み合わせ
この2つの仕組みを正しく理解すると、“意図したサインイン方法を確実に選ばせる” という高度な制御が可能になります。
上記の ① ② で割り当てることができる 認証方法 (Credential Provider GUID)の 一例
実際に制御できる認証方法の GUID は以下の通りです。
| 認証方法 | Credential Provider GUID |
|---|---|
| パスキー | {F8A1793B-7873-4046-B2A7-1F318747F427} |
| パスワード | {60B78E88-EAD8-445C-9CFD-0B87F74EA6CD} |
| Windows Hello PIN | {D6886603-9D2F-4EB2-B667-1971041FA96B} |
| Windows Hello Face | {8AF662BF-65A0-4D0A-A540-A338A999D36F} |
では、それぞれの設定がどのように動作するのかを詳しく見ていきます。
①: GPO (DefaultCredentialProvider)
(設定の場所)
コンピューターの構成-管理用テンプレート-システム-ログオン
「既定の情報プロバイダーを割り当てる」
→ この設定の英語名が、DefaultCredentialProvider です。
(設定方法)
gpedit.msc で、グループポリシーの編集 を開きます。

以下の赤枠内に、Credential Provider GUID の値を入力します。

(動作)
PC の初回ログオン時に、この設定で指定した認証方法が選択された状態になります。
ユーザーは、サインインオプション で、別の認証方法に切り替えることができます。
ユーザーが実際にログオンに使った認証方法は、② のレジストリに記録されます。
※この仕様によって、ユーザーが 最後に選択した認証方法が、レジストリに記録されます。
(動作条件)
② の UserTile のレジストリ配下に SID が無い場合に発動します。
② の UserTile のレジストリ配下に SID が記録されている場合は、その指示が優先されるため、① の指定は無視されます。
公開情報:DefaultCredentialProvider
https://learn.microsoft.com/ja-jp/windows/client-management/mdm/policy-csp-admx-credentialproviders?wt.mc_id=MVP_407731#defaultcredentialprovider
②: レジストリ (UserTile)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\UserTile
UserTile の配下に、SID ごとの最後にユーザーが利用した 認証方法 が記録されています。
(動作)
ユーザーが ログオン画面 で自身のアカウントを選択すると、このレジストリ で指定された 認証方法 が自動選択されます。
万が一、UserTile 配下に、自身の SID が無い場合(削除されていた場合)は ① で指定された値が選択されます。
UserTile はユーザーがサインイン方法を切り替えると即上書きされます
レジストリ設定手順
既定のサインイン方式はユーザーごとに設定されるため、対象ユーザーの SID を確認し、それに対しての設定を行う流れとなります。
1.ターミナル(管理者)を起動します。
2.サインイン中の ユーザーの SID を確認します。
次のコマンドを実行:
whoami /USER

3.レジストリエディターを開きます。
次のコマンドを実行:
regedit

4.以下のレジストリキーを表示させます。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\UserTile
5.右側の一覧に、先ほど確認した SID と同じ名前の文字列(REG_SZ)を見つけて、ダブルクリックで開きます。値のデータ 欄に Credential Provider GUID を入力して OK を押します。

6.サインアウト を実施すると、設定が反映されます。
次回の サインイン画面で 指定した認証方法 が選択されていることを確認します。
注意点1
レジストリで指定した 認証方法 は、固定ではありません。
ユーザーが 別の方法でサインインを行うと、以後は その認証方法が保持されます。
注意点2
レジストリで指定する 認証方法 は、ユーザーが 利用可能 なものである必要があります。
※パスワードが禁止された環境で、パスワード を指定したり、Windows Hello を構成していないのに、Hello を選んでも、機能しません。
以上を踏まえると、以下のような シナリオ に活用できます。
シナリオ1:完全パスワードレスの環境
① で パスキー {F8A1793B-7873-4046-B2A7-1F318747F427} を指定しておく
→ 初回ログオン時から、パスキー 挿入を求められます。
→ これ以降は、利用者が最後に使った認証方法が 次回に優先されます。
シナリオ2:認証方法が複数あるが、常に パスキーを優先で使わせたい
ユーザーが 別の認証方法 に切り替えたとしても、常に パスキーが選択されるように制御したい場合
① で パスキー {F8A1793B-7873-4046-B2A7-1F318747F427} を指定しておく
② 該当 SID のキーを、自動的に削除する
→ 共有端末で、最後に認証した人の影響を受けないように、常に パスキー に固定しておけます。
シナリオ2 の実現案(サンプルスクリプト)
私が PoC でテストしただけの仕組みですが、ひとまず 意図通りに動いています。
ポイント1
(1) 現ユーザーの SID を取得するためには、ユーザー権限での実行が必要
(2) HKLM の レジストリの削除は、システム権限での実行が必要
上記の (1) (2) の両方を実行させるために、(1) で中間ファイルを作成し (2) に引き継いで 該当のレジストリを削除しています。
中間ファイルの存在を見ることで、トラブルシューティングにも活用できます。
ポイント2
本来は、ログオフ時に DeleteUserTile.ps1 を実行できると良いのですが、そういうトリガーが存在しないため、シャットダウン スクリプトで DeleteUserTile.ps1 を実行しています。
サンプルスクリプト
以下の2つのスクリプトは、C:\ProgramData\UserTileCleanup フォルダ配下に置いてください。
※このフォルダ場所は、システム と ユーザー の双方の権限で読み書きできる場所として採用しています。
組み合わせ動作イメージ
[ログオフ]
↓ (ユーザー権限)
LogOffSIDGet.ps1
↓
LastSid.txt に SID 保存
↓
[シャットダウン]
↓ (SYSTEM 権限)
DeleteUserTile.ps1
↓
UserTile の SID を削除
LogOffSIDGet.ps1
$dir = "C:\ProgramData\UserTileCleanup"
$SidFile = "$dir\LastSid.txt"
# 現在のユーザー名(ドメイン\ユーザー)
$UserName = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
# SID を取得
$Sid = (New-Object System.Security.Principal.NTAccount($UserName)).Translate([System.Security.Principal.SecurityIdentifier]).Value
# SID を保存
Set-Content -Path $SidFile -Value $Sid
→ ログオフ時に LastSid.txt 内に、ユーザーの SID が保存されます。
DeleteUserTile.ps1
$dir = "C:\ProgramData\UserTileCleanup"
$SidFile = "$dir\LastSid.txt"
if (Test-Path $SidFile) {
$Sid = Get-Content $SidFile
$Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\UserTile"
# SID の値を削除
Remove-ItemProperty -Path $Path -Name $Sid -ErrorAction SilentlyContinue
}
# スクリプトを実行した足跡を保存(トラシュー目的です。運用時は 割愛しても良いと思います)
Set-Content -Path "$dir\UserTileRemove.txt" -Value $Sid
→ シャットダウン時に LastSid.txt 内の SID を読み込んで、該当のレジストリを削除しています。
スクリプトのトリガー方法
ログオフスクリプト および シャットダウンスクリプト を使って、以下のスクリプトをトリガーするように構成します。
-
ログオフ スクリプト
ユーザーの構成
└ Windows の設定
└ スクリプト(ログオフ)
-
シャットダウン スクリプト
システムの構成
└ Windows の設定
└ スクリプト(シャットダウン)
:::
注意点
あくまで、スクリプトは サンプルの位置づけです。
PoC の範囲でテストして 動作している・・という程度のレベルですので、運用で採用いただく前には、必ず 臨床試験を実施して 問題ないかどうかをご確認ください。
制約事項
サンプルの方式では、ログオフには対応していません。
そのため、ログオフ後に、別のユーザーでサインインされた場合に、今の仕組みでは 最後のユーザーの SID だけが削除されることになるため、完全ではありません。
※SIDを、複数ユーザー分追記する仕組みにして、シャットダウン時にまとめて削除する方法にしても良いかもしれません。
参考
ログオフでも実行させる仕組みとして、タスクスケジューラーで ログオフのイベントログを検知して、SID を吐き出すことも検証してみたのですが、ログ出力のタイミングだと イマイチ 実用には向かない反応速度だったので、採用していません。どなたか、もっと良い方法を編み出してくれれば、ログオフ時で削除が良いと思っています。
さいごに
如何でしょうか?
あなたの環境ではどう使えそうですか?
なかなか、ぴったり合致したニーズは少ないのかもしれませんが、本動作を介して Credential Provider の働きはご理解いただけると思います。
この仕組みを 運用で採用された方は、どのような ニーズ に対して、この仕組みが活用できたのかを、ぜひ コメント欄で フィードバック いただけますと幸いです。





