PowerShell の個人的メモ
たまにPowerShellでスクリプト書くので、個人的によく使うものをメモしておきたくブログに書きました。プログラム素人なので参考になるかは微妙です。
1. コマンド実行時の引数を必須にする
Param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $argHoge,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $argFuga
)
1-1. サンプル
test01.ps1
===============
Param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $argHoge,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $argFuga
)
echo "-----------------"
echo "argHoge = $argHoge"
echo "argFuga = $argFuga"
1-2. サンプルの実行結果①
引数なしでスクリプトを実行すると、対話式で値の入力が必要になります。
PS C:\> .\test01.ps1
コマンド パイプライン位置 1 のコマンドレット test01.ps1
次のパラメーターに値を指定してください:
argHoge: ほげ
argFuga: ふが
-----------------
argHoge = ほげ
argFuga = ふが
# 実行結果2
PS C:\> .\test01.ps1 あいう えお
-----------------
argHoge = あいう
argFuga = えお
1-3. サンプルの実行結果②
スクリプト実行時に引数を指定することもできます。
PS C:\> .\test01.ps1 あいう えお
-----------------
argHoge = あいう
argFuga = えお
2. 配列を使う
$targetList = @("HOGE","FUGA","PIYO")
@("xxx","xxx") という感じで配列を作ります。配列番号を指定して値を引き出すことができます。1番目の値を引き出すときは、0 番を指定します。
$targetList = @("HOGE","FUGA","PIYO")
echo $targetList
echo "------------"
echo $targetList[0]
echo $targetList[1]
echo $targetList[2]
2-1. 実行結果
PS C:\> .\test01.ps1
HOGE
FUGA
PIYO
------------
HOGE
FUGA
PIYO
PS C:\>
3. 変数を初期化する
$hoge = ""
4. 関数を定義する
functin <関数名>() { }
function 関数名(){ } で関数を定義できます。{ と } の間に処理を書きます。
関数を呼び出すときは、関数名を書きます。
4-1. サンプル
function Hoge(){
echo "function is HOGE."
}
# 関数の呼び出し
Hoge
4-2. サンプルの実行結果
PS C:\> .\test01.ps1
function is HOGE.
PS C:\>
5. エラーが発生したときに実行する処理を書く
try{
# 通常の処理
}catch{
# 通常の処理でエラーが発生したときの処理
}finally{
# 通常の処理でエラーが発生してもしなくても実行する処理
}
5-1. サンプル
echo "--- TEST 1 ERROR ---"
try{
echo "test 1 calc start"
1/0
echo "test 1 calc end"
}catch{
echo "ERROR!"
}finally{
echo "END"
}
echo ""
echo "--- TEST 2 OK ---"
try{
echo "test 2 calc start"
0/1
echo "test 2 calc end"
}catch{
echo "ERROR!"
}finally{
echo "END"
}
5-2. 実行結果
PS C:\> .\test01.ps1
--- TEST 1 ERROR ---
test 1 calc start
ERROR!
END
--- TEST 2 OK ---
test 2 calc start
0
test 2 calc end
END
PS C:\>
6. 文字列を出力する
Write-Host "xxxx"
Write-Output "xxxx"
※Write-Host,Write-Output の使い分けはよくわかってないです。
私は echo も含め適当に使っています。
6-1. サンプル
Write-Host "Write-Host で出力"
Write-Output "Write-Output で出力"
6-2. サンプルの実行結果
PS C:\> .\test01.ps1
Write-Host で出力
Write-Output で出力
PS C:\>
7. 配列の初期化
$hogeList = @()
7-1. サンプル
$hogeList = @("HOGE","FUGA","PIYO")
echo $hogeList
$hogeList = @()
echo "----"
echo $hogeList
echo "^^^"
7-2. 実行結果
PS C:\> .\test01.ps1
HOGE
FUGA
PIYO
----
^^^
PS C:\>
8. 2次元配列に値を動的に追加する
$hogeList += ,@( `
"hoge1";
"fuga1";
"piyo1";
)
@(アットマーク)の前に , (カンマ) を書くことを忘れずに!
8-1. サンプルの実行結果
$hogeList = @()
$hogeList += ,@( `
"hoge1";
"fuga1";
"piyo1";
)
$hogeList += ,@( `
"hoge2";
"fuga2";
"piyo2";
)
echo $hogeList[0][1]
echo $hogeList[1][2]
8-2. サンプルの実行結果
PS C:\> .\test01.ps1
fuga1
piyo2
PS C:\>
9. 2次元配列の値を操作する
for( $uniNum=0; $uniNum -lt $uniInfoList.Count; $uniNum++){
# 1次元目のループ
$inner_ary = $uniInfoList[ $uniNum ];
for($x=0; $x -lt $inner_ary.Count; $x++){
# 2次元目のループ
}
}
9-1. サンプル
$uniInfoList = @( @("ほげ","ふが","ぴよ"),@("HOGE","FUGA","PIYO"),@("ホゲ","フガ","ピヨ") )
for( $uniNum=0; $uniNum -lt $uniInfoList.Count; $uniNum++){
$inner_ary = $uniInfoList[ $uniNum ];
$outHoge = ""
$outFuga = ""
$outPiyo = ""
for($x=0; $x -lt $inner_ary.Count; $x++){
switch($x){
0 { $outHoge = $inner_ary[$x] }
1 { $outFuga = $inner_ary[$x] }
2 { $outPiyo = $inner_ary[$x] }
}
}
echo "LoopNumber $uniNum : subNo 1 Valu = $outHoge ; subNo 2 Value = $outFuga ; subNo 3 Value = $outPiyo"
}
9-2. サンプルの実行結果
PS C:\> .\test01.ps1
LoopNumber 0 : subNo 1 Valu = ほげ ; subNo 2 Value = ふが ; subNo 3 Value = ぴよ
LoopNumber 1 : subNo 1 Valu = HOGE ; subNo 2 Value = FUGA ; subNo 3 Value = PIYO
LoopNumber 2 : subNo 1 Valu = ホゲ ; subNo 2 Value = フガ ; subNo 3 Value = ピヨ
PS C:\>
10. スリープ
# 3秒
sleep 3
11. csvファイル読み込みと出力
$csv = import-csv c1.csv
$csv | % {
$tmpId = $_.id
$tmpName = $_.Name
echo "$tmpId : $tmpName"
}
11-1. サンプル①
$csv = import-csv c1.csv
$csvArr = @()
$csv | % {
$tmpId = $_.id
$tmpName = $_.Name
echo "$tmpId : $tmpName"
}
# c1.csv ファイル
"id","Name"
"1001","Yamada"
"1002","Suzuki"
"1003","Mikimoto"
"1004","Tanaka"
"1005","Simada"
"1006","Furuta"
11-2. サンプル①の実行結果
PS C:\> .\test01.ps1
1001 : Yamada
1002 : Suzuki
1003 : Mikimoto
1004 : Tanaka
1005 : Simada
1006 : Furuta
PS C:\>
11-3. サンプル②
$csv = import-csv c2.csv
$csvArr = @()
$csv | % {
if($_.flag1 -eq 1){
$tmpId = $_.id
$tmpName = $_.Name
echo "$tmpId : $tmpName"
}
}
# c2.csv ファイル
"id","Name","flag1"
"1001","Yamada","1"
"1002","Suzuki","0"
"1003","Mikimoto","0"
"1004","Tanaka","1"
"1005","Simada","0"
"1006","Furuta","1"
11-4. サンプル②の実行結果
PS C:\> .\test01.ps1
1001 : Yamada
1004 : Tanaka
1006 : Furuta
PS C:\>
11-5. サンプル③
csvファイルから取得した値を2次元配列に格納します。
$csv = import-csv c1.csv
$csvArr = @()
$csv | % {
if($_.flag1 -eq 1){
$csvArr += ,@( $_.id, $_.Name )
}
}
12. csv形式でファイル出力する
$csv | % {
New-Object PSObject -Property @{
id = $_[0]
Name = $_[1]
}
} | Export-Csv -Path "c2.csv" -Encoding UTF8
12.1 サンプル
$csv = import-csv c2.csv
$csv | % {
New-Object PSObject -Property @{
id = $_.id
Name = $_.Name
}
} | Export-Csv -Path "c3.csv" -Encoding UTF8
#c2.csv
"id","Name","flag1"
"1001","Yamada","1"
"1002","Suzuki","0"
"1003","Mikimoto","0"
"1004","Tanaka","1"
"1005","Simada","0"
"1006","Furuta","1"
12.2 サンプルの実行結果
出力されたc3.csvファイルの中身です。
#TYPE System.Management.Automation.PSCustomObject
"id","Name"
"1001","Yamada"
"1002","Suzuki"
"1003","Mikimoto"
"1004","Tanaka"
"1005","Simada"
"1006","Furuta"
13. 別の関数と変数の値をやり取りする
関数の前に . (ドット) をつけるとグローバル変数を操作できるっぽい(?)
※動きがよくわかってないです。
. funchoge
13-1. サンプル
$hoge=1
function Hoge(){
$hoge = 99
}
function Fuga(){
echo "---"
echo $hoge
}
Hoge
Fuga
. Hoge
Fuga
13-2. サンプルの実行結果
PS C:\> .\test01.ps1
---
1
---
99
PS >
14. 実行結果をファイルに出力する
Start-Transcript .\log_$hoge-$fuga.log -append
Write-Output "log hoge fuga"
Stop-Transcript
14-1. サンプル
Start-Transcript .\log.log -append
Write-Output "log hoge fuga"
Stop-Transcript
14-2. サンプルの実行結果
PS C:\> .\test01.ps1
トランスクリプトが開始されました。出力ファイル: .\log.log
log hoge fuga
トランスクリプトが停止されました。出力ファイル: C:\tmp\log.log
PS C:\>
# log.log の中身
**********************
Windows PowerShell トランスクリプト開始
開始時刻: 20190203214527
ユーザー名: HOST001\user001
RunAs ユーザー: HOST001\user001
構成名:
コンピューター: HOST001 (Microsoft Windows NT 10.0.17134.0)
ホスト アプリケーション: C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe
プロセス ID: 16396
PSVersion: 5.1.17134.407
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.17134.407
BuildVersion: 10.0.17134.407
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
トランスクリプトが開始されました。出力ファイル: .\log.log
log hoge fuga
**********************
Windows PowerShell トランスクリプト終了
終了時刻: 20190203214527
**********************
15. ファイルの値をiniファイル的に変数に格納する
$filename = "conf.ini"
$lines = get-content $filename -Encoding utf8
foreach($line in $lines){
if($line -match "^$"){ continue }
if($line -match "^\s*#"){ continue }
$param = $line.split("=",2)
switch ($param[0]){
"hogeVal" { $hoge = $param[1] }
"fugaVal" { $fuga = $param[1] }
default { Write-Output "Not Found : $param[0]" }
}
}
15.1 サンプル
$filename = "conf.ini"
$lines = get-content $filename -Encoding utf8
foreach($line in $lines){
if($line -match "^$"){ continue }
if($line -match "^\s*#"){ continue }
$param = $line.split("=",2)
switch ($param[0]){
"hogeVal" { $hoge = $param[1] }
"fugaVal" { $fuga = $param[1] }
default { Write-Output "Not Found : $param" }
}
}
echo "hoge = $hoge"
echo "fuga = $fuga"
# conf.ini
hogeVal=HOGEです
fugaVal=FUGAですよ
piyoVal=PIYOですかね
15.2 サンプルの実行結果
PS C:\> .\test01.ps1
Not Found : piyoVal PIYOですかね
hoge = HOGEです
fuga = FUGAですよ
PS C:\>
16. 配列から特定の要素を削除する
PS C:\> $hoge = @("A","B","C")
PS C:\> $hoge
A
B
C
PS C:\> $hoge.length
3
PS C:\> $hoge2 = $hoge -ne "B"
PS C:\> $hoge2
A
C
PS C:\> $hoge2.length
2
PS C:\>
トラブルシュート
[問題] PowerShell実行結果が文字化けする
[対策] 文字コードをShitf-JIS にする
スクリプトファイル(.ps1)に日本語などの2バイト文字があり、ファイルの拡張しが Shift-JIS 以外の場合、文字化けが発生する場合があります。
PS > .\test01.ps1
・醍分逶ョ縺ョ蛟、縺ッ縲・targetList[0] 縺ァ縺吶�・
PS >
メモ帳で文字コードを変換する場合は、[ファイル]->[名前を付けて保存]で、ANSI を選択します(ShiftJIS ≒ANSI)
こんな弱小ブログでもサポートしてくれる人がいることに感謝です。