Open1

powershellのExecutionPolicyの変わった(頭おかしい)仕様

Otogawa Katsutoshi(oto)Otogawa Katsutoshi(oto)

PowershellにはExecutionPolicyというものがある。
これはPowershellの実行ポリシーを変更するもので、
デフォルトではRestrictedとなっており、psgalleryにあるスクリプトや

ExecutionPolicyの仕様はかなり複雑で混乱しやすい。

ここで恐らく知らない人が多いであろう仕様について書く。

ExecutionPolicyの値の確認

Get-ExecutionPolicy -list

デフォルトの設定はWindows serverかそうでないかや、windowsのバージョンによって
違うかもしれない。
windows server 2022, windows 11 23H2 proともに実行してみたが、
powershell5.1, powershell 7.1ともにデフォルト値は同じRemotesigneであった。

仕様として、Powershell 5.1とPowershell coreとでExectuionPolicyは別々の設定として持つ。
Processは環境変数を参照しているだけの仕組みのため、
Powersshell7.1からPowershell5.1を呼び出すなどすると元のProcessの値が引き継がれる。

Powershell5.1の場合のデフォルト設定

< Scope ExecutionPolicy
< ----- ---------------
< MachinePolicy Undefined
< UserPolicy Undefined
< Process Undefined
< CurrentUser Undefined
< LocalMachine RemoteSigned

ドキュメントにはRestrictedと書かれているため、昔はRestrictedがデフォルト値で途中からデフォルト値がRemoteSingedになったのだと思われる。
古いWindows10やWindows8あたりからアップグレードしたものはRestrictedになっている可能性がある。

ドキュメントには特に書かれていませんが、今後、Windowsのシステムが一部powershellになる可能性が高いので、LocalMachineのデフォルト値を変更するのはあまりお勧めしません。

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.4#execution-policy-scope

よく、サイトで調べると実行ポリシーの
Microsoftの

Processは環境変数$env:PSExecutionPolicyPreferenceに
ExectuionPolicyが設定されており、環境変数ゆえに子供のプロセスにも
ProcessのExecutionPolicyが設定される。

これが何を意味するかというと、実質的に実行ポリシーがAllSinged以外の場合は
Powershellに関してすべて権限が許可されていると同意であるということである。

つまり実質的にCurrentUserはActive Directoryに対してLocalUserとしてふるまっているということである。

ここでは話を簡単にするため、
LocalMachineはLocalの管理者権限ユーザー
CurrentUserは

LocalMachine

よって、Powershellでちゃんと実行権限をコントロールしたいなら、GroupPolicyで値を設定するしかないということになる。
LocalAccount

Restrictedはスクリプトモジュールの実行が
SecurityError: File C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Storage\Disk.cdxml cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https://go.microsoft.com/fwlink/?LinkID=135170.

なぜ、ExecutionPolicyのデフォルトがRemoteSinedになったのか?

ここではなぜ
途中からRestrictedというスクリプトモジュールが実行できないものに変わったのか?
ということについて推察したい。

変わった。
これは実はWindowsのシステムにインストールされているコマンドはスクリプトモジュールとバイナリモジュールのコマンドレットがあるということがわかる。
つまり、ずっとコマンドレット(バイナリモジュールでコマンドとして動作するように作ったclass)ではなく、ただのPowershellの関数(スクリプトモジュールで定義する)でしかないものもかなりあるということだ。
Restrictedだと、psm1, ps1, ps1xml,cdxmlのファイルが読めなくなるため、スクリプトモジュールに書かれているコマンドを実行できない。
これにはStorageやBitLocker,などが入っている。

RestrictedだとPowershellのスクリプト自体が実行できないため、
StorageモジュールにあるGet-DiskやGet-Volumeだったり、BitLockerのようなどこら辺が危険なのかよくわからない

Windowsは基本的に管理者かそれ以外かというローランドかなんかみたいな権限になっており、
例にもれず、Storageの一部のオプションやBitLockerも管理者権限でしか操作できない。
StorageグループやらBitLockerグループならその権限をすべて触れるみたいな人にやさしい作りになっていない。