PowerShell入門

変数の指定方法

変数名の指定は次のような形で指定する。

$変数名 = 値

改行を含む文字列を書く場合には@で囲むようにして書く。

$NameVariable = hoge # $変数名 = 値
$strVariable = "hoge" # 文字列は”で囲む
$arrayVariable = 1, 2, 3, "Hello World"
$strNewlines = @"
hoge hoge
hoge hoge
"@

処理中の変数

処理中の変数は$_で示される。

下記で触れるパイプラインで処理の対象になっている変数を意味する。

変数の型

[型名] $変数名 = hoge とすることで型指定した変数の指定が可能である。

[string] $strVariable = "hoge" 
[int] $numVariable = 10

リストの作成

下記のようにカンマ区切りで値を指定すればリストを作成することができる。

また、X..X’のようにすれば指定範囲に該当するリストを作成できる。

$List1 = 1, 2, 3
$List2 = 1..10 # 1から10までのリスト

$List3 = (1, 2, 3) # ()で囲んでも良い
$List4 = @(1, 2, 3) # @と()を使う場合もリスト作成の構文の一つ(多くの場合は省略される)
$List5 = @((1,2,3),(10,20,30)) # リスト内にリストを入れることもできる。

$List = @() # 空のリストを作成

リストのサイズ指定

$List = New-Object string[] 5
$List[4] = "Four"
$List[4] # →Fourと表示される

$List[5] = "Five"
# →「インデックスが配列の境界外です。」とエラーになる。

リスト要素の取扱い

リストの要素はインデックスを使って指定することができる。
インデックスは0から始まるため、一番目のデータのインデックスは0、二番目のデータのインデックスは1となる。

$リスト名[インデックス番号] の形で指定する。

$list = 1..10
$list[0] # 1と表示される。
$list[0,1] # 1と2が表示される。
$list[0..2] # 1から3までの数字が表示される。
$list[-1] # 10が表示される。逆順の一番初め

追加と更新

好きなインデックスを指定してデータの内容を書き換えることができる。

また、リストとリストを加算することでデータを一まとめにしたリストを作成することができる。

$list1 = 1..10
$list2 = 21..30
$list1[4] = 100 # リスト1の5番名の値を100に変更

$total = $list 1 + $list2 # list1とlist2の要素からなるリストができる。
$total += 100 # リストtotalに要素として100を追加

ArrayList

通常のリストでも要素の追加は前述の方法でできるものの、頻繁に要素の追加や削除、変更を行う場合にはArrayListを作成して使ったほうが便利である。

作成や要素の追加、削除の方法は以下のように行う。

$arrayList = New-Object System.Collection.ArrayList # ArrayListの作成
$arrayList.Add("One") # 要素の追加
$arrayList.Remove("One") # 指定要素を削除
$arrayList.AddRange(("one","two","three","four","five")) # 複数要素の一括追加
$arrayList.RemoveAt(3) # インデックス番号3の要素を削除

各リスト要素のループ処理

$list = 1..10
$total = 0
$list | Foreach-Object {$total += $_} # リスト要素の合計値計算

コメントアウト

以下のように#に続く内容がコメントとして扱われる。

# hoge

他のexeファイルの実行

exeファイルを実行する方法は以下の通り。

ファイル名にスペースが入る場合には&を頭につけ、ファイル名をシングルクォートで囲む。

hoge.exe arguments # フルパスにて指定
.\hoge.exe arguments # カレントディレクトリ内のファイルを指定して実行
& 'hoge hoge.exe' arguments # パスに半角スペースが入るファイルの実行

Cmdletの基本

cmdlet(コマンドレット)は、PowerShell上でのコマンドのこと。

形としては、動詞-名詞 の形で指定をする。
(下記例は大文字小文字で書いているが、全て小文字/大文字でも問題ない)

例:Get-ChildItem

例:Set-Location c:\ # c:\へカレントディレクトリを変更

コマンドレットの実行結果に対して簡単なフィルターをかけることもできる。

例としてgから始まるエイリアスを取得してみる。

(エイリアス:コマンドレットなどに使用する別名のこと)

