2014/03/03

PowerShell 共有フォルダのスクリプトファイルを実行したい~自己署名証明書の作成と署名

PowerShellのスクリプト ファイルをWindows Server 2012 R2 Essentials等のファイル サーバに保存し、管理者(ないしは、管理者が指名した従業員)に使ってもらう準備をしています。
しかし、実行ポリシーをRemoteSignedにしている関係上、ファイル サーバ上のスクリプト ファイル(.ps1)は実行エラーになります。
今回は、PowerShell スクリプトファイルをデジタル署名し、共有フォルダのファイルを実行する方法をメモ。
本内容は既出の情報になります。また、初めての作業のため自分用メモとして投稿しております。

署名無し スクリプト ファイルを実行すると?

ご存じのとおり、PowerShellには実行ポリシーがあり、よく使われる「RemoteSigned」の場合はローカルのスクリプト ファイルは実行可能ですが、ファイル サーバ等ネットワーク上のスクリプト ファイルは実行エラーになります。
下記画像はデジタル署名されていないファイルの実行にエラーで、実行ポリシー「RemoteSigned」のポリシーどおりの動きになります。
image

今回の流れ

  1. 自己証明機関の作成
  2. 自己署名証明書の作成
  3. スクリプト ファイルの署名方法

自己証明機関の作成方法

2008年 4月に発行されたTechnet マガジン「Windows PowerShell ~ 署名をお願いします」を参考に作成してみました。
作成はmakecert.exeを使用しますが、自己署名証明書は
  • Visual Studio
  • Windows 7 SDK
から作成できます。
makecert.exeの起動~Visual Studioを使う場合
今回は手持ちのVisual Studio Professional 2013 を使ってみます。
  1. [すべてのプログラム]→[Visual Studio 2013]→[Visual Studio ツール]をクリック
    image
  2. [開発者コマンド プロンプト for VS2013]を[管理者権限]として実行
    image
  3. makecert.exeを実行
    image
makecert.exeの起動~Windows 7 SDKを使う場合
  1. Windows 7 SDKをダウンロード
    http://www.microsoft.com/en-us/download/details.aspx?id=8279
  2. [Windows Native Code Development]→[Tools]のみチェックを入れ、インストール
    2013-12-25_132947
  3. PowerShellを起動
  4. makecert.exeが格納されている下記パスに移動
    C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\bin
    ※v6.0,v7.0A,v8.0,v8.0Aのフォルダがありますが、makecert.exeはv7.1Aに格納されています。
  5. [管理者権限]としてmakecert.exeを実行
    image
自己証明機関の作成
  1. コマンド ラインから、引数付きmakecert.exeを実行
    makecert -n "CN=証明書名" -a sha1 -eku 1.3.6.1.5.5.7.3.3
     -r -sv c:\temp\xxx.pvk c:\temp\xxx.cer
     -ss Root -sr localMachine
  2. パスワードを入力せずに[OK]ボタンをクリック
    image
  3. [はい]をクリック
    image

自己署名証明書の作成

コマンド ラインからmakecert.exeを実行
makecert -pe -n "CN=証明書名" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3
-iv c\temp\xxx.pvk -ic c:\temp\xxx.cer
image 
PowerShell から作成した証明書、および、Thumbprintは下記コマンドから確認出来ます。
Get-ChildItem cert:\CurrentUser\My -CodeSigningCert
実行エラーが発生した場合
実行結果が
Error: Save encoded certificate to store failed => 0x5(5)

image
となった場合は、コマンド プロンプトを[管理者権限]として実行していないためです。
[管理者権限]として実行しましょう。
image
makecert.exeの引数
今後も使いそうな引数をまとめてみました。
引数説明既定値
-r自己署名証明書を作成
-pe生成された秘密キーをエクスポートし、秘密キーを証明書に組み込む
-nサブジェクトの証明書名を指定
X.500 標準に準拠する必要あり
-ss出力される証明書を格納する、サブジェクトの証明書ストア名を指定
-b有効期間の開始日を指定現在の日付
-e有効期間の終了日を指定12/31/2039 11:59:59 GMT
-a署名アルゴリズムを指定
アルゴリズムは、md5,sha1,sha256,sha384,sha512
sha1
-srサブジェクトの証明書ストアの位置を指定
location は、currentuser,localmachine
currentuser
-svサブジェクトの秘密キーファイル(.pvk)を指定
秘密キーファイルが存在しない場合に使用
-ekuEnhanced Key Usage
コンマ区切りの、拡張キー用途オブジェクト識別子 (OID) の一覧を証明書に挿入します。
詳細は事項で。

-eku:ekuに指定するOID(ObjectID)は下記リンクに明記されています。

今回使用する「1.3.6.1.5.5.7.3.3」は、EKU拡張グループの「コード署名(XCN_OID_PKIX_KP_CODE_SIGNING)」の事を表しています。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa379070(v=vs.85).aspx

PowerShell スクリプトの署名方法

最後にスクリプト ファイルを署名します。
$cert = @(Get-ChildItem cert:\CurrentUser\My -CodeSigningCert)[0]
Set-AuthenticodeSignature SampleScript.ps1 $cert

修正・改ざんされたスクリプトファイルを実行するとどうなるのか?

当然ですが、スクリプトの実行エラーが表示されます。
この場合は、再度署名し直しましょう。

この時に非常に役立つのが、PowerShell from Japan!! Blogさんの記事「[Tips]自己署名証明書を作成するには?」の最後で説明されているカスタム関数「Set-Cert]です。
プロファイルにSet-Cert関数を登録したところ、修正後の作業が非常に楽になりました!
※ただ貼り付けただけでは機能しません。注意点をよく読み、ご自身で設定した自己署名証明書のSubjectを確認、修正を行いましょう。

なお、プロファイルへの登録は、PowerShellで
>notepad.exe $PROFILE
を実行し、プロファイルに関数を貼り付けるだけです。
詳しくは、Technet 記事をご覧ください。
Windows PowerShell プロファイル

関連記事

今回参考にさせてもらったサイト
スポンサーリンク

スポンサーリンク