対象
- bashやらzshやらは使ったことある人
- PowerShell初心者
- PowerShellを毎回ググって使ってる人
ググる回数を減らすための基本
コマンドレットとは
コマンドレットとは、シェルでいうコマンドに似た概念です。名前の問題はどうでもよいのですが、一つだけわかっておいた方がよいことは、
- Do-Somethingの形式になっている
という点です。例えば、設定されているエイリアスを確認したい場合には、Get-Alias
と打てばその一覧が表示されますし、逆にエイリアスを設定したい場合にはSet-Alias show Get-ChildItem
と打つことでshow
というエイリアスを作ることができます。この場合、Set
がDo
(=セットする、変数に代入する)にあたり、Alias
がSomething
(=エイリアスを)ということになります。このことを認識しておくと、何かの一覧を取得するためのコマンドレットがわからなくても、Get-Something
の形になることが予想されるなど、コマンドレットを思い出す/探す際のきっかけになります。
また、大文字と小文字を区別しないことも一応確認しておいた方がよいかもしれません。コマンドレットはコマンドに比べて長いので、実践的には適当に小文字で入力してタブ補完をするかエイリアスをきちんと貼っていくことになると思われます。
※ 以下ではコマンドレットをあえてエイリアスを使わずに紹介していますが、実際には、Where-Object
-> ?
など便利で短くかけるようになっているので「PowerShellは長い!」って言ってあげないでください。。。
実行ポリシー
有名な話かもしれませんが、PowerShellは実行ポリシーを適切に設定しないと自分で書いたスクリプトですら実行できなくて残念な気持ちになることになります。実行ポリシーには次の4つがあり、デフォルトでは、一番厳しいRestricted
になっています。
- Restricted
- AllSigned
- RemoteSigned
- Unrestricted
「とりあえずローカルにある自分のスクリプトが動けばOK」のケースが多いと思うので、RemoteSigned
にしておけば十分かと思われます。管理者権限でPowerShellを起動して以下を実行でスクリプトの実行ができるようになります。
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
※ 追記: 下でコメントしてくださっているように、スコープをきちんと限定してやるのがより適切だと思われます。また、実行ポリシーについて詳しく載った記事もそのコメントで紹介していただいているのでご参考ください。
※ 2019/10/22 更新: コメント頂いたものに上記のコマンドを修正しました。 @nukie_53 さんありがとうございます。実行ポリシーについて詳しく知りたい場合は、下のコメントの記事などご参照ください。
コマンドレットはオブジェクトをパイプする
Linuxなどでのシェルでは、文字列をパイプすることになっていたと思いますが、PowerShellではオブジェクトをパイプします。この辺が少し勝手が違うところになってくるわけですが、個人的にはこの点がとても好きです。なんかおしゃれな気がしてします。この辺りは下のgrepの項目で少し触れます。このポイントが一番大切かもしれません。
シェルでよく使ってたコマンドと同じ感じのコマンドレットを使いたい人へ
cd / ls
cd
もls
もデフォルトでエイリアスが貼られているので同じような感覚で使えます。実際この辺は、このエイリアスを使っている人が多いのではないかと予想しています。ちなみにそれぞれ、cd -> Set-Location
,ls -> Get-ChildItem
になっています。
grep
grep
はありません!! 代わりにSelect-String
というコマンドレットがあってそれを使うことでほぼ代替可能のようです。ファイルからの検索では、かなり便利に使えるようです(参考: grepコマンドとPowerShellのsls (Select-String)の比較)。しかし、パイプを通してひとつ前の結果を加工するケースで使う場合には、grep
<=>Select-String
の図式を持ち込まない方が良さそうです。例えば、「Select-Object
にデフォルトで貼られているエイリアスはないかな~?」と思って探す場合には、次のようなコマンドでその存在を確かめることができます。間に挟まっているOut-String
はパイプされてきたオブジェクトを文字列にするために入れる必要があります。
Get-Alias | Out-String -Stream |Select-String ".*Select.*"
実はもっとPowerShellらしい方法があって、
Get-Alias | Where-Object {$_.Name -like "*Select*"}
とすることで見つけることができます。これは、Get-Alias
が返すオブジェクトのName
プロパティに検索をかけていることになります。このあたりは、「オブジェクトを渡すパイプ」を活用している感じがします。
しかし、これはこれで「Nameなんてどこから知ることができるの?」ってなってしまいそうです。実は、PowerShellは実行結果のところにこのプロパティの名前が表示されています。例えば、Get-Alias
と打つと、
CommandType Name Version Source
----------- ---- ------- ------
Alias % -> ForEach-Object
Alias ? -> Where-Object
Alias ac -> Add-Content
Alias asnp -> Add-PSSnapin
Alias cat -> Get-Content
Alias cd -> Set-Location
Alias CFS -> ConvertFrom-String 3.1.0.0 Microsoft.PowerShell.Utility
Alias chdir -> Set-Location
Alias clc -> Clear-Content
Alias clear -> Clear-Host
Alias clhy -> Clear-History
.
.
と表示されます。これがちょうど、ヘッダーがプロパティ名となったテーブルのような形になっています。このことは、きちんと覚えていくと使いやすくなってくると思います。
さらに、パイプで渡されてくるプロパティの名前などをすべて知りたいときには、Get-Member
というコマンドレットが便利で
PS > Get-Alias | Get-Member
TypeName: System.Management.Automation.AliasInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ResolveParameter Method System.Management.Automation.ParameterMetadata ResolveParameter(string
ToString Method string ToString()
CommandType Property System.Management.Automation.CommandTypes CommandType {get;}
Definition Property string Definition {get;}
Description Property string Description {get;set;}
Module Property psmoduleinfo Module {get;}
ModuleName Property string ModuleName {get;}
Name Property string Name {get;}
Options Property System.Management.Automation.ScopedItemOptions Options {get;set;}
OutputType Property System.Collections.ObjectModel.ReadOnlyCollection[System.Management.Aut
Parameters Property System.Collections.Generic.Dictionary[string,System.Management.Automati
ParameterSets Property System.Collections.ObjectModel.ReadOnlyCollection[System.Management.Aut
ReferencedCommand Property System.Management.Automation.CommandInfo ReferencedCommand {get;}
RemotingCapability Property System.Management.Automation.RemotingCapability RemotingCapability {get
ResolvedCommand Property System.Management.Automation.CommandInfo ResolvedCommand {get;}
Source Property string Source {get;}
Version Property version Version {get;}
Visibility Property System.Management.Automation.SessionStateEntryVisibility Visibility {ge
DisplayName ScriptProperty System.Object DisplayName {get=if ($this.Name.IndexOf('-') -lt 0)...
HelpUri ScriptProperty System.Object HelpUri {get=$oldProgressPreference = $ProgressPreference
ResolvedCommandName ScriptProperty System.Object ResolvedCommandName {get=$this.ResolvedCommand.Name;}
と表示され、メソッドなどと一緒にすべてのプロパティを確認することができます。
その他
ps
-> Get-Process
などあります。このページはクックブック的で便利だと思います。
まとめ
上記をまとめると次のようになるかと思います。「とにかくコマンドレットを覚えよう」とするよりも幾分か見通しがよくなるのではないかと思います。
- コマンドレットはDo-Somethingの形
- PowerShellのパイプはオブジェクトを渡す
- 結果表示は、プロパティがヘッダーになっているテーブルになっている
- パイプを受け取る
grep
には、Select-String
が対応しないこともある