「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>PowerShell]]

* 目次 [#t6edc4f1]
#contents

* 概要 [#m1e4b186]
PS1ファイルの作成と実行について。

*実行ポリシー [#i305d670]
-PowerShell の スクリプトファイルは、 拡張子 .ps1 のテキストファイル。
-*.ps1スクリプトファイルは、コマンドプロンプトの中で
--「powershell .\script.ps1」、
--または、PowerShellコマンドプロンプトの中で「.\script.ps1」

>の様にして実行できる。

-が既定では、PowerShell スクリプト そのものについて、~
実行が抑止されているので *.ps1 を実行するには、~
以下の設定変更または回避方法を検討する。

--[[実行ポリシーを変更>#jdedd4bd]]
--[[PowerShell -Command - 構文でスクリプトを読み込ませる>#wc5bad1b]]
--[[PowerShellコマンドプロンプトの中に貼り付ける>#g659c33b]]

**実行ポリシーを変更 [#jdedd4bd]

***Set-ExecutionPolicy [#s515974f]
-実行ポリシーを変更するには、Set-ExecutionPolicy を実行します。
 Set-ExecutionPolicy RemoteSigned

-RemoteSigned を指定すると、
--ローカルコンピュータの.ps1ファイルか、
--ファイル共有またはダウンロードした署名付きの.ps1ファイルが

>実行できます。

-Set-ExecutionPolicy の設定は、恒久的に設定される。
--Bypass (=無制限に.ps1を実行可能) に変更してそのまま放置しないように。
--用が済んだら、既定値の Restricted に戻しておきます。
 Set-ExecutionPolicy Restricted
--scope を指定して、設定変更の対象を限定することもできます。~
※ CurrentUser はこのコマンドを実行したユーザーだけ、設定変更します。
 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

*** [#a21472bb]
***運用時の実行ポリシー [#a21472bb]
メンテナンスや運用作業で.ps1を使用する場合は、~
通常時にどの実行ポリシーにしておくか、検討ください。
-.ps1ファイルに署名を行い、AllSigned にしておくか。
-あるいは、RemoteSigned にしておくか。
-それとも Restricted にしておき、都度実行ポリシーを変更するか。等

**PowerShell -Command - 構文でスクリプトを読み込ませる [#wc5bad1b]
-PowerShell コマンドプロンプトに手入力して逐次実行するかわりに、~
'-Command - を使用して、標準入力からコマンドを連続実行できる。~

-手打ちと同じなので、 Set-ExecutionPolicy Restricted のままでも、実行可能。~
実行ポリシーをどうしても変更したくない場合の次善策として、使用できるか検討する意味は有ります。~
下の例の様に、 batファイルとecho を組み合わせて、引数を与えることも出来ます。~

***batファイル [#c35ff7a4]
ps_test.bat

 @( echo $arg1 = "%~1"
    echo $arg2 = "%~2"
    type ps_test.ps1 ) | powershell -command -

***ps1ファイル [#k5dc1c30]
ps_test.ps1

 function main() {
  $a = ($arg1 + $arg2)
  $b = ([int]$arg1 + [int]$arg2)
  write-output "string : $arg1 + $arg2 = $a"
  write-output "integer : $arg1 + $arg2 = $b"
 }
 
 $err=0
 $ErrorActionPreference = "stop"
 try {
   $log = main
 } catch [Exception] {
   $err=1
   $log = $_
 }
 
 write-output $log
 exit $err

-.ps1 の try/catch の } の下に空行があることに注意。
-powershellコマンドを -Command - で読み込ませる場合、~
手入力と同じようにコードブロックの後に空行が必要です。

***実行例 [#cb11fd36]
これを実行すると、echo の2つが  ps_test.ps1 の先頭に挿入されて、~
PowerShellコマンドプロンプトに手入力して逐次実行することになります。

 ps_test 1 2
 
 string : 1 + 2 = 12
 integer : 1 + 2 = 3


標準入力を手入力の代わりに使用してしまうため、~
スクリプトのなかでキー打鍵待ちのようなことは難しくなります。~

**PowerShellコマンドプロンプトの中に貼り付ける [#g659c33b]
-PowerShellコマンドプロンプトの画面に、クリップボードからスクリプトを貼り付けます。

--スクリプトは、テキストファイルなどで用意しておき、
--メモ帳などで開いたら、テキスト全体をクリップボードにコピー。
--それを、PowerShellコマンドプロンプトに貼り付けます。

-実行ポリシーを変更しない、上のようなバッチファイルも不可であれば、
--手動でPowerShellコマンドプロンプトへ貼り付けをするか、
--PowerShellの使用をあきらめるか

>しかありません。

* 変数のスコープ [#d923bb09]
**スクリプト [#r9abb657]
-ps_scope1.ps1
  $global:g1 = "0"
  $script:s1 = "0"
  $v1 = "0"
  
  write-host "before      : g1=$global:g1 s1=$script:s1 v1=$v1 v2=$v2"
  
  function test1 {
    write-host "start test1 : g1=$global:g1 s1=$script:s1 v1=$v1 v2=$v2"
    $global:g1 = "1"
    $script:s1 = "1"
    $v1 = "1"
    $v2 = "1"
    write-host "end test1   : g1=$global:g1 s1=$script:s1 v1=$v1 v2=$v2"
  }
  
  test1
  
  write-host "after       : g1=$global:g1 s1=$script:s1 v1=$v1 v2=$v2"

**実行例 [#l44741d7]
  E:\temp>powershell
  Windows PowerShell
  Copyright (C) 2009 Microsoft Corporation. All rights reserved.
  
  PS E:\temp> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
 
  PS E:\temp> .\ps_scope1.ps1
  before      : g1=0 s1=0 v1=0 v2=
  start test1 : g1=0 s1=0 v1=0 v2=
  end test1   : g1=1 s1=1 v1=1 v2=1
  after       : g1=1 s1=1 v1=0 v2=
 
  PS E:\temp> write-host "g1=$global:g1 s1=$script:s1 v1=$v1 v2=$v2"
  g1=1 s1= v1= v2=
 
  PS E:\temp>

**解説 [#y3af1648]
-$v1 は
--.ps1 の中で最初に設定している値が、 関数test1 の中でも参照できますが、
--関数test1 の中で設定した値は、関数test1 の外では有効ではありません。~

-$v2 は
--.ps1 の中で未定義のため、 関数test1 の中でのみ有効。

-$script:s1 $v1 $v2
--.ps1 の中だけで有効なため、 スクリプトを終了した後で write-host しても値は設定されていない。

-$global:g1
--スコープがグローバルなので、スクリプトを終了しや後で write-host しても値は設定されたまま。

-通常は、
--.ps1の中でスコープが閉じると考えておき、
--.ps1の中から write-output 以外の方法でスクリプト呼び出し元へ返す情報がある場合に、$global: を使用するか検討するのがいいでしょう。
--あとは、.ps1 の中に限らず、関数間で共有の変数の場合、$script: を使用すると考えておけばいいでしょう。~

* 引数 [#r5aa018b]
ps1スクリプトへの引数

-ps1ファイルの最初に param(..) を記述することで、引数を定義出来ます。
  param (
    [string]$filename,
    [int]$count = 5
  )

-引数名を定義すると 
 powersehll .\test.ps1 -filename c:\temp\testt.txt -count 2

>の様に -引数名 として使用できます。

-[型] と引数名と、省略時の既定値も、指定できます。

-また、Mandatory属性を指定すると、必須の引数になり、省略した場合には、~
PowerShellによって、追加の引数を要求するプロンプトが表示されます。
  param (
    [Parameter(Mandatory=$True)]
    [string]$filename,
 
    [int]$count = 5
  )

-詳細は、
--下のページを参照。
---Windows PowerShell: スクリプト作成の短期集中講座~
http://technet.microsoft.com/ja-jp/magazine/hh551144.aspx
---Windows PowerShell: パラメーターを定義する~
http://technet.microsoft.com/ja-jp/magazine/jj554301.aspx~

--または、PowerShellコマンドプロンプト内で、~
「get-help about_Functions_Advanced_Parameters」を実行。

*参考 [#i3bf7513]
-Windows PowerShell: スクリプト作成の短期集中講座~
http://technet.microsoft.com/ja-jp/magazine/hh551144.aspx

----
Tags: [[:シェル]], [[:インフラストラクチャ]], [[:Windows]]

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS