Saturday, May 31, 2008

PwerShellでの関数は、パイプラインからの値を受け取ることが可能です。

パイプラインからの渡された値は $input という自動変数に格納されます。

まずは、コンソールで下記の通り入力し、pipe-func1 という関数をPowerShellに登録しましょう。

PS > function pipe-func1
>> {
>>     foreach ($a in $input)
>>     {
>>         Write-Host $a
>>     }
>> }
>>

この関数は、パイプラインで受け取った値をforeachで1つずつ取り出し表示するという単純な関数です。

以下のようにして、この関数を実験してみてください。

PS > 1..10 | pipe-func1
1
2
3
4
5
6
7
8
9
10

1..10 というのは、1から10までを表します。(範囲演算子(PowerShell 入門)を参照ください)

結果としてこの関数は$inputに1から10までの数値を受け取り、その値を表示します。

もう1つ実験してみましょう。

PS > "apple","banana","orange" | pipe-func1
apple
banana
orange

こちらは"apple","banana","orange"という3つの値が$inputに渡され、結果その値を表示します。

Saturday, May 31, 2008 10:15:35 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Friday, May 30, 2008

今回はSilverlightアプリケーションの開発手法について説明したいと思います。

前回の説明で、開発に必要なランタイムとSDKのインストールについて説明しました。

このほかにSilverlightの開発はテキストエディタが必要ですので、各自使い慣れているものをご使用ください。

1)開発単位ごとにフォルダを作成する

 Silverlightアプリケーションを開発する際には、アプリケーション単位ごとにフォルダを分けることをおすすめします。

 今回はSampleというフォルダを準備し、そこへファイルを作成していきます。

2)Silverlight.jsファイルを準備する

 Silverlightアプリケーションには、Silverlight.jsファイルが必要です。

 このファイルは、C:\Program Files\Microsoft Silverlight 1.0 SDK\Tools\Silverlight.js\localized の中にある Silverlight.ja-jp.js をコピーし、ファイル名をSilverlight.jsに変更します。

3)基本となるHTMLファイルを作成する

 次にHTMLファイルを作成します。下記は基本となるHTMLファイルです。

 <Title>~</Title>タグは、ご存じの通りWebブラウザに表示されるタイトルですので、任意に変更してください。

 4行目は 2)でコピーしてきたJScriptファイルです。

 5行目のcreateSilverlight.jsというファイルは、実際に表示されるSilverlightアプリケーション本体ファイルです。このファイルは自分で作る必要があります。ファイル名は任意で指定してかまわないのですが、これはMicrosoftの例に倣ってcreateSilverlight.js としています。

 2)でコピーしたファイル(Silverlight.js)は文字コードがutf-8となっています。このJScriptを正しく使用するために6行目が必要となります。

 下記を Sample.htm として Sampleフォルダに文字コードutf-8で保存してください。

<html>
  <head>
    <title>はじめての Silverlight</title>
    <script type="text/javascript" src="Silverlight.js"></script>
    <script type="text/javascript" src="createSilverlight.js"></script>
    <meta http-equiv="Content-type" content="text/html; charset=UTF-8"/>
  </head>
  <body>
  </body>
</html>

4)基本HTML内にSilverlightが組み込まれるエリアを作成する

 先ほどの基本HTMLをWebブラウザで表示するだけでは、Silverlightアプリケーションとして成り立ちません。

 Silverlightが組み込まれるエリアとSilverlightオブジェクトを生成するためのスクリプトを追加する必要があります。

 4-1)Silverlightを組み込むエリアの作成

 Silverlightを組み込むエリアを作成するには<div>タグを使用して下記のように記述します。

  タグ内の「sampleHost」は、任意に名前を付けてかまいません。

<div id="sampleHost"></div>

 4-2)Silverlightオブジェクトを生成する関数を呼び出すスクリプトを追加する

 次にSileverlightオブジェクトを生成するために次のようなスクリプトを追加します。

 getElementByIdで指定している「sampleHost」という名前は4-1)で指定したものと同じである必要があります。

 また、3行目でcreateSilverlightPluginという関数を呼び出していますが、この関数で実際にSilverlightプロジェクトを生成します。この関数は createSilverlight.js に記述します。

<script type="text/javascript">
    var parentElement = document.getElementById("sampleHost");
    createSilverlightPlugin();    
</script>

ここまでをまとめるとSample.htmは下記のようになります。

<html>
  <head>
    <title>はじめての Silverlight</title>
    <script type="text/javascript" src="Silverlight.js"></script>
    <script type="text/javascript" src="createSilverlight.js"></script>
    <meta http-equiv="Content-type" content="text/html; charset=UTF-8"/>
  </head>
  <body>
    <div id="sampleHost"></div>

    <script type="text/javascript">
      var parentElement = document.getElementById("sampleHost");
      createSilverlightPlugin();    
    </script>
  </body>
</html>

5)Silverlightオブジェクト本体を生成するJScriptファイルの作成

 次にSilverlightオブジェクト本体を作成するJScriptファイルですが下記のようにします。詳細については機会を改めて説明したいと思います。

 4行目はxamlファイルの参照先を示します。xamlファイルへは画像やアニメーションの設定などを記述します。

 6行目はSilverlightのプロジェクトのIDで任意に名前を付けることができますがユニークな値にする必要があります。また、ここで設定したユニークIDは3)で作成したHTMLファイルのDIVタグと連動させる必要があります。 今回ユニークIDを"sample"としているので、Sample.htmのDIVタグのIDを"sampleHost"としています。このように ユニークID + Host とする必要があることを覚えておいてください。

 8行目と9行目は、Silverlightオブジェクトの表示エリアとなります。

 14行目はSilverlightのバージョン番号を表しており、1.0を指定します。 

function createSilverlightPlugin()
{  
    Silverlight.createObject(
        "sample.xaml",                  // xamlファイルの参照先
        parentElement,                  // 親要素の定義
        "sample",                       // SilverlightプロジェクトのユニークID
        {                               
            width:'300',                // Silverlightオブジェクトの幅
            height:'300',               // Silverlightオブジェクトの高さ
            inplaceInstallPrompt:false, // インストールプロンプトを適所に表示するかどうか決定
            background:'#FF0000',       // 背景色
            isWindowless:'false',       // Windowlessモードによるプラグインを表示するかどうか決定
            framerate:'24',             // フレームレート最大値
            version:'1.0'               // Silverlightのバージョン番号
        },
        {
            onError:null,               // OnErrorのときのfunction名
            onLoad:null                 // OnLoadのときのfunction名
        },
        null);                          // イベントハンドラ名
}

6)XAMLファイル

今回は、簡単なXAMLファイルを準備しました。Hello, Silverlight World! と表示するだけのもです。

XAMLの要素についても機会を改めて説明したいと思います。

<Canvas
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <TextBlock >Hello, Silverlight World!</TextBlock>
</Canvas>

7)実行

 上記のファイルをすべてSampleフォルダへ保存したら Sample.htm をダブルクリックして実行してみましょう。

 実行結果は、こちらとなります。

 今回紹介したファイルは、こちらからダウンロード可能です。

 もしもこのサンプルをローカルではなくWebサーバー上に配置して実行したときに Hello, Silverlight World! という文字が表示されない場合はMimeタイプの設定が必要です。その際、拡張子を.xaml、Mimeタイプはapplication/xaml+xml とする必要があります。

 

Friday, May 30, 2008 9:47:52 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

少しずつですがSilverlightについても取り上げていきたいと思います。

まずは、開発環境の構築について説明したいと思います。

1)ランタイムのインストール

 Silverlight アプリケーションを動作させるにはランタイムが必要です。 Microsoftのページからインストールを行ってください。

2)SDKのダウンロードとインストール

 次にSDK(Software Development Kit)をダウンロードしてインストールを行います。

 ダウンロードはこちらからどうぞ。

 次にインストールですが、ダウンロードしてきた Silverlightv1.0SDK.msiをダブルクリックし、メニューに従ってインストールしてください。

1)[Next]ボタンをクリック

2)[I Agree]を選択して[Next]をクリック

3)インストール先を選択して[Next]をクリック

4)[Install]をクリック

5)Visual Studio 2005で開発を行いたい場合は[Install]をクリック。必要ない場合は[skip]ボタンをクリックして8)へ

6)[Next]ボタンをクリック

7)[Finish]ボタンをクリック

8)[Finish]ボタンをクリック

Friday, May 30, 2008 3:50:43 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

2008/05/30までの入門記事まとめです。

