特定の時間が過ぎたらPowerShellを使って自動でPCをロックする方法

machine inactivity lockでは、表示名ではなくPolicies\SystemのInactivityTimeoutSecsと適用GPOを最初の対象キーにします。変更や集計へ進む前に秒数・registry型・gpresultの管理元を保存し、別対象を同じ結果へ混ぜないことが出発点です。

この手順の合格条件は「900秒のmachine policyが再取得できlock後に認証が必要な状態」です。Microsoft Learn:machine inactivity security policyとSet-ItemPropertyによる対象DWORDの限定が定義するmachine inactivity security policyとSet-ItemPropertyによる対象DWORDの限定を根拠にし、画面へ値が出たことだけを成功とは判定しません。

停止条件:domain GPOが同じ値を所有している。該当するときは操作を進めず、保存したDWORDまたは未設定状態へ戻しpolicyを更新するを実行可能な形で確認してから再計画します。

日程Fit。無料・登録不要。「いつ空いてる?」を、ひとつのリンクで。リンクを送って、○△×でかんたん日程調整。無料で日程を作る。
目次

machine inactivity lock|表示名以外のキーで選ぶ:Policies\SystemのInactivityTimeoutSecsと適用GPO

この設定を識別するキーはHKLMのpolicy path、InactivityTimeoutSecs、DWORD型、適用元policyです。scheduled taskの名前やtriggerでは識別しません。

  • 一定時間後のPC自動ロック: 実行端末と現在ユーザーを記録する
  • Get-ItemProperty: Source、Version、利用可能なパラメーターを確認する
  • PolicyPath、ValueName、AppliedValue、実行ユーザー、EffectiveAfterRestart: 変更前の値を日時付きで保存する(一定時間後のPC自動ロックの判断では「単発のStart-Sleepスクリプトは再起動や終了で無効になる」を優先し、gpresult.exeが空なら成功扱いしません)。
  • 同じpolicy valueのXML、実行ユーザー、適用値、Settings、最終結果: 復旧に使えることを読み取り確認する(一定時間後のPC自動ロックでは個人端末はユーザー、組織ポリシーは管理者の範囲でGet-ItemPropertyが返す固有値を基準にします)。
  • 同じpolicy valueを上書きするか、無人実行の資格情報と影響が不明: 該当すれば本番実行を見送る

machine inactivity lock|読むだけか変更かを決める:900秒のmachine policyが再取得できlock後に認証が必要な状態

変更前はDWORD値または未設定状態とgpresultを保存し、domain GPO・MDMが所有する値ならローカル変更を中止します。

適用完了はregistry readbackだけではありません。承認済みrestart後、900秒の無操作でlockし、復帰時に再認証を要求することまで記録します。

判断要素一定時間後のPC自動ロックで記録する内容
対象の識別PolicyPath、ValueName、AppliedValue、実行ユーザー、EffectiveAfterRestart
最初の確認Get-ItemProperty
変更または操作Set-ItemProperty
再確認Get-ItemProperty
中止条件同じpolicy valueを上書きするか、無人実行の資格情報と影響が不明

復旧は保存済みJSONから旧DWORDまたは未設定を戻し、再びrestartして旧動作を確認します。

$policyPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
$valueName = 'InactivityTimeoutSecs'
$seconds = 900
$backupPath = Join-Path ([Environment]::GetFolderPath('MyDocuments')) 'ittrip-inactivity-timeout-before.json'
if (Test-Path -LiteralPath $backupPath) { throw "Backup already exists: $backupPath" }
gpresult.exe /h "$backupPath.gpresult.html" /f | Out-Null
if ($LASTEXITCODE -ne 0) { throw "gpresult failed: $LASTEXITCODE" }
$policyResult = Get-ItemProperty -LiteralPath $policyPath -ErrorAction Stop
$hadValue = $null -ne $policyResult.PSObject.Properties[$valueName]
$oldValue = if ($hadValue) { [int]$policyResult.$valueName } else { $null }
[ordered]@{ Schema=1; PolicyPath=$policyPath; ValueName=$valueName; PreviouslyConfigured=$hadValue; OldValue=$oldValue; NewValue=$seconds; CreatedUtc=[DateTime]::UtcNow.ToString('o') } |
  ConvertTo-Json | Set-Content -LiteralPath $backupPath -Encoding utf8 -NoNewline -ErrorAction Stop
