実行ポリシーが「RemoteSigned」であり、なおかつ ZoneId の値が「3」や「4」であったとしても、「信頼できる証明書」が付いてさえいればそのスクリプトを実行できます。
というわけで、今回のテーマは「自己署名証明書の作成と、それによるスクリプトへの署名」です。
|
|
なお、以下 <A> , <B> のブログが同じテーマで書かれているので、参考になります。
<B> PowerShell でコード署名用の証明書を作成する
PowerShell には、自己署名証明書を発行するための " New-SelfSignedCertificate " コマンドレットがあります。
上記 <B> のブログには、 このコマンドレットではコード署名用の証明書を作成できないと書いてあるのですが、Windows 10 の PowerShell 5.0 からできるようになりました。
(Windows 8.1 Pro Update や Windows 7 Professional SP1 に「Windows Management Framework 5.0 Production Preview」をインストールした環境ではできませんでした。)
実務に耐えうる証明書ではないかもしれませんが、とにかくスクリプトを実行することはできたので、その方法を以下に紹介します。
<想定環境>
(a) ワークグループ環境の Windows 10 Pro (ビルド 10240)一台を使用。
(b) Administrators グループに所属するユーザー「psone」を使用。
(c) Set-ExecutionPolicy コマンドレットにより、実行ポリシーを「RemoteSigned」とする。
(d) 署名対象のスクリプトとして E ドライブに「a.ps1」を作成し、Get-Date コマンドレットを記述する。
(e) a.ps1 に、Set-Content コマンドレットにより Zone.Identifier を記述し、ZoneId の値を「3」とする。
※ 以上の環境で PowerShell を起動してa.ps1 を実行すると、「(略)ファイル E:¥a.ps1 はデジタル署名されていません。(略)」といったエラーが表示されます。
<手順>
(0) PowerShell を管理者権限で起動します。
(1) 以下の4条件で、自己署名証明書を作成します。
・フレンドリ名「for_a.ps1」
・作成場所「ローカルコンピューターの個人ストア」
・発行先「self」
・証明書の種類「コードサイニング証明書」
New-SelfSignedCertificate -CertStoreLocation "cert:¥LocalMachine¥My" -FriendlyName "for_a.ps1" -Subject "self" -Type CodeSigningCert
(2) ちゃんと作成できたか確認します。
デフォルトの状態であれば、(1) で作成した一通の他にコードサイニング証明書は無いはずです。
(発行先だけでなく、発行者も「self」になっていました。また、有効期限は1年20分後でした。)
Get-ChildItem Cert:¥localMachine¥My -CodeSigningCert | Select-Object Thumbprint,FriendlyName,Issuer,Subject,EnhancedKeyUsageList,NotAfter
(3) 作成した自己署名証明書を、変数 $CERT に格納します。
$CERT = Get-ChildItem Cert:¥localMachine¥My -CodeSigningCert
(4) 作成した自己署名証明書を、E ドライブに「Cer.cer」としてエクスポートします。
Export-Certificate -FilePath E:¥Cer.cer -Cert $CERT
(5) エクスポートした Cer.cer を、「ローカルコンピューターの信頼された発行元ストア」へインポートします。
(なぜかアクセス拒否されて失敗することがありましたが、時間をおいてから新たに PowerShell を起動して実行したら成功しました。)
Import-Certificate -FilePath E:¥Cer.cer -CertStoreLocation Cert:¥localMachine¥TrustedPublisher
(6) エクスポートした Cer.cer を、「ローカルコンピューターの信頼されたルート証明機関ストア」へもインポートします。
Import-Certificate -FilePath E:¥Cer.cer -CertStoreLocation Cert:¥localMachine¥AuthRoot
(7) 作成した自己署名証明書で、a.ps1 を署名します。
Set-AuthenticodeSignature -FilePath E:¥a.ps1 -Certificate $CERT
(8) a.ps1 を実行します。
現在の日時が表示されれば成功です。
(9) a.ps1 をテキストエディタで開くと、本当に署名されていることを確認できます。
自己署名証明書の情報だと思われる不規則な英数字が、末尾に何行も追記されているのです。
その部分を削除すれば、またスクリプトを実行できない状態に戻ります。
おわり