1 インストールと起動
2 コマンドレットと使用方法の調べ方
3 キー操作
4 コマンドレットの命名規則
5 エイリアスとは
6 エイリアスを作成する
7 コマンドレットはオブジェクトを返す
8 パイプライン
9 データの並べ替え
10 プロパティを抽出する Select-Object
11 特定条件でデータを抽出する Where-Object
12 ログを残す関数
13 グルーピングを行う
14 変数 その1
15 変数 その2
16 算術演算子
17 代入演算子
18 論理演算子
19 Bool値とNull値の表し方
20 比較演算子
21 範囲演算子
22 置換演算子
23 型演算子
24 スカラー比較
25 包含演算子
26 単項演算子
27 if文
28 forループ
29 whileループ
30 do/whileループ
31 foreach
32

breakとcontinue

33 switch 基本構文
34 switch 大文字/小文字の区別
35 switch ワイルドカード
36 switch 正規表現
37 switch ファイル処理
38 スクリプトについて
39 比較演算子によるコレクション比較
40 スクリプトファイルの作成
41 スクリプトファイルでの引数
42 引数の初期値を指定する
43 暗黙の引数
44 引数の明示的な指定
45 引数におけるスイッチパラメータ
46 関数の基礎
47 関数ファイルを作る
48 関数をプロファイルに追加する
49 変数のスコープ その1
50 変数のスコープ その2
51 変数のスコープ その3
52 変数のスコープ その4
Friday, May 30, 2008 3:27:45 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

今回は、グローバル変数について説明したいと思います。

グローバル変数を作成するには、global修飾子を使用します。

下記のスクリプトでグローバル変数のスコープをみて行きたいと思います。

#Scope5.ps1
01 $global:glb_a = 3
02
03 function funcA
04 {
05     Write-Host "2)$glb_a"
06 }
07
08 Write-Host "1)$a"
09 funcA
10 Write-Host "3)$a"

このスクリプトの実行結果は下記の通りです。

PS C:\Work> ./scope5.ps1
1)3
2)3
3)3

グローバル変数のスコープは、Scope5.ps1が呼び出された後スクリプトが終わるまでが有効です。

さらに、スクリプトが終了し、コンソールウィンドウに戻った後もグローバル変数は生存し続けます。

図をご覧いただければわかるように、Scope5.ps1実行後に、$glb_aを確認すると、スクリプト内部で設定した値"3"が表示されています。

コマンドラインでPowerShellに登録されている変数を確認してみましょう。

変数の一覧を確認するには dir variable: とします。

PS C:\Work> dir variable:

Name                           Value
----                           -----
Error                          {CommandNotFoundException, CommandNotFoundException}
DebugPreference                SilentlyContinue
PROFILE                        C:\Users\HIRO\Documents\WindowsPowerShell\Microsoft.P...
HOME                           C:\Users\HIRO
Host                           System.Management.Automation.Internal.Host.InternalHost
MaximumHistoryCount            64
MaximumAliasCount              4096
input                          System.Array+SZArrayEnumerator
StackTrace                        場所 System.Management.Automation.CommandDiscovery.L...
ReportErrorShowSource          1
ExecutionContext               System.Management.Automation.EngineIntrinsics
true                           True
VerbosePreference              SilentlyContinue
ShellId                        Microsoft.PowerShell
glb_a                          3
false                          False
:
:長いので省略
:

このようにグローバル変数は、一度作成するとPowerShell上で使用可能な変数となります。

また、グローバル変数は別のスクリプトファイル実行時にもスコープが及びますので、使用するときは注意が必要です。

Friday, May 30, 2008 2:26:13 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Thursday, May 29, 2008

今回はprivateスコープについて説明したいと思います。

#Scope3.ps1
01 $a = 3
02 
03 function funcA
04 {
05     Write-Host "2)$a"
06     $a = "7"
07     Write-Host "3)$a"
08     funcB
09 }
10
11 function funcB
12 {
13    Write-Host "4)$a"
14 }
15
16 Write-Host "1)$a"
17 funcA
18 Write-Host "5)$a"

まずは、上記のスクリプトですが、最初にfuncAが呼び出され、funcAの中からfuncBを呼び出すように記述してあります。

このスクリプトの実行結果は下記の通りです。

PS C:\Work> ./Scope3.ps1
1)3
2)3
3)7
4)7
5)3

このスクリプトの動作について図で説明したいと思います。

1行目の変数$aはスクリプトスコープを持つ変数となるので、有効期間は赤線の通りでスクリプトファイルの最後までとなります。

次に6行目の変数$aですが、この変数はローカル変数となりfuncAが有効期間となります。

しかし、funcAからfuncBを呼び出しているため、funcAで作成したローカル変数$aの有効期間は青線で示した箇所となってしますので注意が必要です。

では、funcA内だけで有効なローカル変数を作成した場合にはどうすれば良いでしょうか?

これを実現するにはprivate修飾子を使用します。

下記はScope3.ps1をprivate修飾子を使用したものに書き換えたものです。6行目だけが変更になっています。

#Scope4.ps1
01 $a = 3
02 
03 function funcA
04 {
05     Write-Host "2)$a"
06     $script:a = "7"
07     Write-Host "3)$a"
08     funcB
09 }
10
11 function funcB
12 {
13    Write-Host "4)$a"
14 }
15
16 Write-Host "1)$a"
17 funcA
18 Write-Host "5)$a"

このスクリプトの実行結果は下記の通りです。

PS C:\Work> ./Scope4.ps1
1)3
2)3
3)7
4)3
5)3

下図はScope4.ps1での変数のスコープを表したものです。

private修飾子を使用することで、funcBへは影響を与えなくなることがわかりますね。

Thursday, May 29, 2008 11:29:03 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

変数のスコープ その1では、スクリプトスコープを持つ変数と、関数内で有効なローカル変数について説明しました。

今回は、スクリプトスコープへのアクセスについて説明したいと思います。

その前に前回のおさらいをちょっとだけしたいと思います。

#Scope1.ps1

01 $a = 3
02
03 function Sample1
04 {
05    Write-Host "1)変数`$a=$a"
06    $a = 5
07    Write-Host "2)変数`$a=$a"
08 }
09 
10 #関数 sample1を実行
11 Sample1
12 Write-Host "3)変数`$a=$a"

1行目で作成した変数$aはスクリプトスコープを持つ変数となりますが、関数Sample1の6行目でローカル変数$aが作成されるとそれ以降関数Sample1内で$aを参照するとローカル変数である$aを参照することとなります。

これは、関数内ではローカル変数$aが優先されるからであるということは前回説明したとおりです。

ローカル変数$aが優先されている状況下の中で、スクリプトスコープを持つ$aを参照するにはどうすれば良いでしょうか?

これは、script修飾子を使用することで参照が可能になります。

このことを理解するために作成した例を下記に示します。

#Scope2.ps1
01 $a = 3
02
03 function Sample2
04 {
05     Write-Host "1)変数`$a=$a"
06     $a = 5
07     Write-Host "2)変数`$a=$a"
08     Write-Host "3)変数`$a=$script:a"
09     $script:a = 7
10     Write-Host "4)変数`$a=$script:a"
11     Write-Host "5)変数`$a=$a"
12 }
13
14 #関数 sample2を実行
15 Sample2
16 Write-Host "6)変数`$a=$a"

このスクリプトの実行結果は下記の通りです。

PS C:\Work> ./Scope2.ps1
1)変数$a=3
2)変数$a=5
3)変数$a=3
4)変数$a=7
5)変数$a=5
6)変数$a=7

最初に関数Sample2が呼び出され5行目が実行されます。ここで表示される変数はスクリプトスコープを持つ変数$aです。

次に6行目で変数$aに5を代入していますが、これはローカル変数$aとなります。

7行目で表示している変数$aはローカル変数$aです。5が表示されます。

8行目でscript修飾子を使用して、スクリプトスコープを持つ変数$aを表示しています。3が表示されます。

9行目で、スクリプトスコープを持つ変数$aに7を代入します。

10行目で、スクリプトスコープを持つ変数$aを表示します。9行目で書き換えたので7が表示されます。

11行目で、ローカル変数$aを表示します。5が表示されます。途中スクリプトスコープを持つ$aの書き換えを行いましたが影響を受けなかったことがわかります。

16行目で変数$aを表示します。この変数は関数の外なので、スクリプトスコープを持つ変数$aの表示となり7が表示されます。これは関数sample2内でscript修飾子を使用して価を7に書き換えたからです。

以上のことから

・関数内でスクリプトスコープを持つ変数へのアクセスはscript修飾子を使用する

・script修飾子を使用して値を書き換えても、同一名称のローカル変数へは影響しない

ということがおわかりいただけたかと思います。

 

Thursday, May 29, 2008 10:50:57 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

今回は、スクリプトファイルと関数内における変数のスコープについて説明したいと思います。

まずは、下記スクリプトで変数のスコープについてみていきたいと思います。左側の数字は説明上付けた行番号です。

#Scope1.ps1