Write-Host "Review $backupPath.gpresult.html. Stop if domain GPO/MDM owns this policy."

単発のStart-Sleepスクリプトは再起動や終了で無効になる。組織端末はGPO/MDMで一貫して管理する。 そのため、Get-ItemPropertyの値は別の公式な取得経路またはGet-ItemPropertyと照合します。

machine inactivity lock|環境差で変わる値を見抜く:独自Start-Sleep processをlock policyの代替にすること

自動ロックの目的は離席時のセッション保護であり、常駐するStart-Sleepスクリプトをポリシーの代替にすることではありません。InactivityTimeoutSecsの現値とgpresultの適用元を保存し、端末単位の設定とユーザーのスクリーンセーバー設定を分けて判断します。値が0または未設定なら、その理由がGPOかローカル未構成かも区別します。

家庭端末でも再起動後に残るMachineスコープの非アクティブ制限を使えば、ログオンごとのスクリプト起動漏れを避けられます。15分など承認した秒数を一台で試し、動画視聴や会議中の挙動、ロック解除、適用ポリシーを確認してから展開します。

自動ロックはHKLMのInactivityTimeoutSecsだけでなく、gpresultで確認した適用元GPOと有効値を記録します。組織ポリシーが所有する端末ではローカル値を繰り返し上書きせず、ポリシー担当者と変更単位を合わせます。

一定時間後のPC自動ロックの「スクリプトの作成手順」では、Get-ItemPropertyの取得時刻と対象件数を残します。後からGet-ItemPropertyを実行したとき、スクリプトの作成手順の差分理由を説明できる形にします。

machine inactivity lock|戻せる材料を先にそろえる:保存したDWORDまたは未設定状態へ戻しpolicyを更新する

machine inactivity lock|previewから限定実行へ進む:Policies\SystemのInactivityTimeoutSecsと適用GPO

$backupPath = Join-Path ([Environment]::GetFolderPath('MyDocuments')) 'ittrip-inactivity-timeout-before.json'
$backup = Get-Content -Raw -LiteralPath $backupPath -ErrorAction Stop | ConvertFrom-Json
$policyPath = [string]$backup.PolicyPath; $valueName = [string]$backup.ValueName; $seconds = [int]$backup.NewValue
Set-ItemProperty -LiteralPath $policyPath -Name $valueName -Type DWord -Value $seconds -WhatIf
if ((Read-Host 'After reviewing gpresult, type APPLY-LOCK-POLICY') -cne 'APPLY-LOCK-POLICY') { throw 'Cancelled' }
Set-ItemProperty -LiteralPath $policyPath -Name $valueName -Type DWord -Value $seconds -ErrorAction Stop
if ([int](Get-ItemPropertyValue -LiteralPath $policyPath -Name $valueName -ErrorAction Stop) -ne $seconds) { throw 'Policy readback failed' }
if ((Read-Host 'Type RESTART to make the local policy effective') -cne 'RESTART') { throw 'Restart is required before behavior verification' }
Restart-Computer -Force

machine inactivity lock|権限や到達性の不足で中断する:domain GPOが同じ値を所有している

一定時間後のPC自動ロックでアクセス拒否が出た場合は、すぐ管理者として再実行せず個人端末はユーザー、組織ポリシーは管理者という必要範囲を確認します。対象側のACLや管理ロールも分けて調べます。

machine inactivity lock|再取得値を完了条件へ結ぶ:900秒のmachine policyが再取得できlock後に認証が必要な状態

$backupPath = Join-Path ([Environment]::GetFolderPath('MyDocuments')) 'ittrip-inactivity-timeout-before.json'
$mode = 'VERIFY_APPLIED' # ROLLBACK または VERIFY_ROLLBACK
$backup = Get-Content -Raw -LiteralPath $backupPath -ErrorAction Stop | ConvertFrom-Json
$policyPath = [string]$backup.PolicyPath; $valueName = [string]$backup.ValueName
function Restore-InactivityTimeout {
  if ((Read-Host 'Type ROLLBACK-LOCK-POLICY') -cne 'ROLLBACK-LOCK-POLICY') { throw 'Cancelled' }
  if ([bool]$backup.PreviouslyConfigured) { Set-ItemProperty -LiteralPath $policyPath -Name $valueName -Type DWord -Value ([int]$backup.OldValue) -ErrorAction Stop }
  else { Remove-ItemProperty -LiteralPath $policyPath -Name $valueName -ErrorAction Stop }
  if ((Read-Host 'Type RESTART-ROLLBACK to apply the restored policy') -cne 'RESTART-ROLLBACK') { throw 'Rollback restart is required' }
  Restart-Computer -Force
}
if ($mode -eq 'VERIFY_APPLIED') {
  if ([int](Get-ItemPropertyValue -LiteralPath $policyPath -Name $valueName -ErrorAction Stop) -ne [int]$backup.NewValue) { throw 'Applied value mismatch' }
  if ((Read-Host 'After observing the full idle interval, lock, and resume authentication, type LOCK-TEST-PASSED') -cne 'LOCK-TEST-PASSED') { throw 'Behavior not verified' }
} elseif ($mode -eq 'ROLLBACK') { Restore-InactivityTimeout
} elseif ($mode -eq 'VERIFY_ROLLBACK') {
  $property = Get-ItemProperty -LiteralPath $policyPath -ErrorAction Stop
  $exists = $null -ne $property.PSObject.Properties[$valueName]
  if ($exists -ne [bool]$backup.PreviouslyConfigured) { throw 'Rollback presence mismatch' }
  if ($exists -and [int]$property.$valueName -ne [int]$backup.OldValue) { throw 'Rollback value mismatch' }
} else { throw 'Unsupported mode' }
  • Get-ItemProperty: 同じ対象IDを再取得できた
  • 一定時間後のPC自動ロック: 意図した値または件数だけが変化した
  • 適用値、実行条件、LockBehaviorResult、実行プログラムを個別確認する: 関連機能も異常がない(一定時間後のPC自動ロックの判断では「単発のStart-Sleepスクリプトは再起動や終了で無効になる」を優先し、gpresult.exeが空なら成功扱いしません)。
  • タスクパス違い、無効状態、イベント適用値、参照権限不足: 取得失敗をゼロ件として扱っていない
  • 単発のStart-Sleepスクリプトは再起動や終了で無効になる。組織端末はGPO/MDMで一貫して管理する。: 環境固有の制約に反していない

machine inactivity lock|復旧失敗時の停止点を置く:保存したDWORDまたは未設定状態へ戻しpolicyを更新する

変更前のポリシー値と適用元GPOを記録する。ローカル値を上書きせず、管理GPO側で元の値へ戻して再適用を確認する。

machine inactivity lock|ゼロ件と取得不能を区別する:独自Start-Sleep processをlock policyの代替にすること

machine inactivity lock|定期実行へ渡す記録を決める:秒数・registry型・gpresultの管理元

  • Get-ItemPropertyの実行時刻、対象件数、エラー件数を残した
  • PolicyPath、ValueName、AppliedValue、実行ユーザー、EffectiveAfterRestartで対象を一意に特定した(一定時間後のPC自動ロックの判断では「単発のStart-Sleepスクリプトは再起動や終了で無効になる」を優先し、gpresult.exeが空なら成功扱いしません)。
  • 同じpolicy valueのXML、実行ユーザー、適用値、Settings、最終結果を変更前に保存して読めることを確認した(一定時間後のPC自動ロックではgpresult.exeが同じ対象を返さない場合、変更前のポリシー値と適用元GPOを記録する)。
  • Set-ItemPropertyの対象を一端末・一ユーザー・一設定に限定した
  • Get-ItemPropertyと実利用テストの両方を確認した
  • 同じpolicy valueを上書きするか、無人実行の資格情報と影響が不明場合は実行を中止した

machine inactivity lock|似た機能との違いを確認する:user単位ではなくcomputer単位になる理由

公式情報・参考資料

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次