Get-Alias g* # gで始まるものに限定

# 以下が結果

CommandType     Name                                               Version    Source  
-----------     ----                                               -------    ------  
Alias           gal -> Get-Alias                                                      
Alias           gbp -> Get-PSBreakpoint                                               
Alias           gc -> Get-Content                                                     
Alias           gcb -> Get-Clipboard                               3.1.0.0    Micro...
Alias           gci -> Get-ChildItem                                                  
Alias           gcm -> Get-Command                                                    
Alias           gcs -> Get-PSCallStack                                                
Alias           gdr -> Get-PSDrive                                                    
Alias           ghy -> Get-History                                                    
Alias           gi -> Get-Item                                                        
Alias           gin -> Get-ComputerInfo                            3.1.0.0    Micro...
Alias           gjb -> Get-Job                                                        
Alias           gl -> Get-Location                                                    
Alias           gm -> Get-Member                                                      
Alias           gmo -> Get-Module                                                     
Alias           gp -> Get-ItemProperty                                                
Alias           gps -> Get-Process                                                    
Alias           gpv -> Get-ItemPropertyValue                                          
Alias           group -> Group-Object                                                 
Alias           gsn -> Get-PSSession                                                  
Alias           gsnp -> Get-PSSnapin                                                  
Alias           gsv -> Get-Service                                                    
Alias           gtz -> Get-TimeZone                                3.1.0.0    Micro...
Alias           gu -> Get-Unique                                                      
Alias           gv -> Get-Variable                                                    
Alias           gwmi -> Get-WmiObject  

パラメーターの指定

パラメーターを指定して利用することが非常に多い。

パラメーターで指定するには、動詞-名詞 -パラメーター 指定条件 の形にする。

指定例を示すと以下のようになる。

Get-Process -Name "chrome" # プロセス名がchromeのプロセスを取得

Pipeline

Pipelineは初めの処理の結果を次の処理の入力値に使うようにして、アウトプット→インプット・アウトプット→インプットのように連続した処理を行うことができる。

以下のように各処理をパイプライン | で区切って書く。

処理1のアウトプットを処理2に渡し、それをもとに処理、処理結果を処理3に渡すことになる。

処理1 | 処理2 | 処理3

結果の出力

パイプラインを使えば出力結果をスムーズ、簡単に出力して保存することができる。

CSV形式での出力

Get-Service | Export-csv -Path hoge.csv # 指定したパスhogeにcsv形式で結果を出力する。

テキストファイル形式での出力

Get-Service | out-file -FilePath hoge.txt

Foreach-Objectによる各リスト要素の操作

リストの各要素に何らかの操作を加える場合にはForeach-Objectを使うことで、それが実行できる。

また、パラメーターとして-Begin, -Process, -Endを渡すことでより細かい指定も可能である。

$List1 = 1,10,100,1000
$List1 | Foreach-Object { $_ * 10} # List1の各値を10倍する
$List1 | Foreach-Object -Begin{$Total=0} -Process{$Total += $_} -End{$Total}
# ↑合計値算出。-Begin, -Process, -Endは省略可能。

Where-Objectでフィルターをかける

Where-Objectで調べる値を与えることでフィルターをかけることができる。

例えば、chromeという名前のプロセスを調べる場合には、下記のように書けばよい。

処理1の結果から処理2で指定した条件に応じた結果を返してくれる。

Get-Process | Where-Object {$_.Name -eq "chrome"}
Get-Process | Where-Object Name -eq "chrome" # 上と同じ結果

比較オペレーターはマイクロソフトの解説ページによれば以下の通り。

TypeOperatorComparison test
Equality-eqequals
-nenot equals
-gtgreater than
-gegreater than or equal
-ltless than
-leless than or equal
Matching-likestring matches wildcard pattern
-notlikestring does not match wildcard pattern
-matchstring matches regex pattern
-notmatchstring does not match regex pattern
Replacement-replacereplaces strings matching a regex pattern
Containment-containscollection contains a value
-notcontainscollection does not contain a value
-invalue is in a collection
-notinvalue is not in a collection
Type-isboth objects are the same type
-isnotthe objects are not the same type

結果にソートをかける

ソートはパイプラインにSortと何でソートをかけるのか、降順かを選択すればよい。

形としては、Cmdlet | Sort -ソート対象 -Descending
(降順にする場合のみDescendingをつける)

Get-Process | Sort Name -Descending # プロセス名でソートをかける例。
Get-Process | Where-Object{$_.name -eq "chrome"} | Sort Id # フィルターとソート

※フィルターとソートを両方使う場合には、ソートの処理時間・負荷を考えて基本的にはフィルター後のデータに対してソートをかけるようにする。

条件式、If分の作り方

基本的なIf分の作りは他のVBAやPythonなどとほとんど同じような作り方である。

If (条件式) {条件式がTrueの場合の処理}
If (-not(条件式)) {False(ある種True)の場合の処理} # -notがFalseをTrueにする。

elseifやelseももちろん使える。

If (条件式1) {条件式1がTrueの場合の処理}
elseif(条件式2) {条件式1がFalseで条件式2がTrueの場合の処理}
else {条件式1、条件式2共にFalseの場合の処理}

Switch文

Switch分はelseifとelse等からなる条件式をより簡素化してシンプルにかけるようにしたもの。

switch(判定値)と判定値を渡し、その値が条件に合致するかをそれぞれの条件式で判断、条件を満たしたところで処理を実行する。

VBAやVBSのSelect Caseと同じようなもの。

switch(判定値)
{
 {$_ 条件式1} {条件式1がTrueの場合の処理}
 {$_ 条件式2} {条件式2がTrueの場合の処理}
 {$_ 条件式3} {条件式3がTrueの場合の処理}
 default {条件式1~3を満たさない場合の処理}
}

ループ処理

Forループ分

Forループも他のVBAやPythonで使ったことがある方は抵抗なくかけると思う。

for($i = 1; $i -le 10; $i++){$i} # iが10未満であればTrue。実行結果は1から10を表示。

すでに上でforeach-objectは使ったが、foreache(){処理}のようにしてforeach分によるループ処理も可能である。

これはVBAをやったことがある方ならお馴染みだと思う。

.NET Object

New-Object cmdlet

自動化の基礎

新しいファイルの作成

New-Item -Path ファイルのパス # 指定したパス内に新しいファイルを作成する

文字列の置換え

文字列に含まれる特定の文字を置き換えることも簡単にできる。

-Replaceを使えば正規表現で文字列の置換えが可能。

$strTest = "Hello World"
$strTest.Replace("World","Tanaka") # "Hello Tanaka"に置換え

$strTest -Replace "(.*) (.*)", "Hoi Tanaka" # "Hoi Tanaka"に置換え

特定の文字を削除するには、Replaceで””に置換えるか、.Trim()を使う。

$strTest = "Hello World"
$strTest.Replace("Hello","")
$strTest.Trim("Hello")

文字列の前後のスペース削除

.Trim()を使えば文字列前後のスペースを削除できる。
.TrimStart()、.TrimEnd()を使って前後どちらかのスペースを指定して削除することも可能。

$strSpace = "   Hello World   "
"*"+$strSpace+"*" # → *   Hello World   *
"*"+$strSpace.Trim()+"*" # → *Hellow World*

クリップボードの操作

Get-Clipboardでクリップボードの値を取得。

Set-Blipboardでクリップボードに値を渡す。

日付操作

最新日付の取得

最新日付を指定のフォーマットで取得する。

フォーマットを指定する際に、mmは時間の分を意味する。日付の月はMMと大文字で書く。

Get-Date -Format "yyyy/MM/dd"

Get-Dateは日時を取得できるので、上の例では日付のみ取得しているが、日時の取得もフォーマットに指定すれば可能(フォーマットをまったく指定しなくても可)

ファイルの取扱い

ファイルの作成やちょっとした変更は簡単な作業で一つ一つにはさほど時間がかからないが、量が多かったり、毎日行わなければいけなかったりということになれば、面倒な作業になりうる。

なにせつまらない。

そんな作業もPowerShellを使えば自動化することができる。

$file = Get-Content hoge.txt # hoge部分にパスを指定
$file = ${hoge.txt} # こちらでもファイル内容を読み込める。
$file = [System.IO.File]::ReadAllLines("hoge.txt") # これもファイル内容の読み込み。

Get-Contentが内容だけでなく追加の情報も返すのに対して、[System.IO.File]::ReadAllLinesは内容の読み込みだけを行う。

ファイル内容を読み込み、特定の文字を置換える。

$base = "hoge"
$new = "hogehoge"
$file = $file -creplace $base, $new

この置換え時には大文字小文字に気を付ける必要がある。
また、一行ごとに処理が行われるため、2行に対象キーワードが分かれている場合には見逃してしまう。

複数行に渡る文字列を対象にキーワードの置換えを行う場合には、下記のようにテキストファイルの読込み時に-Rawをつけて一行の文字列として読込むことで対処する。

$file = Get-Content hoge.txt -Raw # 全ての内容を一行のものとして読み込む

ブラウザと指定リンク先の自動表示

Yahoo! JapanとGoogleをリンク指定し、Edgeで開いてみる。

$Link1 = "https://www.yahoo.co.jp/"
$Link2 = "https://www.google.com/"
$allLinks = $Link1, $Link2
$allLinks | Foreach {start microsoft-edge:$_} # microsoft-edge:の後にスペースを入れないこと
$allLinks | Foreach {start msedge $_} # こちらでも同じ

ウェブ上のファイルのダウンロード

Invoke-WebRequestを使えば簡単にURLを指定してファイルをダウンロードすることができる。

Invoke-WebRequestはウェブページのHTML以外の情報も取得するが、メタデータが不要でシンプルにHTMLだけ取得したい場合にはInvoke-WebRequestの代わりにInvoke-RestMethodを使う。

Invoke-WebRequest URL -OutFile ToPath # URLにファイルのURL、ToPathにファイルの行先パスを指定

取得したHTML情報から必要情報を取り出すには、HTMLのタグやID、Classなどの情報を指定することで実現できる。

これはVBAやPythonなどでスクレイピングをしたことがある方なら同じような指定方法であるため取っつきやすい。

$page = Invoke-WebRequest "URL"
$target = page.ParsedHTML.getElementsByID("ID_Name")
$target2 = page.ParsedHTML.getElementsByTagName("Tag_Name")
$target2.innerText # 指定タグ内の文字列を取得
$links = $page.Links

このInvoke-WebRequestとInvoke-RestMethodの使い方は静的なHTMLを取得するのみである。

クリックするとページの表示情報が変わるような動的なページには対応できない場合がある。

対話的なウェブページへの対応

Invoke-WebRequestと-SessionVariableや-WebSession パラメーターを利用することで対応する。

ウェブサービスを操作するには、New-WebserviceProxyを利用する。

ログインIDとパスワードの指定

Get-Credentialを使えばIDとパスワードを指定するフォームが表示されるため、そこに必要情報を入力することでログインフォームの入力に利用することができる。

Get-Credentialの後に表示されるフォームは下の画像のもの。

入力したIDやパスワードの取得・指定方法は次のように書く。

$loginInfo = Get-Credential
$logingInfo.UserName # 入力したIDの取得
$LoginInfo.GetNetworkCredential().Password # 入力したパスワードの取得

$loginInfo = Get-Credential -Credential IDhoge # この方法で予めIDを指定することもできる

ヘルプの使い方

PowerShellで何かわからないことがあった場合にはヘルプを使いこなすことで大抵のことは解決できるようになっている。

また、ヘルプは非常に使いやすいようにできており、これを積極的に活用していくことが推奨されている。

Get-Help Get-Service # Get-Serviceのヘルプを取得
Help Get-Service # より詳細のヘルプを取得したい場合には、詳細画面に進める。

Get-Help Get-Service -ShowWindow # 別ウインドでヘルプを表示。

-ShowWindowをつけるとヘルプが非常に見やすくなる。
また、ヘルプ内の検索をかけるのにも便利なため、頻繁に使うことになると思われる。