01 $a = 3
02
03 function Sample1
04 {
05    Write-Host "1)変数`$a=$a"
06    $a = 5
07    Write-Host "2)変数`$a=$a"
08 }
09 
10 #関数 sample1を実行
11 Sample1
12 Write-Host "3)変数`$a=$a"

このスクリプトを実行すると結果は下記のようになります。

PS C:\Work> ./Scope1.ps1
1)変数$a=3
2)変数$a=5
3)変数$a=3

この動作について図で解説したいと思います。

まず、このスクリプトの1行目で、変数$aが作成され、3が代入されます。

この変数はスクリプト内で有効です。(1行目から12行目までがこの変数のスコープとなります)

次に、11行目で関数Sample1を呼び出します。

5行目が実行されるわけですが、ここでは1行目に作成した変数$aが参照され"3"を表示します。

次に6行目で変数$aに5を代入していますが、ここでの変数$aは1行目で作成した変数とは別のものとなります。この変数は関数Sample1内でのみ有効で生存期間は6行目から7行目までとなります。これはローカル変数と呼ばれます。

最後に、12行目が実行されるわけですが、ここでの変数$aは1行目で作成した変数$aであるため、結果として"3"が表示されます。

以上のことから

・スクリプトファイル内で作成した変数は、スクリプトファイル内すべてが有効範囲である。

・関数内で作成した変数は、関数内のみが有効範囲である。

・スクリプトファイル内で有効な変数と、関数内で作成した変数が同一名の場合は関数内で作成した変数が優先されるが、スクリプトスコープを持つ変数を上書きしない

ということがわかります。

Thursday, May 29, 2008 9:49:08 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Wednesday, May 28, 2008

最近、HIROs.NETの方の更新をサボっているわけですが、そろそろVS2008系についてもまとめていきたいと思っています。

(数名からリクエストをいただいております)

Windows アプリケーションにおけるコントロールはVS2005もVS2008も一緒なので、WPFとLINQを中心にやっていきます。

まずは、このブログで1記事ずつ書いていき、まとまったらHIRO's.NETの方へアップするというスタイルでやっていこうと思いますのでよろしくお願いいたします。

これにより現在連載中のPowerShell入門の方がおろそかにならないよう気をつけたいと思います。

そのほかにもリクエストがありましたら、ご連絡ください。

HIRO

 

Wednesday, May 28, 2008 11:25:19 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

前回の「関数ファイルを作る(PowerShell 入門)」で、関数を作成して利用する方法を紹介しました。

しかし、前回の方法では、PowerShellを終了すると、せっかく登録された関数も次回起動時には無効になってしまうという問題があります。

今回は、関数をプロファイルに登録することで、PowerShell起動時に自動で登録されるようにする方法を紹介します。

まずは、プロファイルですが、これはPowerShell起動時に1度だけ読み込まれる特別なスクリプトファイルです。

このファイルは $Profile という自動変数に格納されています。

試しにコマンドラインで $Profileを確認してみましょう。

C:\Users\HIRO\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
PS C:\Users\HIRO>

コマンドラインで下記のように入力し、メモ帳でプロファイルを開いてみましょう。

PS C:\Users\HIRO> Notepad $Profile

もしも、過去にプロファイルを作成したことがない場合は、「ファイル C:\Users\HIRO\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1が見つかりません。 作成しますか?」と聞かれるので、「はい」を選択してください。

あとは、下記のように入力してMicrosoft.PowerShell_profile.ps1を保存します。

function funcA
{
    Write-Host "funcAです"
}

保存が終わったら、PowerShellを再起動し、funcAを実行してみましょう。

PS C:\Users\HIRO> funcA
funcAです

このように、プロファイルに関数を記述すると、毎回PowerShellに関数を手動で登録する必要がなくなります。

(スクリプトの実行にはセキュリティ設定が必要ですので、動作しない場合は「スクリプトファイルの作成(PowerShell 入門)」を参考に設定してください。)

しかし、多数の関数をMicrosoft.PowerShell_profile.ps1に記述するのはメンテナンスが大変です。

これを解決する方法としてよこけんさんのサイトの「プロファイル活用」でスマートな方法が紹介されています。

実は、私自身もこの方法を採用させていただいております。

この方法を使用すれば、前回の「関数ファイルを作る(PowerShell 入門)」で説明したように、関数をファイルに保存し管理が可能になります。

ただし、1点だけ注意していただきたいことがあります。

それは、プロファイルに記述する関数はスコープを指定しなくても問題ありませんが、ファイルに記述する関数はglobalスコープが必要であるということです。

Wednesday, May 28, 2008 10:31:14 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Tuesday, May 27, 2008

今回は、関数をファイル(*.ps1)に作成し、実行する方法について説明したいと思います。

これまでに、PowerShellに関するいろいろなサイトをみてきましたが、この件に関して詳しく解説しているところを見つけられていません。

参考になるサイトを知っている方、是非情報をお寄せください。

 

まずは、テキストエディタを開いて下記のように入力し、MyFunction.ps1 として保存してください。(説明の都合上C:\Workに保存するものとします。)

function funcA
{
    Write-Host "funcAです"
}

では、この MyFunction.ps1 にある funcA を実行するにはどうしたらよいのか?

1つの方法としては、このMyFunction.ps1に下記のように1行追加すると関数funcAを呼び出すことになります。

function funcA
{
    Write-Host "funcAです"
}

funcA    #この行を追加することでfuncAを呼び出す

よって、下記のようMyFunction.ps1を実行すれば、funcAが実行されることとなります。

PS C:\Work> ./MyFunction.ps1
funcAです

関数をコマンドラインから実行する

関数をコマンドラインから呼び出す実験をするために、MyFunction.ps1を以下のようにしてください。

function funcA
{
    Write-Host "funcAです"
}

では、この関数をコマンドラインから、コマンドレットであるかのように関数名を指定するだけで呼び出すにはどうしたら良いでしょうか?

PS C:\Work> funcA
用語 'funcA' は、コマンドレット、関数、操作可能なプログラム、またはスクリプト ファイルと
して認識されません。用語を確認し、再試行してください。
発生場所 行:1 文字:5
+ funcA <<<<

関数名を記述するだけではだめなようです。

では、MyFunction.ps1にあるfuncAなので下記のようにしたらどうなるか?

PS C:\Work> ./MyFunction.ps1 funcA
PS C:\Work>

これは、エラーにもならなければ実行もされません。

実は、コマンドラインから呼び出すためには関数名の先頭にglobal修飾子が必要です。MyFunction.ps1を下記のように修正してください。

function global:funcA
{
    Write-Host "funcAです"
}

そして、関数を使用するために下記のようにしてPowerShellに関数を登録します。

PS C:\Work> ./MyFunction.ps1
PS C:\Work>

これで準備はOKです。あとはコマンドラインで関数名を記述すれば、実行されます。

PS C:\Work> funcA
funcAです

Get-ChildItemコマンドレットを使用することで、関数がPowerShellに登録されているかを確認することができます。

PS C:\Work> Get-ChildItem function:

CommandType     Name                                 Definition
-----------     ----                                 ----------
Function        prompt                               'PS ' + $(Get-Location) + $(if ($...
Function        Clear-Host                           $spaceType = [System.Management.A...
:
:長いので省略
:
Function        funcA                                Write-Host "funcAです"...

実は、今回の方法で登録した関数はPowerShellを終了すると無効になってしまいます。

次回はこの問題を解決する方法について説明したいと思います。

Tuesday, May 27, 2008 10:57:59 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Monday, May 26, 2008

今回は PowerShellでの関数の基礎について説明したいと思います。

まずは、基本構文ですが

function 関数名 {
    実行するスクリプト
}

のように記述します。

たとえば、3 + 2 を実行して表示する関数 Add は下記のように記述します。

PS > function Add { Write-Host (3 + 2) }

この関数を実行するには、コマンドラインで

PS > Add
5

とします。

引数のある関数を作成するには

function 関数名 (引数1, 引数2, 引数n) {
    実行するスクリプト
}

または、Paramキーワードを使用して

function 関数名 {
    Param(引数1, 引数2, 引数n)
    実行するスクリプト
}

のように記述します。

下記は、2つの引数を加算して返す関数Add2です。 値を返す場合には return キーワードを使用します。

PS > function Add2([int]$x, [int]$y)
>>{
>>    return ($x + $y)
>>}

この関数は、引数を2つもっているので、実行するには

PS > Add2 3 2
5

関数名の後に、値を2つスペースで区切って渡します。

Monday, May 26, 2008 11:20:45 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [2]  |  Trackback
Friday, May 23, 2008

PowerShellでは、引数に「スイッチパラメータ」と呼ばれるものを使用することができます。

スイッチパラメータを持つコマンドレットの一つに Read-Host があります。

Get-Helpコマンドで、Read-Hostのヘルプをみてみましょう。

PS > get-help read-host -Detailed

名前
    Read-Host

概要
    コンソールから入力を 1 行読み取ります。


構文
    Read-Host [[-prompt] <OBJECT>] [-asSecureString] [<CommonParameters>]


詳細説明
    コンソールから入力を 1 行読み取ります。 ユーザーに入力を要求する場合に使用できます。
    セキュリティ保護された文字列を作成する場合にも使用できます。


パラメータ
    -prompt <Object>
        これはプロンプト オブジェクトになる文字列です。 プロンプト文字列にスペースが含ま
        れている場合、そのスペースは二重引用符で囲む必要があります。

    -asSecureString <SwitchParameter>
        True に設定されてい場合、入力文字はアスタリスク (*) でエコー表示されます。 出力は
         SecureString オブジェクトになります。

    <CommonParameters>
        このコマンドレットは、次の共通パラメータをサポートします: -Verbose、-Debug、
        -ErrorAction、-ErrorVariable、および -OutVariable。詳細については、
        「get-help about_commonparameters」と入力してヘルプを参照してください。
:
:長いので省略
:

-asSecureStringのところがSwitchParameterとなっています。

-asSecureStringは引数値を必要としないパラメータであることを意味し、指定するだけで機能します。

Read-Hostはコマンドラインから1行を読み取るコマンドレットですが、-asSecureStringが指定されると入力された値は*で表されます。

PS > Read-Host -asSecureString
******
System.Security.SecureString

このように、スイッチパラメータは指定することで動作を変更することを可能にするための、引数です。

では、スイッチパラメータの作成方法についてみていきましょう。

スイッチパラメータを作成するには、スイッチパラメータにする引数の前に[switch]を付けるだけです。

下記は、単純にHelloと表示するだけのスクリプトですが、スイッチパラメータ-helpを指定すると説明が表示されるというものです。(say-hello.ps1とします)

Param ([switch]$help)

if ( $help )
{
	Write-Host "この関数は挨拶をします"
}
else
{
	Write-Host "Hello!!"
}

以下はスイッチパラメータなし呼び出した場合です。

PS C:\Work> ./say-hello.ps1
Hello!!

以下はスイッチパラメータを指定した場合です。

PS C:\Work> ./say-hello.ps1 -help
この関数は挨拶をします

スイッチパラメータの動作について理解していただけたでしょうか?

ここでスイッチパラメータのメカニズムについてみてみましょう。

スイッチパラメータは、指定すると変数に真の値(TRUE)がセットされます。

下記スクリプト(Check-Switch.ps1)を準備して実験してみましょう

param ([switch]$sw)

Write-Host $sw

スイッチパラメータを指定しない場合は、下記のようにスイッチパラメータ変数にFalseがセットされます。

PS C:\Work> ./Check-Switch
False

スイッチパラメータを指定した場合は、下記のようにスイッチパラメータ変数にTrueがセットされます。

PS C:\Work> ./Check-Switch -sw
True

ぜひ、スイッチパラメータについて理解し、今後のスクリプト開発お役立てください。

Friday, May 23, 2008 9:28:41 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Thursday, May 22, 2008

Param内に記述する引数は、明示的に指定することで、引数の順番を入れ替えることが可能です。

たとえば下記のスクリプト(sample.ps1)は、$weightと$heightの2つの引数があります。

param($weight, $height)
Write-Host ("体重:" + $weight)
Write-Host ("身長:" + $height)

まずは普通に実行してみましょう。

PS C:\Work> ./sample.ps1 60 165
体重:60
身長:165

次に、明示的に引数を指定してみましょう。

やり方は簡単で -引き数名 値 とします。

PS C:\Work> ./sample.ps1 -height 165 -weight 60
体重:60
身長:165

このように引数を明示的に指定することで、paramに記述された順番に関係なく正しく値を渡すことができます。

次の例に示すように、複数の引数がある場合は、途中まで明示的に引数を指定すれば、最後の引数は値だけ渡しても同様に動作します。

PS C:\Work> ./sample.ps1 -height 165 60
体重:60
身長:165
Thursday, May 22, 2008 10:08:16 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

CultureInfoクラスとJapaneseカレンダークラスを使用して現在の日付を和暦表示してみたいと思います。

まずは、カルチャに日本(ja-JP)を指定してCultureInfoのインスタンスを作成します。

次にこのインスタンスの.DateTimeFormat.CalendarにJapaneseCalendarをセットします。

最後に、DataTime型の日付をToStringで書式指定(ggyy年MM月dd日)することで和暦表示することができます。

*和暦変換が可能なのは明治元年9月8日からですので注意して下さい。

PS C:\Work> $ci = New-Object System.Globalization.CultureInfo("ja-JP")
PS C:\Work> $ci.DateTimeFormat.Calendar = New-Object System.Globalization.JapaneseCalendar
PS C:\Work> (Get-Date).ToString("ggyy年MM月dd日", $ci)
平成20年05月22日

特定の日を和暦表示するには、下記のようにして使用します。

PS C:\Work> $ci = New-Object System.Globalization.CultureInfo("ja-JP")
PS C:\Work> $ci.DateTimeFormat.Calendar = New-Object System.Globalization.JapaneseCalendar
PS C:\Work> ([DateTime]"1868/9/8").ToString("ggyy年MM月dd日", $ci)
明治01年09月08日
Thursday, May 22, 2008 9:19:48 AM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Wednesday, May 21, 2008

スクリプトファイルでの引数(PowerShell 入門)で、Paramキーワードを使用した引数の受け取りについて説明しました。

実はParamキーワードを使用しなくても、実行時に引数を渡し、受け取ることができます。

それには、自動変数 $args を使用します。

下記は、スクリプト実行時に渡された引数の値をコンソールに表示するという簡単なスクリプトです。ExArgs1.ps1として保存してください。

Write-Host $args

このスクリプトを下記のようにして、実験してみましょう。

PS > ./ExArgs1.ps1 "HIRO"
HIRO

実行時に渡した値は、$argsに代入されるので、結果として渡した値が表示されます。

実はこの$args変数は、複数の値を受け取ることが可能で、複数の値を受け取った場合は配列変数となります。

下記のスクリプトで実験してみましょう。ExArgs2.ps1として保存してください。

foreach ( $a in $args )
{
	Write-Host $a
}

このスクリプトを下記のようにして、実験してみましょう。

PS > ./ExArg2.ps1 "HIRO" "PowerShell"
HIRO
PowerShell

$args変数は複数の値を取得できることがおわかりいただけたでしょうか? このように、paramキーワードを使用しなくても値を受け取ることができます。

では、paramと$argsの2つを同時に使用したら、どうなるでしょうか?

下記のスクリプトで実験してみましょう。ExArgs3.ps1として保存してください。

param ($a)
Write-Host ("Paramで受け取った値 " + $a)
Write-Host ("`$argsで受け取った値 " + $args[0])

実行時に、ExArg3.ps1に値を一つだけ渡してみましょう。この結果は、下記の通りparamの引数$aに値を受け取っています。

PS > ./ExArg3.ps1 "HIRO"
Paramで受け取った値 HIRO
$argsで受け取った値

では実行時に、ExArg3.ps1に値を二つ渡した場合はどうなるでしょうか?この結果は、下記の通りでparamの引数$aには最初の値"HIRO"が、$argsにはParamで受けきれなかった値"PowerShell"が代入されます。

PS > ./ExArg3.ps1 "HIRO" "PowerShell"
Paramで受け取った値 HIRO
$argsで受け取った値 PowerShell

PowerShellでのparamと$argsの性質について理解しておくことをおすすめします。

Wednesday, May 21, 2008 10:25:17 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [4]  |  Trackback
Tuesday, May 20, 2008

PowerShellのGet-Helpコマンドレットを使用すると、特定のコマンドレットのヘルプを参照することができます。

このとき、パラメータ -Detailed を使用すると詳細なヘルプをみることができ、その中には使用例も含まれています。

たとえば、Get-Command 調べる場合は

PS > Get-Help Get-Command -Detailed

名前
    Get-Command

概要
    コマンドレットおよびその他の Windows PowerShell コマンド要素に関する基本情報を取得し
    ます。


構文
    Get-Command [[-argumentList] <OBJECT[]>] [-verb <STRING[]>] [-noun <STRING[]>] [-tota
    lCount <INT>] [-syntax] [-pSSnapIn <STRING[]>] [<COMMONPARAMETERS>]

    Get-Command [[-name] <STRING[]>] [[-argumentList] <OBJECT[]>] [-commandType {<ALIAS>
    | <FUNCTION> | <FILTER> | <CMDLET> | <EXTERNALSCRIPT> | <APPLICATION> | <SCRIPT> | <A
    ll>}] [-totalCount <int>] [-syntax] [<CommonParameters>]


詳細説明
    Get-Command コマンドレットは、コマンドレットおよびその他の Windows PowerShell コマン
    ド要素であるファイル、関数、Windows PowerShell プロバイダに関する基本情報を取得します
    。
:
:長いので省略
:
    -------------------------- 例 1 --------------------------

    C:\PS>get-command

    このコマンドは、すべての Windows PowerShell コマンドレットの情報を取得します。 既定で
    は、コマンドの種類 ("Cmdlet")、コマンドレットの名前、および構文の一覧が表示されます。




    -------------------------- 例 2 --------------------------

    C:\PS>get-command -verb set | format-list

    このコマンドは、set 動詞を持つすべてのコマンドレットの情報を取得し、その一部の一覧を

このように、ヘルプには使用例が含まれています。

このヘルプの中から使用例だけを取り出すには

PS >(Get-Help Get-Command -Detailed).Examples

のようにします。

ただ、毎回このように入力して使用例を取得するのは面倒なので関数を作成してみました。

#=========================================================================================
# Get-Example: コマンドレットの使用例を取得する
#
# UPDATE: 2008-05-20
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Get-Examples([string]$cmdlet)
{
    (Get-Help $cmdlet -Detailed).Examples
}

この関数を使用するには、Get-Examplesの後に、使用例を取得したいコマンドレットを指定するだけです。

PS > Get-Examples Get-ExecutionPolicy

-------------------------- 例 1 --------------------------

C:\PS>get-executionpolicy


このコマンドは、シェルの現在の実行ポリシーを取得します。


Restricted

-------------------------- 例 2 --------------------------

C:\PS>set-executionpolicy RemoteSigned; get-executionPolicy


これらのコマンドは、シェルの実行ポリシーの新しいユーザー設定を設定してから、有効な実行ポ
リシーを表示します。 コマンドは、セミコロン (;) によって区切られます。 この例では、グルー
プ ポリシー設定が存在しないため、ユーザー設定がシェルで有効なポリシーです。


RemoteSigned
Tuesday, May 20, 2008 10:03:14 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Monday, May 19, 2008

この記事は

記事 関数名 説明
SQL*PLUSもどきを作る1 PSOracle SQL*PLUSもどきのメイン関数
SQL*PLUSもどきを作る1の説明 PSOracle SQL*PLUSもどきのメイン関数の説明
SQL*PLUSもどきを作る2 Get-OracleConnectionStirng 接続文字列を作成する
SQL*PLUSもどきを作る3 Execute-QueryString SQLを実行した結果をDataSetに格納して返す
SQL*PLUSもどきを作る4 desc descコマンド
SQL*PLUSもどきを作る5(改訂版) Read-MultiLine コマンドラインから複数行の入力を受け取る
SQL*PLUSもどきを作る6 Execute-Query SQLを実行して、結果をコンソールウィンドウに表示する
SQL*PLUSもどきを作る7 Disconnect 切断処理

SQL*PLUSもどきを作る8

Write-SqlHistory SQL実行履歴の保存

の続きです。

前回、SQL実行履歴を保存する関数を作成しました。

今回は、SQL*PLUSもどきを作る6で作成した関数に、この機能を組み込みたいと思います。

とは、いっても一行追加するだけです。

 

#=========================================================================================
# Read-MultiLine: QueryStringを実行する
#
# UPDATE 2008/04/28		Ver.1.0.0
#        2008/05/19		Ver.1.0.1
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Execute-Query
{
	#複数行のQueryStringを受け取る
	$strSQL = Read-MultiLine
	
	#履歴の作成(Ver.1.0.1)
	Write-SqlHistory $strSQL
	
	#QueryStringを実行する
	$dtSet = Execute-QueryString $strSQL
	if ( $dtSet.Tables.Count -gt 0 )
	{
        #format-tableコマンドレットでデータを表示
        $dtSet.Tables[0].Rows | format-table
	}
}

#エイリアス設定
Set-Alias -name EQS -value Execute-Query -scope "Global"

これで、実行したSQLがXMLファイルに履歴として作成されるようになります。

Monday, May 19, 2008 5:03:30 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

スクリプトファイルの引数は、あらかじめ初期値を指定しておくことができます。

下記のように入力して、Get-TaxlusivePrice.ps1 として保存してください。

param ( $yen, $tax=1.05 )
write-Host $yen * $tax

このスクリプトは、引数$yen(税込み前価格)と$tax(税率)を持っており、$taxには初期値として1.05を与えてあります。

たとえば、100円の税込み金額を計算する場合は

PS C:\Work> ./Get-TaxInclusivePrice.ps1 100

105

のように、$taxにはあらかじめ1.05が与えられているため、結果として105が返されます。

税率を1.1で計算した場合には

PS C:\Work> ./Get-TaxInclusivePrice.ps1 100 1.1

110

のように、2つめの引数に1.1を渡します。

こうすると初期値1.05を1.1で上書きし、計算が実行されます。

このように、あらかじめ初期値を指定しておくと、その引数は省略が可能であり、また必要に応じて実行時に書き換えることが可能です。

Monday, May 19, 2008 3:57:27 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

スクリプトファイルで引数を使用するにはparamキーワードを使用します。

まずは、下記のように入力しsample1.ps1と名前をつけて保存してください。(説明の都合上 C:\Work に保存するものとします)

このスクリプトは$xと$yの変数にそれぞれ値を受け取り、加算結果を表示するスクリプトです。

param ( $x, $y )
Write-Host ("`$x + `$y =" + ( $x + $y ))

Param使用時の注意事項

paramキーワードのの前には、実行可能なスクリプトを記述してはいけないことに注意してください。

記述してもよいのは、コメント行と空の行のみです。

引数の渡し方

前回スクリプトの実行はフルパスで指定するか、先頭に./をつけて実行することを説明しました。

引数のあるスクリプトでは、これに加えて渡す値をスペース区切って記述します。

たとえば、このスクリプトに2と3の値を渡す場合は

PS C:\Work>> ./sample1.ps1 2 3

のようにします。このスクリプトを実際に実行すると

PS C:\Work>> ./sample1.ps1 2 3
$x + $y = 5

のようになります。

Monday, May 19, 2008 3:09:45 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Sunday, May 18, 2008

PowerShellにおけるスクリプトファイルはテキストエディタで作成することが可能で、拡張子はps1と決められています。

1)スクリプトファイルを作成する

テキストエディタ(メモ帳など)で下記のように入力して、Sample1.ps1として保存してください。(任意の場所でかまいませんが、説明の都合上C:\Workに保存したものとします)

$d = Get-Date
Write-Host ("ただいま" + $d + "です")

2)スクリプトファイルの実行権限を設定する

PowerShellでスクリプトファイルを実行するには、実行権限を設定する必要があります。

まずは下記のように入力して、自分の実行権限を確認します。

PS > Get-ExecutionPolicy

実行ポリシー 説明
Restricted すべてスクリプトの実行を禁止
AllSigned すべてのスクリプトに証明書を要求
RemoteSigned インターネットからダウロードしたスクリプトに証明書を要求
Unrestricted すべてのスクリプトの実行を許可

自分のPCにあるスクリプトが実行できればよいので、今回は下記のように入力してRemoteSignedに設定しましょう。

PS > Set-ExecutionPolicy RemoteSigned

3.スクリプトを実行する

スクリプトファイルは、ファイル名を入力しただけは実行することができません。 下記のようにファイル名の先頭に./をつけるか、フルパスで指定する必要があります。

PS C:\Work> ./sample1.ps1
ただいま05/18/2008 10:00:00です

Sunday, May 18, 2008 9:23:40 AM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

よこけんさん からお題をいただきましたので今回はそれを取り上げたいと思います。

比較演算子ではコレクション比較も行うことが可能です。

下記はよこけんさんに示していただいた例ですが

PS > @(1, 2, 3) -eq 2
2

左辺がコレクションの場合、右辺に一致する要素を返してきます。(通常は真偽値が返されます)

下記のようにした場合には

PS > @(1, 2, 3, 2, 1) -eq 2
2
2

一致した要素すべてが返されます。

比較演算子はif文とセットで使用されることが多いのですが、コレクション比較を行う場合は

PS > $ary = @(1, 2, 3) -eq 2

のようにすることで、比較結果を変数に代入し利用することができます。複数の値が返される場合は、当然 $ary は配列変数となります。

では、ほかの比較演算子でも、コレクション比較を行ってみましょう。

-ne 否定

-ne演算子でコレクション比較を行うと、下記のように右辺に等しくないものすべてを返します。

PS > @(1, 2, 3) -ne 2
2

-gt より大きい

-gt演算子でコレクション比較を行うと、下記のように右辺より大きいものすべてを返します。

PS > @(1, 2, 3) -gt 1
2
3

-ge 以上

-ge演算子でコレクション比較を行うと、下記のように右辺以上の値すべてを返します。

PS > @(1, 2, 3) -ge 2
2
3

-lt より小さい

-lt演算子でコレクション比較を行うと、下記のように右辺より小さいすべてを返します。

PS > @(1, 2, 3) -lt 3
1
2

-le 以下

-le演算子でコレクション比較を行うと、下記のように右辺以下の値すべてを返します。

PS > @(1, 2, 3) -le 3
1
2
3
Sunday, May 18, 2008 8:23:57 AM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Thursday, May 15, 2008

これまでのPowerShell入門を理解していただければ、今回から紹介するスクリプトや関数についてすんなりと入っていけることと思います。

今回は、PowerShellコンソール上でのスクリプトの入力方法について説明したいと思います。

まずは、コマンドラインで下記のように入力してみてください。

PS C:\Work> if ( Test-Path "Test.txt" )

この状態で[Enter]を押すと

>>

のように、">"が2個連結された文字が表示されます。

これはPowerShellがスクリプトの入力モードに入っていることを意味します。

これは、PowerShellが1行では完結しないことを認識したからです。

では、続けて下記のように入力してください

>> {
>>   Write-Host "Test.txtは存在します"
>> }
>> else
>> {
>>   Write-Host "Test.txtは存在しません"
>> }
>>

最後の"}"を入力したあと[Enter]を2回押すと、スクリプトの入力モードが終了し、スクリプトが実行され、結果が表示されます。

ただし、PowerShellがスクリプトが完結していると判断した場合だけです。もしも完結していると判断されない場合は、[Enter]を押すごとに">>"を表示し続けます。

もしも途中で、入力を終了したい場合は[Ctrl]+[C]を入力します。

このように、PowerShellでは、コンソールで直接スクリプトを入力し、実行をすることが可能です。

ただし、実行されるのは入力直後の1回だけであるため、長いスクリプトには向いていません。

ということで、次回はスクリプトファイルの作成方法について説明したいと思います。

Thursday, May 15, 2008 11:05:50 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Wednesday, May 14, 2008

PowerShellのswitchではファイルの操作を行うことが可能です。

ファイル操作を行うには-fileオプションを使用します

下記はファイルに含まれる特定文字列を含む行をカウントする例です。

PS C:\Workgt;>  switch -file c:\work\pscmd.txt
>> {
>>    "Get*" { $Cnt++ }
>> }
>> 

switchでファイル操作を行う場合、1行ずつ処理が行われます。

上記は、実行するたびに1行ずつ読み取り"Get*"かどうかを評価し、"Get*"である場合は$cntがインクリメントされます。

$cntがどうなったかを下記のようにして確認してみてください。

PS C:\Work> $Cnt
29

 

この例を実行してみたい場合は、下記のようにしてあらかじめファイルを準備してください。

下記を実行すると、コマンド一覧が記述されたファイルが作成されます。

PS C:\Work> Get-Command | Select-Object {$_.Name} > PSCmd.txt
Wednesday, May 14, 2008 11:42:05 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [4]  |  Trackback
Tuesday, May 13, 2008

PowerShellにおけるswitch は-regex パラメータを使用することで、正規表現による評価を行うことが可能になります。

下記は先頭が"H"で始まっているかを正規表現で評価しています。

PS > switch -regex ("HIRO")
>> {
>>  "(^H)" {"Hで始まっています"}
>> }
>>
Hで始まっています

-regexパラメータを使用した場合は、-wildcardと -exact は無効になります。文字列でない場合、このオプションは無視されますので注意が必要です。

Tuesday, May 13, 2008 11:38:34 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [2]  |  Trackback
Monday, May 12, 2008

現在までにこのblogで紹介した、入門記事のまとめです。

まだ進行中ですので、引き続きおつきあい願います。

 

1 インストールと起動(PowerShell 入門)
2 コマンドレットと使用方法の調べ方(PowerShell 入門)
3 キー操作(PowerShell 入門)
4 コマンドレットの命名規則(PowerShell 入門)
5 エイリアスとは(PowerShell 入門)
6 エイリアスを作成する(PowerShell 入門)
7 コマンドレットはオブジェクトを返す(PowerShell入門)
8 パイプライン(PowerShell入門)
9 データの並べ替え(PowerShell入門)
10 プロパティを抽出する Select-Object (PowerShell入門)
11 特定条件でデータを抽出する Where-Object(PowerShell入門)
12 ログを残す関数(PowerShell Tips)
13 グルーピングを行う Group-Object(PowerShell入門)
14 変数 その1(PowerShell 入門)
15 変数 その2(PowerShell入門)
16 算術演算子(PowerShell 入門)
17 代入演算子(PowerShell 入門)
18 論理演算子(PowerShell 入門)
19 Bool値とNull値の表し方(PowerShell 入門)
20 比較演算子(PowerShell 入門)
21 範囲演算子(PowerShell 入門)
22 置換演算子(PowerShell 入門)
23 型演算子(PowerShell 入門)
24 スカラー比較(PowerShell 入門)
25 包含演算子(PowerShell 入門)
26 単項演算子(PowerShell 入門)
27 if文(PowerShell 入門)
28 forループ(PowerShell 入門)
29 whileループ(PowerShell 入門)
30 do/whileループ(PowerShell 入門)
31 foreach(PowerShell 入門)
32

breakとcontinue(PowerShell 入門)

33 switch 基本構文(PowerShell 入門)
34 switch 大文字/小文字の区別(PowerShell 入門) 
35 switch ワイルドカード(PowerShell 入門)

Monday, May 12, 2008 11:33:26 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [6]  |  Trackback

PowerShellにおけるswitchで、-wildcardパラメータを使用すると、ワイルドカードによる評価を行うことができるようになります。

-wildcardパラメータは、switchと条件の間に記述します。

下記は"H"で終わるパターンと"H"で始まるパターンを評価します。

PS > $a = "HIRO"
PS > switch -wildcard ( $a )
>> {
>> "*H" { Write-Host "Hで終わる文字列です" }
>> "H*" { Write-Host "Hで始まる文字列です" }
>> }
>>
Hで始まる文字列です
Monday, May 12, 2008 11:17:57 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Sunday, May 11, 2008

switchの条件が文字列である場合は、-casesensitive パラメータを使用することで大文字と小文字の区別をできるようになります。

-casesensitiveパラメータは switchと条件の間に書きます。

下記は、変数$aに"HIRO"を代入しておき、小文字と大文字で実行するブロックが決まります。

$aには大文字が入っているので、"大文字"と表示されます。

PS > $a = "HIRO"
PS > switch -casesensitive ( $a )
>> {
>> "hiro" { Write-Host "小文字" }
>> "HIRO" { Write-Host "大文字" }
>> }
>>
大文字
Sunday, May 11, 2008 10:26:43 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Saturday, May 10, 2008

PowerShellにおけるswitchは、ほかの言語のswitchと比較すると多くの機能を持ち備えています。

何回かに分けて説明したいと思います。

まず、基本構文ですが

switch -options (評価する式)
{
  <パターン> {実行するコマンドブロック}
  <パターン> {実行するコマンドブロック}
:
  default    {実行するコマンドブロック}
}

となります。

caseというキーワードがないことに気づきましたか? VB, C, C#などの言語を使用している方にはちょっと違和感があるかもしれません。

では、早速ですが、この基本構文を使用した例を見てみましょう。

PS > switch ( $a ) {
>> 1 { Write-Host "`$a は 1 です" }
>> 2 { Write-Host "`$a は 2 です" }
>> 3 { Write-Host "`$a は 3 です" }
>> 4 { Write-Host "`$a は 4 です" }
>> 5 { Write-Host "`$a は 5 です" }
>> }
>>
$a は 3 です

上記は変数$aを評価し、該当するコマンドブロックの実行を行います。

次に一致するパターンが複数あったらどうなるかをみてみます。

PS >  switch ( $a ) {
>> 1 { Write-Host "`$a は 1 です" }
>> 2 { Write-Host "`$a は 2 です" }
>> 3 { Write-Host "`$a は 3 です" }
>> 3 { Write-Host "`$a は three です" }
>> 4 { Write-Host "`$a は 4 です" }
>> 5 { Write-Host "`$a は 5 です" }
>> }
>>
$a は 3 です
$a は three です

上記のように該当するパターンすべてのコマンドブロックを実行します。

次にbreakを使用する例を見てみましょう。

先ほどの例のパターンの値が"3"(2つあるうちの最初のほう)にbreakを仕掛けます。

PS >  switch ( $a ) {
>> 1 { Write-Host "`$a は 1 です" }
>> 2 { Write-Host "`$a は 2 です" }
>> 3 { Write-Host "`$a は 3 です"; break }
>> 3 { Write-Host "`$a は three です" }
>> 4 { Write-Host "`$a は 4 です" }
>> 5 { Write-Host "`$a は 5 です" }
>> }
>>
$a は 3 です

breakが実行されると、コードはそこで中断されてswitchを抜けるため、2つめのパターン"3"のコマンドブロックが実行されていないことがわかります。

最後にdeafultキーワードについてみてみましょう。

defaultキーワードは、どのパターンにも該当しない場合に行う処理を記述することができます。

PS > $a = 7
PS > switch ( $a ) {
>> 1 { Write-Host "`$a は 1 です" }
>> 2 { Write-Host "`$a は 2 です" }
>> 3 { Write-Host "`$a は 3 です" }
>> 4 { Write-Host "`$a は 4 です" }
>> 5 { Write-Host "`$a は 5 です" }
>> default { Write-Host "該当なし" }
>> }
>>
該当なし
Saturday, May 10, 2008 10:15:27 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [2]  |  Trackback
Friday, May 09, 2008

breakはループ制御(foreach, for, while, do)やswichないで出現した場合、そこでそのコードを終了します。

以下はforループでの break 使用例です。変数 $i が3に等しくなるとbreakが実行され、コードを終了します。

PS> for ( $i = 0; $i -lt 5; $i++ )
>> {
>>   if ( $i -eq 3 )
>>   {
>>     break
>>   }
>>   Write-Host $i
>> }
>>
0
1
2

次に continue ですが continueが実行されると、実行フローはループの先頭へ移動し、次の反復処理を行います。breakと異なるのは、ループを終了しないことです。

以下はforループでのcontinue使用例です。if文で$i % 2が真の場合(計算結果が奇数)にcontinueが実行され、実行フローがループの先頭であるforに移動します。

PS > for ( $i = 0; $i -lt 10; $i++ )
>> {
>>   if ( $i % 2 )
>>   {
>>     continue
>>   }
>>   Write-Host $i
>> }
>>
0
2
4
6
8
Friday, May 09, 2008 11:04:57 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

この記事は

記事 関数名 説明
SQL*PLUSもどきを作る1 PSOracle SQL*PLUSもどきのメイン関数
SQL*PLUSもどきを作る1の説明 PSOracle SQL*PLUSもどきのメイン関数の説明
SQL*PLUSもどきを作る2 Get-OracleConnectionStirng 接続文字列を作成する
SQL*PLUSもどきを作る3 Execute-QueryString SQLを実行した結果をDataSetに格納して返す
SQL*PLUSもどきを作る4 desc descコマンド
SQL*PLUSもどきを作る5(改訂版) Read-MultiLine コマンドラインから複数行の入力を受け取る
SQL*PLUSもどきを作る6 Execute-Query SQLを実行して、結果をコンソールウィンドウに表示する
SQL*PLUSもどきを作る7 Disconnect 切断処理

の続きです。

今回は、実行したSQLの履歴を保存する Write-SqlHistoryという関数を作成したので紹介します。

#================================================================================================
# Write-SqlHistory: SQL実行履歴の作成
#
# UPDATE: 2008-05-09 Ver.1.0.0
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#================================================================================================
function global:Write-SqlHistory([string]$SQL)
{
  #保存可能な履歴数
  $MaxHistory = 100
  $SaveFile = "$([Environment]::GetFolderPath(`"MyDocuments`"))\WindowsPowerShell\Oracle\History.xml"
  
  $UPDT = (Get-Date).ToString("yyyy/MM/dd hh:mm:ss")
  if ( Test-Path $SaveFile )
  {
    #データセットの作成
    $dtSet = New-Object System.Data.DataSet("History_Data")
    #既存ファイルの読み込み
    [void]$dtSet.ReadXml($SaveFile)
    
    #データテーブルの取り出し
    $dtTbl = $dtSet.tables[0]
    
    #保存可能数を超えた場合
    if ( $dtTbl.Rows.Count -ge $MaxHistory )
    {
      #最初の行を削除
      $dtTbl.Rows[0].Delete()
    }
    
    #新規レコードの作成
    $dtRow = $dtTbl.NewRow()
    #データをセット
    $dtRow["UPDT"] = $UPDT
    $dtRow["SQL"] = $SQL
    #データテーブルにレコードの追加
    $dtTbl.Rows.Add($dtRow)
    #XMLファイルを作成
    $dtSet.WriteXml($SaveFile)
  }
  else
  {
    #Xmlセッティングの作成
    $settings = New-Object System.Xml.XmlWriterSettings
    #エンコーディングの指定
    $settings.Encoding = [System.Text.Encoding]::UTF8
    #インデントの指定
    $settings.Indent = $True

    #XmlWriterの作成
    $xmlWriter = [System.Xml.XmlWriter]::Create($savefile, $settings)
    #要素の追加
    $xmlWriter.WriteStartElement("History_Data")
    $xmlWriter.WriteStartElement("History")
    $xmlWriter.WriteElementString("UPDT",$UPDT)
    $xmlWriter.WriteElementString("SQL",$SQL)
    [void]$xmlWriter.WriteEndElement
    #XmlWriterのClose
    $xmlWriter.Close()
  }
}

この関数は

PS > Write-SqlHistory "SELECT * FROM EMP"

のように使用します。

関数が実行されると

<?xml version="1.0" standalone="yes"?>
<History_Data>
  <History>
    <UPDT>2008/05/09 11:03:38</UPDT>
    <SQL>select * from emp</SQL>
  </History>
  <History>
    <UPDT>2008/05/09 11:03:45</UPDT>
    <SQL>select * from tbl2</SQL>
  </History>
</History_Data>

の様なXMLファイルが作成されます。UPDTタグにはSQL実行日時が、SQLタグには実行したSQLが書き込まれます。

開発ポイント

1.保存先の確認
 Test-Pathコマンドレットで保存先のXMLファイルの存在を確認します。
 保存先がある場合はDataSetを使用してXML操作を行います。
 保存先が存在しない場合はXmlWriterで新規にXMLファイルを作成します。

2.新規XMLファイルを作成する
 保存先のXMLファイルが存在しない場合はXmlWriterでXMLファイルを作成するのですが、インデントとエンコーディング指定するために XmlWriterSettings を作成します。 こうしないとインデントがされず読みにくいXMLファイルができてしまいます。
 要素の追加には WriteStartElement を使用し、値の追加は WriteElementString にて行っています。
 要素の追加が終わったら WriteEndElement を実行します。 このとき[void]を付けないと、この行を実行したときにコンソールに実行時の文字列が表示されてしまうので注意が必要です。
 最後にCloseメソッドを実行してXmlWriterを閉じます。

3.既存のXMLファイルを読み込みデータを追加する
 既にXMLファイルが存在する場合にはDataSetを使用してXML操作を行うこととしました。
 まずはNew-Object コマンドレットでDataSetを作成し、ReadXmlメソッドでDataSetに既存XMLを読み込みます。
 DataSetは複数テーブルを格納できるオブジェクトなのでデータが入っている1つめのテーブルだけを変数 $dtTblに取り出します。
 次に、延々と履歴が保存されることのないように上限値に達していないかをチェックします。上限は$MaxHistory変数に100として格納しています。もしもデータ数が上限を超えたら(dtTbl.Rows.Countが100以上)最初の1件のデータを削除するようにしています。(Deleteメソッド)
 あとは$dtTbl.NewRow()で新規レコードを作成し、各要素にデータをセットし、テーブルへの追加を行います。
 最後にDataSetのWriteXmlメソッドを呼び出してXMLファイルを作成します。

Friday, May 09, 2008 2:49:53 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

Windows OSに備わっているタスクからPowerShellのスクリプトを実行する方法を紹介します。

まずはタスクに登録するスクリプトですが、前日からタスクを実施するまでの1日間に発生したシステムイベントをファイルに保存するというスクリプト(get-SystemEvent.ps1)を作ってみました。

#現在より1日前の日時を求める
$day = (Get-Date).AddDays(-1)
#1日前から現在までのシステムイベントログを取得
$events = get-eventlog -logname system | where {$_.TimeWritten -ge $day}
#取得したイベントログをファイルへ書き込み
$events > "C:\Work\eventlog.txt"

スクリプトの説明

Get-EventLogコマンドレットを使用してシステムのイベントログを取得します。

このときパラメータ -logname system とすることでシステムイベントログを取得することができます。

1日間のイベントを取得するのですが、1日前をAddDays(-1)で取得して、whereオブジェクトで該当するイベントを抜き出して、$events変数へ保存します。

ファイルへの書き込みはリダイレクト演算子(>)を使用して行っています。

スクリプトを実行するには

PowerShellのスクリプトを実行するには、*.ps1のファイルを直接実行しようとしてもだめです。

powershell スクリプトファイルのパス

とする必要があります。

このとき、PowerShellがスクリプトの実行権限を持っている必要があります。(PowerShellにおけるプロファイルの作成(PowerShell Tips)を参照願います。)

あとは下記のようにしてタスクに登録するだけです。schtaskに関しては各自でヘルプを参照願います。

schtasks /Create /SC DAILY /ST 8:00:00 /TN GetSystemEvent /TR "powershell C:\Work\get-SystemEvent.ps1"

これで、次回のAM8:00から毎日システムイベントをファイルに落とすことが可能になります。

Friday, May 09, 2008 1:38:54 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Thursday, May 08, 2008

この記事は

SQL*PLUSもどきを作る その1(PowerShell Tips)
SQL*PLUSもどきを作る その1の説明(PowerShell Tips)
SQL*PLUSもどきを作る その2(PowerShell Tips)
SQL*PLUSもどきを作る その3(PowerShell Tips) 
SQL*PLUSもどきを作る その4(PowerShell Tips) 
SQL*PLUSもどきを作る その5 改訂版(PowerShell Tips)
SQL*PLUSもどきを作る その6(PowerShell Tips)

の続きです。

今回は切断処理を行うDisconnect関数を作成しました。

とはいってもSQL*PLUSもどき(関数PSOracle)は非接続型を採用しているため、実際には切断処理は必要ありません。

しかし、PSOracle関数を実行して、動的に登録された関数やグローバル変数をいつまでも残しておくのは気持ち悪いため、Disconnect関数を作成し、それらを削除するようにしてみました。

#=========================================================================================
# Disconnect: 切断処理の実施
#
# UPDATE: 2008-05-08
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Disconnect
{
    $ret = Read-Host ($OracleConnInfo + " から切断します。よろしいですか?( Y/N )")
    if ( $ret -eq "N" )
    {
        return
    }
    
    #PSOracle用に登録したグローバル変数を削除
    Remove-Item variable:OracleDataSource
    Remove-Item variable:OracleUserID
    Remove-Item variable:OraclePassword
    Remove-Item variable:OracleConnInfo

    #Oracle専用スクリプトファイルを格納しているディレクトリの設定
    $OracleScriptPath = "$([Environment]::GetFolderPath(`"MyDocuments`"))\WindowsPowerShell\Oracle"
    
    #存在するパス?
    if ( Test-Path $OracleScriptPath )
    {
        #PSOracle用に登録された関数の削除(長いので折り返しています。実際には1行        Get-ChildItem $OracleScriptPath -Include "*.ps1" -Recurse -Force | 
% { Remove-Item ("function:" + [System.IO.Path]::GetFileNameWithoutExtension($_.Fullname)) }
    }
    else
    {
        #実行可能なスクリプトがない場合は処理終了
        return
    }
}

