君はロックなんか効かない（スクリーンロックの回避方法について）

# 3行で要約

- 管理者が自動スクリーンロックや自動スリープを設定している場合のユーザー側での回避方法
- 常駐ソフト、ブラウザ拡張機能、VSCODE拡張機能、PowerShellスクリプトの4つの方法の紹介と技術解析
- あいみょんの歌は「[君はロックを聴かない](https://youtu.be/ARwVe1MYAUA?si=WX03cAODvYGeolyE)」なので、タイトルの芸術点は高くないですが、これ以上のタイトルを思いつきませんでした


## はじめに


情報セキュリティの基本としてスクリーンロックの適切な運用というものがあると思います。
離席時にPCをロックすることで、第三者が不正にPCを利用されることを防止します。
また、省電力の観点でも適切な時間でロックやスリープする設定にすることは推奨されています。

そのため、そこそこの企業では管理者の設定でスクリーンロックまでの時間を固定したり、PC監視ソフトで自動スクリーンロック無効を検知するなどの対策を取っているようです。

ですが、作業内容や環境によって自動スクリーンロックを無効にしたい場合がありますので、回避方法について記事にまとめました。

作業環境やセキュリティポリシーなどは、各個人によって異なりますので、本記事の方法をを使って問題が起きた場合は自己責任でお願いします。


## Windows設定

スクリーンロックの設定のおさらいをしておきます。

- 「システム > 電源」>「画面とスリープ」

画面とスリープの時間が設定できます。

![system_sleep2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/f9e23481-5b0b-430e-8bb3-6959a910f68a.png)



- 「個人用設定 > ロック画面」>「スクリーンセーバー」

スクリーンセーバーの時間が設定できます。

![system_lock2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/51f3fb4a-8b12-4165-a2bc-2c69f8471964.png)

![screensaver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/4e7928fd-2fb0-4ea9-860a-acc7ab9cf3f8.png)



管理者からこれらの設定を固定されている環境では、次以降に記載する回避する方法を試してください。


## ソフトウェアを使った自動スクリーンロック回避

自動スクリーンロックを回避できるソフトウェアがあります。

### PowerToys：Awake

Microsoft公式のPowerToysで[Awake](https://learn.microsoft.com/ja-jp/windows/powertoys/awake)が提供されています。
電源プランに影響されずに起動状態を維持します。MS公式なら管理者からインストール許可もらいやすいのではないかと思います。

[gitに公開されているソース](https://github.com/microsoft/PowerToys/tree/main/src/modules/awake/Awake)を見た感じだと[SetThreadExecutionState](https://learn.microsoft.com/ja-jp/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate)を使って実現してるようです。


### マウス操作の再現する方法

古くから使われているフリーソフトではマウス操作を再現するなどの方法でスリープやロックするのを防ぐ方式が多いようです。

[参考：マウスふるふる](https://www.vector.co.jp/soft/winnt/util/se497749.html?srsltid=AfmBOorivvNBxjw6Bp5819YbnLGGUiHzcnK-Tjfi-b3zN7aMOl37iL4B)


## ブラウザ拡張機能を使った自動スクリーンロック回避

ソフトウェアのインストールが許可されていない環境の場合は、ブラウザの拡張機能で自動スクリーンロックを防ぐことができます。

評価高そうなのを２つ紹介しておきます。
ツールバーに追加されるアイコンからawake状態を設定できます。

- Keep Awake (Display | System) [Edge](https://microsoftedge.microsoft.com/addons/detail/keep-awake-display-sys/jjaendaehnalocdginbjmaclfjgidlla) / 
 [chrome](https://chromewebstore.google.com/detail/apmicgkbejflkgeljipcebaoeigmangd?utm_source=item-share-cb)

![keepawake_red.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/f9fcc9e7-88bd-45e8-8a60-5b8b62cd55cf.png)

赤丸のアイコンクリックするとスリープ抑制できる簡単操作。

- Keep Computer Awake (for a While)
  [Edge](https://microsoftedge.microsoft.com/addons/detail/keep-computer-awake-for-/gpcjnpdkecmdghbnkeifiljlknkjhjke) / [Chrome](https://chromewebstore.google.com/detail/imbpigcghoambmanjekibelfjemnnool?utm_source=item-share-cb)

![keepcomputerawake.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/0d0b96fe-5d0d-43fa-aa02-902daff8bc63.png)

アイコンクリックするとメニューがでるので、「Screen On」を選択すればスリープ抑制できます。カスタムしたい方向け。



技術的には拡張機能の電源制御APIである[chrome.power.requestKeepAwake](https://developer.chrome.com/docs/extensions/reference/api/power)を使っているようです。



## VSCODE拡張機能を使った自動スクリーンロック回避

ブラウザの組織管理で拡張機能の追加が制限される環境もあるので、さらに別な方法としてVSCODE拡張機能で自動スクリーンロック回避する方法も紹介しておきます。

開発用のPCであれば、VSCODEのインストールは制限されないはず。

~~そしてVSCODEは組織管理できないから、VSCODE拡張機能に制限は無いはず。~~
※友人から[VSCODEの組織管理は可能](https://code.visualstudio.com/docs/setup/enterprise#_device-management)ってマサカリもらった。

拡張機能検索してみた感じでは１つしか見つけられなかったです。

- [NoSleep](https://marketplace.visualstudio.com/items?itemName=srk113.nosleep)

こちらはF15キーを定期的に送信してスクリーンロックされないようにする方式です。F15キーを使うアプリは無いと思いますが強引な仕様です。

ダウンロード数少ないから怪しいアプリかもしれないと疑い、直接vsixファイルを展開して中身見ましたがF15キーを定期送信する意外の処理は無いっぽいから大丈夫そう。


Ctrl+Shift+P でメニュー出して選択することでスリープ抑制状態になります。

![Nosleep-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264524/b108c15c-eb20-45e1-9aa6-a9618c46b228.png)


|コマンド|説明| 
| --- | --- |
|NoSleep: Activate| スリープ抑制| 
|NoSleep: Deactivate| スリープ抑制解除| 
 

## PowerShellからSetThreadExecutionStateを使って自動スクリーンロック回避

VSCODE拡張機能も使えないのであれば、PowerShellからSetThreadExecutionStateを実行するという方法があります。
[こちらの記事](https://azechi-n.hatenadiary.com/entry/2018/04/06/181909)のスクリプトがシンプルでそのまま使えそうです。


### 私PowerShellだけどスリープ抑制したい

私の[過去記事のPowerShell常駐スクリプト](https://qiita.com/magiclib/items/cc2de9169c781642e52d)と組み合わせれば、以下のような感じになります。

環境によっては定期実行しないとスリープ抑制できないらしいのでタイマーイベント使って30秒間隔で内部時間をリセットします。


```PowerShell:awake.ps1

Add-Type -AssemblyName System.Windows.Forms

function main(){
  $mutex = New-Object System.Threading.Mutex($false, "Global\mutex_awake")
  # 多重起動チェック
  if ($mutex.WaitOne(0, $false)){    
    # SetThreadExecutionState API の準備(スリープ抑制)
    $ES_SYSTEM_REQUIRED = [uint32]"0x00000001"
    $ES_CONTINUOUS = [uint32]"0x80000000"
    $ES_DISPLAY_REQUIRED = [uint32]"0x80000002"
    $awakecode = '[DllImport("kernel32.dll")] public static extern uint SetThreadExecutionState(uint esFlags);'
    $awakefunc = Add-Type -MemberDefinition $awakecode -namespace Win32Functions -name _SetThreadExecutionState -PassThru
    $null = $awakefunc::SetThreadExecutionState($ES_SYSTEM_REQUIRED -bor $ES_CONTINUOUS);    # スリープ抑制

    # Win32ShowWindowAsync API の準備(タスクバー非表示)
    $windowcode = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
    $asyncfunc = Add-Type -MemberDefinition $windowcode -namespace Win32Functions -name Win32ShowWindowAsync -PassThru
    $null = $asyncfunc::ShowWindowAsync((Get-Process -PID $pid).MainWindowHandle, 0)
    
    $application_context = New-Object System.Windows.Forms.ApplicationContext
    $timer = New-Object Windows.Forms.Timer
    $path = Get-Process -id $pid | Select-Object -ExpandProperty Path # icon用
    $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
    $notify_icon = New-Object System.Windows.Forms.NotifyIcon
    $notify_icon.Icon = $icon
    $notify_icon.Visible = $true
    $notify_icon.Text = "awake"
    $menu_item_exit = New-Object System.Windows.Forms.MenuItem
    $menu_item_exit.Text = "awake - Exit"
    $notify_icon.ContextMenu = New-Object System.Windows.Forms.ContextMenu
    $notify_icon.contextMenu.MenuItems.AddRange($menu_item_exit)
    $menu_item_exit.add_Click({
      $application_context.ExitThread()
    })

    # タイマーイベント
    $timer.Enabled = $true
    $timer.Add_Tick({      
      $null = $awakefunc::SetThreadExecutionState($ES_DISPLAY_REQUIRED); # 定期的に呼び出すことディスプレイ状態維持
    })

    $timer.Interval = 30 * 1000 # 30秒間隔
    $timer.Start()
    [void][System.Windows.Forms.Application]::Run($application_context)
    $timer.Stop()
    $null = $awakefunc::SetThreadExecutionState($ES_CONTINUOUS);    # 抑制解除
    $notify_icon.Visible = $false
    $mutex.ReleaseMutex()
  }
  $mutex.Close()
}

main

```


## おわりに

自動スクリーンロック、自動スリープの回避方法をまとめてみました。
いろんな方法、いろんなソフトウェア、いろんなAPIが提供されていて面白いですね。

セキュリティ上は、無効にしないほうが良いので、本記事の情報の使い方はお気をつけください。

あと、仕事さぼるのをばれない為のスリープ抑制としては、チャットツールは離席状態と判断すると思いますので、他の方法をお探しください。


記載しながら他の方法のアイディアも思いついたのですが、別記事のネタになりそうなので温存しておきます。




# 私PowerShellだけど…シリーズ

[私PowerShellだけど、君のタスクトレイで暮らしたい](https://qiita.com/magiclib/items/cc2de9169c781642e52d)
[私PowerShellだけど「送る」からファイルを受け取りたい（コンテキストメニュー登録もあるよ）](https://qiita.com/magiclib/items/7529557f756af9c8d21b)
[私powershellだけどタスクトレイの片隅でアイを叫ぶ](https://qiita.com/magiclib/items/9d0cd35814b6fcff2e44)
[私PowerShellだけど子を持つ親になるのはいろいろ大変そう](https://qiita.com/magiclib/items/ef0ab5c1fd8e0260b39d)
[私PowerShellだけどあなたにトーストを届けたい（プログレスバー付）](https://qiita.com/magiclib/items/12e2a9e1e1e823a7fa5c)
[私Powershellだけど日付とサイズでログを切り替えたい(log4net)](https://qiita.com/magiclib/items/4fe5bab3e879dd8de951)
[私PowerShellだけどスクリプトだけでサービス登録したい](https://qiita.com/magiclib/items/b4e2e919f02af1b04b58)
[私PowerShellだけどスクリーンショットを撮影したい](https://qiita.com/magiclib/items/91f7d32cbd766b39b293)
[私PowerShellだけどマウスカーソル付きのスクリーンショットを撮影したい](https://qiita.com/magiclib/items/c867525aa83db5a00ebb)

[サンプルソース置き場](https://github.com/part-time-penguin/qiita_powershell_samples)