はじめに
- 今まではbash/ksh(UNIX系)を使うことが多かった
- コマンドプロンプトで特段困ってなかったので、避けていた
- 担当プロジェクトで使うことになった
- 勉強したら、まあまあ便利かも ←いまここ
Powershellとは?
- コマンドプロンプトと同じくWindowsのCLIツール
- パイプ処理でオブジェクトを扱える
- Windows Server 2008 / Windows 7から標準機能として搭載
- 今はOSS化してWindows以外でも動く(PowerShell Core)
抑えておきたい概念
コマンドレット
- Powershellランタイムで動くコマンド
- [動詞-名詞]の命名規則
-
Get-Command
:コマンドレットの一覧を取得するコマンド- 詳細は、MSリファレンス(Get-Command)参照
-
Get-Help
:コマンド詳細調べる- 詳細は、MSリファレンス(Get-Help)参照
- エイリアス(別名)で呼び出せる(Set-Location→cd 等..)
-
Get-Alias
:エイリアス一覧取得するコマンド - 詳細は、MSリファレンス(Get-Alias)参照
-
- コマンド入力中にTABキーで補完が効く
- コマンドレットは戻りとして「.NET Frameworkのオブジェクト」を返す
- パイプ処理(|)でコマンドを組み合わせできる
例)1MBを超えるサイズのpngファイル名とサイズを表示
Get-ChildItem -Path *.png |
Where-Object {$_.length -gt 1MB} |
Sort-Object -Property length |
Format-Table -Property name, length
ドライブ
- PowerShell上のコマンドレットからアクセス可能な「データの保管場所」のこと
- Cドライブなどに加え、「レジストリ」や「証明書ストア」もドライブとして使用できる
-
Get-PSDrive
:現在のセッションで利用可能なドライブを一覧表示- 詳細は、MSリファレンス(Get-PSDrive)参照
- プロバイダはドライブの実装でドライバの機能を実際に提供している(NET Frameworkベースのクラス・ライブラリ)
実行方法
- スクリプトファイルは「.ps1」の拡張子となる
- ただし、標準ではダブルクリックでPowershellが実行される訳ではない
- コマンドラインでの実行例
PS > .\Sample.ps1
PS > C:\work\Sample.ps1
※「.ps1」の部分は省略できる
- 実行後リターンコードは、
echo $LASTEXITCODE
で取得できる
初回実行
スクリプト実行ポリシーを設定する必要あり
PS > Set-ExecutionPolicy RemoteSigned
実行ポリシー | 概要 |
---|---|
Restricted | すべてのスクリプトを実行不可 |
AllSigned | すべてのスクリプトに証明書を要求 |
RemoteSigned | インターネット経由でダウンロードしたスクリプトのみ証明書を要求 |
Unrestricted | すべてのスクリプト実行を許可(ただしインターネット経由でダウンロードしたコードは実行確認のみあり) |
変数
- 先頭文字は「$」で始まること
- 2文字目以降は任意の英数字、またはアンダースコア(_)であること
- 「\${Windows PowerShell + .NET Framework}」のような\${~}では任意の文字が使える
スコープ
- 変数/関数/エイリアス/ドライブがスコープを持つ
種類 | 意味 | 変数の指定 |
---|---|---|
グローバル・スコープ | スクリプトの外からでもアクセス可 | $global:x |
スクリプト・スコープ | スクリプト内であればどこからでもアクセス可 | $script:x |
ローカル・スコープ | 宣言されたブロック内かその子ブロック内からアクセス可 | $local:x |
プライベート・スコープ | 宣言されたブロック内からのみアクセス可 | $private:x |
こちらの記事には、コードによる解説と詳細の説明があり、大変参考になります。
変数の型
- 型は動的に解釈されるため、以下のような不具合の可能性がある(前者は文字列連結、後者は整数の加算として処理される)
PS > $x = "1"
PS > $y = 2
PS > $z = $x + $y
PS > Write-Output $z
12
PS > $x = 1
PS > $y = "2"
PS > $z = $x + $y
PS > Write-Output $z
3
- 明示的に型指定(キャスト構文)もできる
PS > [System.Int32] $x = 10
- 型名のエイリアス
エイリアス | .NET Frameworkの型名 |
---|---|
byte | System.Byte |
int | System.Int32 |
long | System.Int64 |
single、float | System.Single |
double | System.Double |
decimal | System.Decimal |
char | System.Char |
bool | System.Boolean |
string | System.String |
array | System.Array |
xml | System.Xml.XmlDocument |
type | System.Type |
文字列
- 4種類ある
- シングルクォートで囲まれた文字列
- ダブルクォートで囲まれた文字列
- シングルクォートで囲まれたヒア・ドキュメント
- ダブルクォートで囲まれたヒア・ドキュメント
- 変数の展開については、2.(ダブルクォート)を使用すること ※1.(シングルクォート)は変数が展開されない
PS > $name="鈴木"
PS > Write-Output "私の名前は $name です。"
私の名前は 鈴木 です。
PS > Write-Output '私の名前は $name です。'
私の名前は $name です。
- 特殊文字のエスケープ文字は「`」(バッククォート)※「\」はパス区切りなので使われない
エスケープ・シーケンス | 概要 |
---|---|
`b | バックスペース |
`n | 改行 |
`r | キャリッジ・リターン |
`t | タブ |
- ヒア・ドキュメント
「@"<改行>~<改行>"@」(または「@'<改行>~<改行>'@」)を文字列の区切りとする
PS > $body=@"
>> これは1行目
>> 次は2行目
>> "@
>> #ここでEnter押下
PS > Write-Output $body
これは1行目
次は2行目
配列・連想配列(ハッシュテーブル)
- 配列の定義
- $array=要素, 要素, 要素, ...
- $array=@(要素, 要素, 要素, ...)
- 連想配列の定義
- $map=@{キー名=値; キー名=値; ...}
アクセス方法は以下の通り
- 配列の定義
- $array[インデックス番号]
- 連想配列の定義
- $map["キー名"]
- $map.キー名
.NET Frameworkライブラリの利用
- PowerShellは.NET Frameworkライブラリを使って、通常のコマンドレットより高度な操作ができる
- 現在ロードされているアセンブリの確認方法
PS > [Appdomain]::CurrentDomain.GetAssemblies() | %{$_.GetName().Name}
mscorlib
Microsoft.PowerShell.ConsoleHost
System
System.Core
System.Management.Automation
Anonymously Hosted DynamicMethods Assembly
Microsoft.PowerShell.Security
System.Transactions
Microsoft.PowerShell.PSReadline
Microsoft.PowerShell.Commands.Utility
System.Configuration.Install
- 例)System.Collections.ArrayListクラスを利用する
PS > $list=New-Object System.Collections.ArrayList
PS > $list.Add("a")
0
PS > $list.Add("b")
1
PS > $list.Add("c")
2
PS > $list
a
b
c
PS > $list.Count
3
- 静的メンバにアクセスする場合は「::」演算子を使う
PS > [Math]::Pow(2, 3) #2^3 = 8
8
構文
比較演算子
演算子 | 概要 | 例 |
---|---|---|
-eq | 等しい(=) | $_.Name -eq "hoge" |
-ne | 等しくない(≠) | $_.Name -ne "hoge" |
-gt | より大きい(>) | $_.Length -gt 1MB |
-ge | 以上(≧) | $_.Length -ge 1MB |
-lt | 未満(<) | $_.Length -lt 1MB |
-le | 以下(≦) | $_.Length -le 1MB |
-like | あいまい検索(ワイルドカード) | $_.Name -like "*.log" |
-match | 正規表現検索 | \$_.Name -match "^[0-9]{3}-[0-9]{4}\$" |
if構文
$x = 10
if($x -ge 8){
Write-Output '$xは8以上です。'
}elseif($x -ge 5){
Write-Output '$xは5以上8未満です。'
}else{
Write-Output '$xは5未満です。'
}
$xは8以上です。
switch ~ case構文
$x = 1
switch($x){
1 {
Write-Output '$xは1です。'
break
}
2 {
Write-Output '$xは2です。'
break
}
3 {
Write-Output '$xは3です。'
break
}
default {Write-Output '$xは1、2、3ではありません。'}
}
Tips
-wildcardや-regexオプションで正規表現の判定ができる
$x = "北海道札幌市"
switch -wildcard ($x){
"*札幌*" {Write-Output '$xは"札幌"を含みます'}
"*小樽*" {Write-Output '$xは"小樽"を含みます'}
"*函館*" {Write-Output '$xは"函館"を含みます'}
}
ループ構文
for文
$ary=@(100,200,300)
for($i=0; $i -lt 3; $i++){
$sum += $ary[$i];
}
Write-Output $sum
foreach文
$ary=@(100,200,300)
foreach($dat in $ary){
$sum += $dat;
}
Write-Output $sum
while文
$i=0;
$sum=0;
$ary=@(100,200,300)
while($i -lt 3){
$sum += $ary[$i];
$i++;
}
Write-Output $sum
do ~ while文
$i=0;
$sum=0;
$ary=@(100,200,300)
do{
$sum += $ary[$i];
$i++;
}while($i -lt 3)
Write-Output $sum
do ~ whileは後置判断となるので、必ず1回は処理が実行されることに注意してください。
関数
構文規則
function 関数名 [(引数[=デフォルト値],...)] {
関数の本体
[return 戻り値]
}
例)三角形の面積を求める関数
function Triangle([double] $width=1, [double] $height=1) {
return $width * $height / 2
}
Triangle 3 6
9
まとめ
まずは、基礎的な概念や構文についてまとめてみた。
Microsoft社が開発したシェルのため、Windowsがやはりメインターゲットとなるが、.NET Frameworkベースのため拡張性や高機能性が魅力。
オブジェクト指向のパイプ処理を上手く使いこなすのが、初心者には第一関門になりそう。
一度使って慣れると、様々な業務の定型作業を自動化できそう。
To be continued.
次回は、実用的で便利なスクリプトについて記事を挙げてみようと思う。
- ファイルの一括操作
- Excelやxmlの読み書き
- プログラム自動生成
- DBとの連携
etc..
以上