使用方法ですが下記のように関数をコールするだけです。

PS > Disconnect

これで、PSOracle関連の関数は使用することができなくなります。

開発ポイント

変数と関数の削除

変数や関数を削除するにはRemove-Itemコマンドレットを使用します。

変数を削除するには Remove-Item Variable:変数名 とします。

たとえば $OracleDataSouurceを削除する場合は変数の$を取って

PS > Remove-Item variable:OracleDataSource

とします。

関数の削除も同様にして、Remove-Item function:関数名 とします。

PSOracleによって登録された関数のリストをどうやって取得するか悩みました。

登録した関数のリストを取得するいいアイディアが浮かばなかったので、邪道だとは思いましたが、ファイル名=関数名.ps1 としているので、ファイル名から拡張子を取ったものをRemove-Itemコマンドレットで削除するように記述し、関数の削除を行っています。

Thursday, May 08, 2008 4:32:32 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Monday, May 05, 2008

ちょっと気づくのが遅れたんですが、5/2にWindows PowerShell V2 Community Technology Preview 2 (CTP2) がリリースされました。

ダウンロードは

Download Windows PowerShell V2 CTP2

から行うことができます。

インストールする場合は、前のバージョンをアンインストールする必要があります。

またVer1.0とVer2.xは共存できないので注意が必要です。

