パワーシェル備忘録

概要

マイクロソフト社が開発したCUIまたはそこで使用する言語を指す。拡張子は ps1。

コマンドプロンプトでは細かい処理が難しかったが、 その機能拡張版のようなもの。

たとえばコマンドプロンプトではテキスト単位でしか値を渡すことができないが、PSではオブジェクトを渡すことができる。型付けも可能。

というのも、.NET上で動くため、.NETのフレームワークが使用できる。

入力するコマンドはコマンドレットと呼ばれ、 <動詞>-<名詞>で構成される。

cdなども使用できるが、これらはコマンドレットに対し、エイリアスが設定されているからである。

バージョン確認

$psversiontable

参考

チートシート

PowerShell 使い方メモ

基本操作

コメント:#

# 行全体がコメント
<#
複数行コメント
#>

コンソール出力

Write-Host

Write-Host “aaa”
Write Host aaa でも可だが、 文字列の間にスペースがある場合は、全体をダブルクォーテーションで括る。

※コンソール出力内での計算はできないかも

${a} “test”
Write-Host {a} + “wao” #test + wao

echo

Write-Outputのエイリアス。Write-Hostと異なり、 出力ストリームに渡す。

特にその後扱いが無ければコンソールに出力されるが処理が挟まってしまう場合がある。

特に関数内で使用すると、 戻り値として指定がされるらしい。

スクリプトファイルの実行

バッチファイルと異なり、 ダブルクリックでは実行できない。以下のコマンドで実行する。

.\ファイル名

置換

$hoge = 置換文字列 -replace "置換前", " 置換後"

処理の終了、中断

exit  // 引数に終了コードを渡すこともできる

変数の使用

${変数} = "hoge"
echo ${変数 } #hoge

※$変数でも使用できるが、文字列が連結されている場合など変な挙動をすることがあるので{}を付ける

型判定

$obj.GetType()

文字列リテラル

$a = "aaa"
echo "hoge $a"  #hoge aaa
echo 'fuga $a' #fuga $a

文字列結合

echo ("hoge" + "fuga") #hogefuga

エスケープシーケンス

  • タブ:`t
  • キャリッジリターン:`r
  • 改行:`n
  • ダブルクォーテーション:`”

if文

if ("test" -eq $value) {
  // 処理
}

比較演算子

  • -eq : 等しい
  • -ne:等しくない
  • -like:含む
  • -notlike:含まない
  • -match:正規表現比較
  • -contains:含む(配列)

like句でワイルドカード指定

if ( $value -like "P*She??" )
*:任意の文字列
?:任意の1文字

for文

for ($i = 0; $i -lt 3; $i++) {
  echo $i
}
foreach ($i in @(1, 2, 3, 4)) {
  echo $i
}

%はForeach-Objectを意味する

例) $my_ary = @('first', 'second', 'third');
※以下はすべて同じ
$my_ary | %{Write-Host $_;}
$my_ary | ForEach-Object{Write-Host $_;}
$my_ary | foreach(Write-Host $;}
foreach($value in $my_ary) {Write-Host $value;}

特定の文字列を含む

${str}.contains("${str}")

配列から判定する場合:contains

${arr} -contains $str
#配列arrが文字列 strを含むとき True

ファイル操作

カレントディレクトリとディレクトリの移動

Set-Location  ※エイリアス: cd
Get-Location  ※エイリアス:pwd ??

ディレクトリ作成

New-Item -Force -Path ${today} -ItemType Directory
mkdir -f ${today}
※ -Force -f は同名のディレクトリがあった場合でも強行する

ファイル取得

$content = (cat sample.txt)
echo $content #sample.txtの中身が出力される
catはGet-Contentのエイリアス

指定したファイルがあるか確認する

Test-Path "C:\temp\script\users.txt"  #True or False

テキストファイルを1行ずつ処理

パイプライン構文

cat sample.txt | % { echo "<li>$_</li>"}
#ForEach-Object にパイプすることで、 1行ずつ処理できる。 ($_に1行ずつ格納される)
<li>sample.txtの1行目</li>
<li>sample.txtの2行目</li>
<li>sample.txtの3行目</li>

ちゃんと書くと、

cat sample.txt | foreach ($i){
  echo $i #"$i"に1行ずつ格納される
}

文字列検索:Select-String

grep的なもの。主なオプション引数は以下。

  • -Path:ファイルのパスを指定する。 省略可能
  • -Pattern:検索するテキストを文字列または正規表現で指定する
  • -NotMatch:指定したパターンに一致しないファイルを検索する
  • -CaseSensitive:大文字と小文字を区別する。省略時は区別されない
Select-String C:\Work\*.* -Pattern "abc"
#Work配下から、 abcという文字列を含ファイル検索

ただし、検索対象にファイルではなくフォルダが存在する場合エラーが起きる可能性があるので、汎用的には以下が実用的。

Get-ChildItem "[フォルダパス]" -Recurse -File | Select-String -Pattern "[SearchText]" -List

Windows従来のfindstrでも可。

findstr 文字列

csvの読み込み:Import-Csv [filepath]

参考:PowerShell で csv を扱う方法まとめ

デフォルトではヘッダー行ありで読み込む。無い場合は以下のオプションでヘッダー名を配列で指定する。

-Header "col1", "col2", "co13"

戻り値はオブジェクトになっている

${sampleCsv} = Import-Csv [filepath]  #変数 sampleCsvに格納
Where-Objectでのフィルタリングなどが利用できる

■値の抽出

ヘッダー名: headを持つ csvを読み込んだとすると、 head列の値の取得は以下でできる。(多分リストオブジェクト)

${sampleCsv}.head

さらにこの列の6番目のデータを取得したいのであれば以下

${sampleCsv}.head[5]

※ヘッダー行は飛ばして0はじまり。 すなわち、 ヘッダーのすぐ下の値を参照したい場合に0を指定する。

■indexの取得

検索対象$strが何行目にあったのか知りたい場合

$idx = $arr.IndexOf($str)

カレントディレクトリ

Get-Location
pwd

パスの結合:Join-Path [pathA] [pathB]

パワーシェルでは、Get-Locationの戻り値はSystem.Objectであり、文字列として以下のような操作はできない。

Get-Location + "test.txt"
エラー:[System.Management.Automation.PathInfo] に 'op_Addition という名前のメソッドが含まれない〜

パスを結合する場合には以下のようにする。

Join-Path Get-Location /test.txt

スラッシュは無くても補完してくれるのでとても便利。

配列

${array} = @("hoge", "fuga", "piyo")

#@()は配列の宣言。省略することもできるが、空の配列、連想配列を使用するとき、配列のutilメソッドを使用するときなどに必要になるため、書いておく方が無難。

echo $array.GetType().Name  #Object[]
echo ($array[0] + ", " + $array[1] + ", " + $array[2])  #hoge, fuga, piyo

セパレーター

Write-Host @(100, 200, 300) -Separator "::"
#100::200::300

関数

関数定義

※基本は値渡し?

function SampleFunc ($arg) {
  return $arg + 1
}

呼び出し

SampleFunc 2 4

コンソール系

パイプライン構文

LinuxやTypescript系言語でもおなじみのパイプライン構文が使える。

(コマンド1) | (コマンド2)
ipconfig | Select-String -Pattern "IPv4"  #ipconfigからIPv4の情報のみ表示
Write-Output @(2,4,6,8,10,12) | Select-String 2 #2と12のみが出力される

入力中の文字列クリア

Esc

インシデント

スクリプト実行時エラー:用語が認識されない

用語'●●'は、コマンドレット、関数、スクリプトファイル、または操作可能なブログラムの名前として認識されません

ファイル実行する際、パワーシェルでは、冒頭に「.\」を付ける必要がある。

Select-String を実行しようとしたらエラー

Select-String .\* -Pattern "SearchText"

ファイル xxx を読み取れませんでした:パス ‘xxx’ へのアクセスが拒否されました。

特定のパス配下を再帰的に検索する場合、フォルダに対しても Select-String を実行してしまいエラーとなる。

対象をファイルだけに限定して実行する。

Get-ChildItem "[フォルダパス]" -Recurse -File | Select-String -Pattern "[SearchText]" -List

スクリプト実行時エラー:ポリシー設定による制限

このシステムではスクリプトの実行が無効になっているため、ファイル XXX を読み込むことができません。

ポリシーには以下のレベルがあり、会社の情報セキュリティ部門などで統制されている。

パワーシェルのスクリプトに対し、高いポリシー制限がかかっているとこのエラーが発生する。

  • Restricted:スクリプトの実行を禁止します(デフォルト設定)。
  • AllSigned:信頼された発行者によって署名されたスクリプトのみを実行します。
  • RemoteSigned:ローカルで作成されたスクリプトは実行できますが、インターネットからダウンロードされたスクリプトは署名が必要です。
  • Unrestricted:すべてのスクリプトを実行できますが、インターネットからダウンロードされたスクリプトは実行前に警告が表示されます。

まずはポリシーの設定を確認する。

Get-ExecutionPolicy
// Restricted

現在のユーザーに対して実行ポリシーを RemoteSigned に設定

※ 管理者権限が要求される場合は、PowerShell を管理者として開き直す

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

再度ポリシーの設定を確認

Get-ExecutionPolicy
// RemoteSigned

改めて実行すると正常終了した。

全文を表示したい

ファイルの中身が長いと、一定の長さで『:』が表示され、以降は表示されない。

もちろんEnterを押して、続きの文字を見ることはできるのだが、全文を見たいときは不便。

そんなときはOut-Hostを追加する。

処理内容 | Out-Host

出力がテーブル形式やリスト形式なら、Format-Tableを使用する。

処理内容 | Format-Table -AutoSize

 

 

コメント

タイトルとURLをコピーしました