RemoteSigned と Zone.Identifer (1)

PowerShell のスクリプト(.ps1) を実行できるかどうかは、「実行ポリシー」によって決定されます。

現在の設定が何であるかを確認するためには ” Get-ExecutionPolicy ” コマンドレットを実行します。

 





   




   

 

実行ポリシーの既定値や設定可能な選択肢は OS によって異なり、Windows Server 2012 R2 の場合はタイトルにある「RemoteSigned」が既定値です。

この実行ポリシーの意味は「インターネットからダウンロードされたすべてのスクリプトおよび構成ファイルが、信頼された発行元によって署名されていることを要求します。」で、平たく言うと「インターネットから落としてきた、素性の知れないスクリプトは実行できない」となります。

実行できるスクリプトは、「インターネットから落としてきたスクリプト以外」や、「インターネットから落としてきた、信頼できる証明書が付いたスクリプト」です。

 

 

では、OS はどのようにして「そのスクリプトはインターネットから落としてきたモノか否か」を判定しているのでしょうか。

この判定には、ファイルの「Alternate Data Streams(代替データストリーム)」が利用されています。

「Alternate Data Streams」は、ファイルの「属性値」というより、「付加情報(ストリーム)群」といった方が適切かもしれません。

(なお、この付加情報群は .ps1 ファイルだけでなくあらゆるファイルに存在し得るのですが、NTFS ファイルシステムの機能であるため、FAT32 のドライブにあるファイルには存在しません。)

 

 

Alternate Data Streams には様々な付加情報を格納可能なのですが、その中の一種にファイルの入手元を分類する「Zone.Identifier」があります。

Zone.Identifier に記録されている「ZoneId」の値が「3」であれば、そのファイルは「インターネットから落としてきたファイル」だと見做されます。

 

 

ファイルの Zone.Identifier はテキストエディタで開いて確認できるのですが、開き方がやや特殊です。

カレントディレクトリにある「a.ps1」について確認するには、コマンドプロンプトで ” notepad a.ps1:Zone.Identifier ” を実行します。

もし、開いたメモ帳に以下の3行が表示された場合、 a.ps1 は「インターネットから落としてきたファイル」だと見做されます。(3行目は空)

= = = = = = = = = = = = = = = = = = = = = = =

[ZoneTransfer]

ZoneId=3

 

= = = = = = = = = = = = = = = = = = = = = = =

(対象ファイルに Zone.Identifier が存在しない場合は、その旨のポップアップメッセージが表示されます。)

テキストエディタを使うこの方法により、Windows XP Professional SP3 と Windows Server 2012 R2  Datacenter で、Zone.Identifier を確認できました。

 

 

テキストエディタ以外に、Zone.Identifier を PowerShell で確認することもできますが、PowerShell 3.0 (Windows 8 に標準搭載) 以降のバージョンが必要です。

(Windows 7 に PowerShell 3.0 をインストールした環境でも成功しました。)

確認のためには、” Get-Content a.ps1 -Stream Zone.Identifier ” コマンドレットを実行します。

メモ帳で開いた場合と違うのは、空の3行目が表示されないことぐらいです。

 

 

さて、テキストエディタや Get-Content コマンドレットで確認できるということは、任意に編集することもできるということです。

ローカルで作成したファイルには本来 Zone.Identifier が存在しませんが、意図的に書き込んで、OS に「インターネットから落としてきたファイル」だと思わせることもできます。

逆に、ZoneId を「3」以外の値に編集して、OS に「インターネットから落としてきたファイルではない」と思わせることもできます。

 

 

カレントディレクトリにある「a.ps1」の Zone.Identifier を PowerShell で編集する方法を、3パターン紹介します。

(前述の通り、バージョンが 3.0 以降である必要があります。)

 

(1) ローカルで作成した「a.ps1」に、「インターネットから落としてきたファイル」と同じ内容の Zone.Identifier を書き込む場合

Set-Content a.ps1 -Stream Zone.Identifier [ZoneTransfer],ZoneId=3

 

(2) ZoneId の値を「3」から「1」(イントラネットから落としてきたファイル)に書き換える場合

Set-Content a.ps1 -Stream Zone.Identifier [ZoneTransfer],ZoneId=1

 

(3) 「a.ps1」から Zone.Identifier を削除する場合

Remove-Item a.ps1 -Stream Zone.Identifier

 

 

つづく