Monday, May 05, 2008 11:00:19 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Sunday, May 04, 2008

foreachはコレクションに含まれるすべての項目を順番に処理します。構文は次の通りです。

foreach ( 変数 in コレクション )
{
    実行するスクリプト
}

よく知られたコレクションの一つに配列があります。下記は配列変数$weekdayから値を1つずつ取り出して表示します。

$weekdayには値が5つ格納されているので5回ループし、"Mon"から順番に値を取り出して変数$wに代入し、Write-Hostコマンドレットでコンソールに出力します。

PS > $weekday = "Mon","Tue","Wed","Thu","Fri"
PS > foreach ($w in $weekday)
>> {
>> Write-Host $w
>> }
>>
Mon
Tue
Wed
Thu
Fri

もう1つ例を示します。

下記はGet-Serviceコマンドから返される項目でStatusが「Running」になっているサービス名を表示します。

Get-Serviceコマンドレットでローカルコンピュータ上のサービスを取得し、その結果の1つ1つを$sに取り出しながらループを行います。

PS > foreach ( $s in Get-Service )
>> {
>>   if ($s.Status -eq "running")
>>   {
>>     Write-Host $s.ServiceName
>>   }
>> }
>>
Sunday, May 04, 2008 9:44:24 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [2]  |  Trackback
Saturday, May 03, 2008
Saturday, May 03, 2008 11:39:40 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback
Friday, May 02, 2008
Thursday, May 01, 2008

