WindowsのPowerShell
WindowsのPowerShellはその名の通り強力で便利なツールです。しかしそれがゆえ悪意のあるユーザーに狙われやすく改善と脅威の顕在化が激しいものでもあります。
そのため正しく理解しておかないとセキュリティーホールになりかねません。またセキュリティアップデートにより今まで意図したとおりに動いていたものが、急に動かなくなり修正を求められることも考えられます。
そこで今回はWindowsPowerShellについて学習しました。
PowerShellとは
コマンドラインでWindowsを操作するツールです。従来からある「コマンドプロンプト」や「Windows Script Host」の強化版だと考えると簡単かもしれません。実際、コマンドラインと互換性のあるコマンドも多く存在します。>によるリダイレクトにも対応しています。
たいていのアプリがそうであるようにPowerShellには複数のバージョンがあります。これを確認するには「PSVersionTable」変数の中身を見ます。PowerShellでは変数の接頭に$(半角ドルマーク)が付きます。PowerShell内で変数の中身を表示させたい場合は、そのまま$変数名(まはた${変数名})とすればいいので、「$PSVersionTable」とすることでバージョンを確認できます。複数行にわたって表示項目がありますが、PSVersionの行がそれにあたります。バージョンにより使えるコマンドも変わってきます。
...
PSVersion 5.1...
...
ちなみに変数に値をセットするには、「$変数=値」とします。値が文字列の場合は"(ダブルクォート)で囲います(「$変数="文字列"」)。さらに値だけでなく「1+2や"文字"+"列"」といった式を代入することもできます。ただし、$PSVersionTableは読み取り専用の変数の為、値をセットしようとするとエラーになります。
書式
詳細なドキュメントはMicrosoft:「PowerShell ドキュメント」にあります。これらに掲載されているPowerSehllのコマンド群は、基本的に-(ケバブケース)でつながっているのに加え単語同士の区切りに大文字(キャメルケース)が使われています。
ケバブケースの方は順守しないといけませんが、キャメルケースの方は小文字のままでも認識されます。
実行ポリシー
まず、PowerShellには「実行ポリシー」というものが存在します。これは主にPowerShellスクリプトに対する実行許可を設定するものです。
現在の状態は次の「Get-ExecutionPolicy」コマンドを実行すると表示できます。
RemoteSigned
「スクリプト」とはPowerShellのコマンドの集まりをまとめたファイルで、中に指定されている順番に従ってコマンドが実行されるものです。
この実行の可否の設定が「実行ポリシー」と呼ばれるもので、次のような種類があります。
- Restricted
スクリプトの実行は許可されません。
- AllSigned
信頼された発行元により署名がされていなければ実行されません。
- RemoteSigned
インターネットからダウンロードしたスクリプトは、信頼された発行元により署名がされていなければ実行されません。
インターネットからダウンロードしたスクリプトでも「Unblock-File」等のコマンドによってブロックが解除された場合は実行されます。
- Unrestricted
インターネットからダウンロードしたスクリプトの場合は警告を出し、その実行の可否をユーザーに委ねます
- Bypass
すべてのスクリプトが実行されます。
- Undefined
ポリシーが設定されていない状態です。
これはスクリプトの実行制限ですので、スクリプトが禁止されていても、スクリプトファイルの通りに一行ずつ実行することはできます。
利用者の意図しないところでスクリプトを実行されてしまうのを防ぐのに用います。
ポリシーの設定と適用範囲
ポリシーを設定するには「Set-ExecutionPolicy」コマンドに、ポリシー名は先に出たリストの中からパラメータを選択します。このコマンドの実行は管理者でなければ実行できません。
デフォルトではポリシーは「LocalMachine」に対して適用されますが、適用する範囲も指定できます。
適用範囲はスコープと呼ばれ、接続時点のセッションのみ有効な「Process」、接続中のユーザーに対して有効になる「CurrentUser」、コンピュータ全体に適用される「LocalMachine」があります。また複数スコープが設定されていた場合は優先度が高い方が採用されます。
スコープを指定して設定をするには「-Scope」オプションを使います。たとえば、Processに対して、Bypassを指定するなら次にようにします。
ポリシーと優先度の確認をするには「Get-ExecutionPolicy」コマンドに「-List」オプションを付けて実行します。
Scope | ExecutionPolicy |
MachinePolicy | Undefined |
UserPolicy | Undefined |
Process | Bypass |
CurrentUser | RemoteSigned |
LocalMachine | AllSigned |
上から順にみていきUndefinedでない最初のものが実際のポリシーとして採用されます。この場合はBypassが採用されます。一番厳しいルールが適用されるわけではないことに注意してください。
オプションの確認の仕方
先のGet-ExecutionPolicyとSet-ExecutionPolicyコマンドをの例では、-Listや-Scopeというオプションを使いました。コマンドにどのようなオプションが存在するか、複数あるオプションの順序はどうなっているかを調べるときは「Get-Help」コマンドを実行します。
...
この時「このコンピューターにこのコマンドレットのヘルプ ファイルは見つかりませんでした。ヘルプの一部だけが表示されています。」と表示される場合は「管理者権限のあるPowerShell」で「Update-Help」としてヘルプファイルをダウンロードするか、「Get-Help xxx -Online」としてブラウザでヘルプを開く方法があります。
ここで表示されるルールに従ってオプションや順序を指定します。[]内にあるものは存在していてもしなくてもいいものです。<>内には指定されるべき値を示す名称、{}の中には設定する値の候補が|で区切られて入っています。
ちなみにGet-Helpに引数を与えないと、PowerShell全体のヘルプとなります。
コマンドの結果を別のコマンドに渡す
コマンドの結果を別のコマンドに渡したい場合にはパイプラインという機能を使います。パイプを利用するには|(シフトを押しながら¥キー)記号を使って、前後のコマンドを区切って使います。
たとえば先の「Get-ExecutionPolicy -List」の結果をファイルに保存するには次のようにします。
...
ちなみにこのコマンドの結果はファイルに出力されるので画面に表示されません。画面にも表示させたい場合は、「Out-File」ではなく「Tee-Object」というコマンドが用意されています。
他、覚えておくと便利な使い方
他、便利な使い方として、コマンドはTABキーによる補完があります。Get-EとしてTABキーを押すと、入力した文字で始まるコマンドが1つ自動で表示されます。違った場合は再びTABキーを押すと次の候補が表示されます。
コマンドの途中で改行を入れたい場合は`(シフトキーを押しながら@)の入力の後にENTERキーを押します。
入力を中断するにはCtl+Cで止めることができます。
スクリプトファイルの作り方と実行方法
スクリプトファイルの作り方はとても簡単です。テキストファイルにコマンドを入力して拡張子を.ps1として保存するだけです。
実行時は.(半角コンマ)の後にスクリプトのパスを渡します。また「powershell スクリプトパス」としたり、「Start-Process -FilePath "powershell.exe" -ArgumentList "スクリプトのパス"」として、引数を与えて再度PowerShellを呼び出す方法もあります。
...
PowerShellでファイアウォールのルールを追加する
コマンドは多数あります。特定の操作をPowerShellで実現できるかどうかは公式ページから使えるコマンドを探します。この時バージョンの不一致に注意してください。
利用方法の一例としてファイアウォールの設定をPowerSehllのスクリプト経由で行う際の設定を紹介しておきます。多くのパソコンで同じファイアウォールルールを適用させたい場合はPowerShellのスクリプトにしておくと楽です。
通常ではローカルネットワークからしか応答しないようになっているPingコマンド(正確にはICMPv4)の範囲を、プライベートネットワークかドメインネットワークに所属している場合は192.168接頭のネットワーク全体へ広げます。
changefirewall.ps1
# 受信 New-NetFirewallRule ` -Name 'ping_in' ` -DisplayName 'ping_in' ` -Description 'ping_in' ` -Enabled True ` -Profile Domain,Private ` -Direction Inbound ` -Action Allow ` -Program Any ` -LocalAddress Any ` -RemoteAddress 192.168.0.0/16 ` -Protocol ICMPv4 ` -LocalPort Any ` -RemotePort Any ` -LocalUser Any ` -RemoteUser Any # 送信 New-NetFirewallRule ` -Name 'ping_out' ` -DisplayName 'ping_out' ` -Description 'ping_out' ` -Enabled True ` -Profile Domain,Private ` -Direction Outbound ` -Action Allow ` -Program Any ` -LocalAddress Any ` -RemoteAddress 192.168.0.0/16 ` -Protocol ICMPv4 ` -LocalPort Any ` -RemotePort Any ` -LocalUser Any ` -RemoteUser Any
次回はPower Shellでプリンタを管理してみたいと思います。