Powershell 逆引き

# Powershell 逆引き




## 演算子・文字列
　シェルというだけあって書き方がシェルと同じように書ける。

### 「または」「かつ」（論理演算子）
- "-or" "and"で書ける[^LO]
   
```Powershell:実行例
PS C:\Users> $a = 1
PS C:\Users> $b = (2 -gt $a) -and ($a -gt 0)
PS C:\Users> $b
True
```

### 「より大きい」「より小さい」「同じ」「異なる」（比較演算子）
- "-gt" "-lt" "-eq" "-ne" で書ける。[^CO] 

### 特殊文字
|意味|エスケープシーケンス|
|:---:|:---:|
|タブ|\`t|
|改行(CRLF)|\`r`n|

### 配列に比較演算子を使うとtrueのもののみの配列を返すフィルターとして動作
　コメント欄で教えていただいて、便利だったのでメモ。[^STB]

```PowerShell:配列に比較演算子
$a = 1, 2, 3, 4, 5
$b = ($a -gt 2)
Write-Output $b

3
4
5
```

　※左辺が配列である必要がある。逆にすると以下エラー

```PowerShell:配列に比較演算子でエラー
Could not compare "2" to "1 2 3 4 5". Error: "Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32"."
At line:3 char:1
+ $b = 2 -gt $a
+ ~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : ComparisonFailure
```




## データ

### 型変換[^TC]
- 右辺の最初のデータ型に自動的に変換される
- [string][int]などで意図的に変換も可能

### 文字列の連結
- 配列に格納された文字列　→　System.String クラスの Join メソッドを使用
- 文字列の連結には【+】記号【+=】演算子を利用
- 文字列の繰り返しには【*=】演算子を利用

```Powershell:*=の例
PS C:\Users> $a = "hoge"
PS C:\Users> $a *= 3
PS C:\Users> $a
hogehogehoge
```

### 日付取得と書式変更
　Get-Dateで日付取得し、ToStringで書式を変更。[^DT]

```Powershell:日付取得の例
PS C:\Users> (Get-Date).Tostring("yyyy/MM/dd HH:mm:ss")
2017/09/12 17:07:15
```

## 入力
### 引数
　paramを使うことで引数を変数に流し込める。
　$args.length で引数の個数を。

```Powershell:引数取得・個数チェック例
PS C:\Users> cat .\paramTest.ps1
param($aaa, $bbb)
Write-Output $aaa
Write-Output $bbb
Write-Output $args.length
PS C:\Users> .\paramTest.ps1 hoge fuga
hoge
fuga
0
```

　paramは先頭に書かないと次のエラーが出る。

```Powershell:paramのエラー例
PS C:\Users> cat .\paramTest.ps1
Write-Output $aaa
param($aaa, $bbb)
Write-Output $aaa
PS C:\Users> .\paramTest.ps1 hoge fuga
param : The term 'param' is not recognized as the name of a cmdlet, function, script file, or operable program. Check t
he spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\UsersparamTest.ps1:2 char:1
+ param($aaa, $bbb)
+ ~~~~~
    + CategoryInfo          : ObjectNotFound: (param:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
```




## 出力
### 文字列出力
　以下のような出力方法がある[^OU]

- "と'
- Write-* Cmdlet
- $Host.UI
- .NET Framework

### リダイレクト
　リダイレクトが可能なので、ログファイルを作りやすい。
　リダイレクトのオプションについてはマニュアルが分かりやすい。忘れそうなものについて抜粋[^RD]

|演算子|リダイレクト内容|
|:---:|:---:|
|2>   |エラーメッセージをリダイレクト|
|*>>  |全ての出力を追記リダイレクト|



## 制御

## 分岐(if)・ループ(for/while)あれこれ

### 簡単に構文を
　他の言語とごっちゃになるので、括弧の配置だけ簡単に。

- if() {} elseif() {} else {}
- for(;;) {}
- while() {}
- do while() {}

### 変数の初期値判定
　変数の前に[bool]をつけることで、変数の初期値判定結果値を返す。
　よって、変数をif文などの条件式に入れることで、「変数が初期値かどうか」の判定が可能。
　String型であれば「""かどうか」の判定に使える

```Powershell:変数に値が入っているかどうかの判定例
$server = ""
if (!$server) {
    Write-Output "サーバー名を引数に入れてください"
    exit
}
```

### コマンド実行間隔を調整したい
- Start-Sleep(sleep)を利用[^SL]

```Powershell:Sleepの実行例
PS C:\Users> Start-Sleep 10 #10秒停止
PS C:\Users> Start-Sleep -m 1000   #1000ミリ秒（＝10秒）停止
```

### 条件分岐・ループ・ジャンプ処理
- 参考URL[^CS]参照
- swhich文の豊富さは便利
- きちんとcontinue / break があるのでループからの脱出に悩まなくてよい

### DOSのpauseに相当するものは？[^PA]
- Read-Host ”文字列”
- $host.UI.RawUI.ReadKey()　※何か入力するまで一時停止



## 関数
### 関数の再利用
　スクリプトをドットソース形式で使用することで可能。[^DS]


```Powershell:ドットソース形式例
. "hoge.ps1"
```


## プロセス・サービス

### プロセス停止まで待機
- Wait-Process を使う[^WP]
   - サービス停止まで待機するには、サービスを動かしているプロセスのPIDを取得し、そのプロセスの停止を見る方法もある

### サービスの開始・停止・再起動[^SV]

### Windows OS Versionの取得
[System.Environment]::OSVersion で取れる[^OSLevel]

```Powershell:OSLevel取得例

PS C:\> [System.Environment]::OSVersion

Platform ServicePack    Version        VersionString
-------- -----------    -------        -------------
 Win32NT Service Pack 1 6.1.7601.65536 Microsoft Windows NT 6.1.7601 Service Pack 1

PS C:\> [System.Environment]::OSVersion.Version

Major  Minor  Build  Revision
-----  -----  -----  --------
6      1      7601   65536


PS C:\> [System.Environment]::OSVersion.Version.Major
6

```



## 実行環境
- .ps1を他の環境で実行できない
   - ポリシーにより制約がかかっているため、実行ポリシーの変更を（一時的に）行う[^PS1]
- タスクスケジューラに登録したPowershellが動かない・一部エラーとなる（手動実行は成功する）
   - タスクの「セキュリティオプション」で「最上位の特権で実行する」のチェックが入っているかどうか確認。[^AdmTask]


### バージョンの確認方法
　$PSVersionTableで可能。


### デバッグについて
　良く使う手法についてはこちら。詳細は参考URLに詳しい。[^DE]

- ISEのソースコード上で、一旦止めたい場所でF9を押すと、一時停止する場所（ブレークポイント）を作成できる
- 一時停止中、コンソールウィンドウに変数名＋Enterで、その時の変数の内容を確認できる
- 再開はF5





## 参考URL

[^LO]: [03.論理演算子 < 演算子 Tips メニュー < PowerShell Tips < HIRO's.NET](http://hiros-dot.net/PowerShell/operator/operator03.htm)
[^CO]: [04.比較演算子 < 演算子 Tips メニュー < PowerShell Tips < HIRO's.NET](http://hiros-dot.net/PowerShell/operator/operator04.htm)
[^TC]: [PowerShell – 型変換を行う](http://www.itlab51.com/?p=5859)
[^DT]: [PowerShellで日付書式にカスタム書式パターンを指定する](http://tech.guitarrapc.com/entry/2013/02/09/030226)　※他にも日付の取り扱い例が豊富
[^OU]: [PowerShell での文字列出力について考える](http://tech.guitarrapc.com/entry/2014/01/17/073338)
[^SL]: [Start-Sleep コマンドレットの使用](https://technet.microsoft.com/ja-jp/library/ee177002.aspx)
[^CS]: [PowerShell制御構文](http://capm-network.com/?tag=PowerShell%E5%88%B6%E5%BE%A1%E6%A7%8B%E6%96%87)
[^PA]: [[PowerShell] コマンドプロンプトの"pause"的なモノ](https://blogs.yahoo.co.jp/hanahathouse/62725199.html)
[^WP]: [【Wait-Process】PowerShellで実行中のプロセスが停止するのを待つ方法](https://cheshire-wara.com/powershell/ps-cmdlets/system-service/wait-process/)
[^SV]: [PowerShell サービス取得・変更を行うコマンドレットのまとめ](http://nasunoblog.blogspot.jp/2014/01/powershell-get-service-matome.html)
[^PS1]: [Powershellを楽に実行してもらうには](http://qiita.com/tomoko523/items/df8e384d32a377381ef9)
[^OSLevel]: [PowerShell で Windows OS Versionを取得する \- tech\.guitarrapc\.cóm](http://tech.guitarrapc.com/entry/2013/10/25/075920)
[^AdmTask]: [管理者権限が必要なPowershell をタスクスケジューラで動かす場合](https://social.technet.microsoft.com/Forums/ja-JP/1ad41fac-b8f7-4ecf-818c-a37554885590/powershell-?forum=powershellja)
[^DE]: [Windows PowerShell ISE でスクリプトをデバッグする方法](https://docs.microsoft.com/ja-jp/powershell/scripting/core-powershell/ise/how-to-debug-scripts-in-windows-powershell-ise?view=powershell-5.1)
[^RD]: [about_Redirection](https://technet.microsoft.com/ja-jp/library/hh847746.aspx)
[^DS]: [Windows PowerShell 関数をスクリプトで再利用する方法はありますか](https://gallery.technet.microsoft.com/scriptcenter/b590021a-b311-47f9-8f48-3809658b7cbf)
[^STB]: [PowerShellの演算子一覧 \- しばたテックブログ](http://blog.shibata.tech/entry/2015/12/03/000000)