このBlogはhttp://techbank.jp/hiroへもクロスポストで運営しているのですが、そちらの方でRead-MultiLineメソッドの終端判定に"EOF"という文字列を指定できるかという質問がありました。

この関数はSQL*PLUSもどきで使用することを想定していたので、当初は";"が入力されたら入力を打ち切るように作りました。

(これはSQL*PLUSで実行するコマンドは";"を終端文字として判定しているからです)

しかし、このRead-MultiLineメソッドは「SQL*PLUSもどき」以外でも使用可能な関数であるため、終端判定を1文字以上でも行えるよう見直してみました。

下記が改訂版の関数です。

#=========================================================================================
# Read-MultiLine: コマンドラインから複数行の入力を受け取る
#
# UPDATE 2008/04/24		Ver.1.0.0 
#        2008/05/01		Ver.1.0.1 終了判定文字に1文字以上の文字列を指定できるよう修正
#
# copyright HIRO's.NET(http://hiros-dot.net/)
#=========================================================================================
function global:Read-MultiLine ( [string]$prompt, [string]$endChar = ";" ){
	if ($args[0] -eq "-?" )
	{
		Write-Host @"
名前:
        Read-MultiLine

概要:
        コマンドラインから複数行文字列を取得します。

構文:
        Read-MultiLine [-prompt] [-endChar]

使用方法:
        -------------------------- 例 1 --------------------------
        `$a = Read-MultiLine
        
        この例はコマンドラインから複数行を取得し行終端が";"の場合に読み取りを中止し結果を返します。
        入力の終了を判定する文字は";"が規定値です。
        
        -------------------------- 例 2 --------------------------
        `$a = Read-MultiLine -prompt "文字列を入力してください"
        
        この例はプロンプトに"文字列を入力してください"と表示した後に入力を受け付けます。
        
        -------------------------- 例 3 --------------------------
        `$a = Read-MultiLine -endChar "#"
        
        この例は入力の終了を判定する文字を"#"とします。
        ユーザー入力の行終端が"#"である場合に、入力を中断し結果を返します
        
        -------------------------- 例 4 --------------------------
        `$a = Read-MultiLine -endChar "EOF"
        
        この例は入力の終了を判定する文字を"EOF"とします。
        ユーザー入力の行終端が"EOF"である場合に、入力を中断し結果を返します
        
"@ -foregroundcolor Cyan
        return
	}
	if ( $prompt.Length -gt 0 ){ Write-Host ($prompt + ":") }
	
	while(1)
	{
		$ip += Read-Host
		if ($ip.SubString($ip.Length - $endChar.Length) -eq $endChar){ break; }
		else{$ip += "`n"}
	}
	#Write-Host $ip
	
	
	return $ip.Substring(0, $ip.Length - $endChar.Length)
}

whileの中のif文を

if ($ip.SubString($ip.Length-1,1) -eq $endChar)

から

if ($ip.SubString($ip.Length - $endChar.Length) -eq $endChar)

へ変更しました。

Thursday, May 01, 2008 10:18:03 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

do/while文は最後に評価が行われるループです。最後の評価が「偽」となった時点でループを終了します。よって、必ず1回は処理の実行を行います。

do/whileループの構文は下記の通りです。

do
{
  実行する文
}
while (条件)

下記は変数$iが5未満の場合実行します。

PS C:\Work> $i = 0
PS C:\Work> do
>> {
>>   Write-Host $i
>>   $i++
>> }
>> while ($i -lt 5)
>>
0
1
2
3
4
Thursday, May 01, 2008 10:03:54 PM (Tokyo Standard Time, UTC+09:00)  #    Comments [0]  |  Trackback

Theme design by Jelle Druyts

Pick a theme: