PowerShell でスプリクト。


参考資料
 Windows PowerShell宣言! (単行本) (アマゾン)
 Windows PowerShellコマンド&スクリプティング入門(@IT)
 Windows PowerShell でのスクリプティング(マイクロソフト)



Power Shell は .NET Framework 2.0 上で動作するため 「.NET Framework 2.0 再配布可能パッケージ」をインストールしておく。 エラーメッセージを日本語化する 「.NET Framework 2.0 日本語 Language Pack」も合わせて入れておく。
コマンドの名前は「動詞-名詞」のようにハイフンで繋ぐ形となる。 get-childitem が DOS コマンドの dir や UNIX コマンドの ls に相当する。 また、エイリアスにより、「dir」[ls]と打ち込んでもファイル一覧を取得できる。  Get-ChildItem コマンドレットの使用  http://www.microsoft.com/japan/technet/scriptcenter/topics/msh/cmdlets/get-childitem.mspx  PowerShellのGet-ChildItemコマンドレットでファイル名の一覧を取得する(応用編)  http://www.atmarkit.co.jp/fwin2k/win2ktips/1066psflist2/psflist2.html
エイリアス get-alias により、割り当てられているエイリアスを取得できる。 自分でエイリアスを追加する場合は new-ailias [エイリアス名] [コマンドレット名/関数名]  エイリアス  http://www.microsoft.com/japan/technet/scriptcenter/topics/msh/cmdlets/aliases.mspx
実行ポリシー Restricted(デフォルト) 最も高いセキュリティでスプリクトファイルの実行は出来ない。 AllSigned すべてのスクリプトに証明書を要求 RemoteSigned インターネット経由でダウンロードしたスクリプトのみ証明書を要求 Unrestricted すべてのスクリプト実行を許可(インターネット経由でダウンロードしたコードは実行確認のみあり) ポリシーの変更 set-executionpolicy RemoteSigned ポリシーの確認 get-executionpolicy  セキュリティとセキュリティ記述子  http://www.microsoft.com/japan/technet/scriptcenter/topics/msh/cmdlets/security.mspx  署名ツール  Cryptography Tools  http://msdn2.microsoft.com/en-us/library/Aa380259.aspx  セキュリティAPIに関する技術調査   http://www.ipa.go.jp/security/fy15/reports/sec_api/
スプリクトファイルの拡張子 .ps1 実行するスプリクトがたとえカレントフォルダに存在する場合でも .\sample.sp1 のように相対パス表記をする必要がある。 この手間を省くには、Windows の環境変数に 「;.\」を追加しておく。  スクリプトとアプリケーション  http://www.microsoft.com/japan/technet/scriptcenter/topics/msh/cmdlets/scripts.mspx  Windows PowerShell スクリプトを実行する  http://technet.microsoft.com/ja-jp/scriptcenter/powershell_owner05.aspx
環境ファイル 起動時に読み込まれる設定ファイル(profile.ps1)で 全てのユーザ %windir%\system32\WindowsPowerShell\v1.0\profile.ps1 現在のユーザ %UserProfile%\My Documents\WindowsPowerShell\profile.ps1 の順で読み込まれる。 同一名の関数定義が存在した場合は、後から読まれた関数が有効となる。
コメント # <# #> コンソールに文字を出力 "Hello World" Write-Host "Hello World" Write-Output "Hello World" 配列 @ () を使う。 例) $abc = @(123,456,789)   この配列にアクセスするには   $abc[0] 連想配列 @ {} を使い要素間は ; で区切る 例) $abc = @{a=123; b=456}   この要素にアクセスするには   $abc.a 又は $abc["a"] 変数 先頭に $ 文字をつけた任意の英数字及びアンダースコア 例) $abc = [system.int64]123   データ型の確認は   PS > $abc.GetType()   IsPublic IsSerial Name BaseType   -------- -------- ---- --------   True True Int64 System.ValueType    .NET Frameworkの型名    System.Byte 8 ビット符号なし整数(0 から 255)    System.Int16 16 ビット符号付き整数(-32768 から +32767)    System.Int32 32 ビット符号付き整数(-2,147,483,648 から +2,147,483,647)    System.Int64 64 ビット符号付き整数(-9,223,372,036,854,775,808 から +9,223,372,036,854,775,807)    System.Single 単精度浮動小数点数(-3.402823e38 から +3.402823e38)    System.Double 倍精度浮動小数点数(-1.79769313486232e308 から +1.79769313486232e308)    System.Decimal 10 進数(-79,228,162,514,264,337,593,543,950,335 から 79,228,162,514,264,337,593,543,950,335)    System.Boolean true または false のいずれかの値    System.Char Unicode 文字    System.String テキストを一連の Unicode 文字として表現    System.Array 配列の作成、操作、検索、および並べ替えを行うメソッド    System.Xml.XmlDocument XML ドキュメント    System.Type 型宣言 [型]$a     型へキャスティング(失敗時は エラー) $a -is [型]  型と等しい $a -isnot [型] 型と等しくない $a -as [型]  型へキャスティング(失敗時は $null) 自動変数 $home ユーザのホームフォルダ $pshome PowerShell のインストールフォルダ $_ 現在のパイプラインオブジェクト $args スプリクトからの引数 $input パイプラインに渡された入力オブジェクト $true ブール値のTrue $false ブール値のFalse $null ヌル値 $host PowerShell のホストアプリケーションへの参照 $pid PowerShell のProcess ID $error エラー情報 $myinvocation 実行中のスプリクトやコマンドの情報 演算子 -eq 次の値に等しい(=) -ne 次の値に等しくない(≠) -gt 次の値より大きい(>) -lt 次の値より小さい(<) -ge 次の値以上(≧) -le 次の値以下(≦) -like 文字列の比較(ワイルドカード対応) -notlike -match 文字列の比較(正規表現対応) -notmatch 論理演算 -and  AND -or   OR -not(!) NOT ビット演算 -band  AND -bor  OR -bnot  NOT -bxor  XOR -shl  左シフト -shr  右シフト [Convert]::ToString($a, 2) 2進数変換 [Convert]::ToString($a, 8) 8進数変換 [Convert]::ToString($a, 16) 16進数変換 [Convert]::ToInt32("2進数", 2) 2進数文字列を数値変換 [Convert]::ToInt32("8進数", 8) 8進数文字列を数値変換 [Convert]::ToInt32("16進数", 16) 16進数文字列を数値変換 0x00 16進数  演算子の一覧は  get-help about_operator  で確認出来る。  文字列比較で大文字、小文字を区別するには  先頭に「c」しない場合は「i」をつける。  演算子の一覧は  get-help about_operator  で確認出来る。  また、 ヒア文字列(改行や引用符を含める場合に利用) @""@ または @''@ を使う。 例) $a = "1" $b = "2" $her = @' $a $b '@ 結果は $a $b $her = @" $a $b "@ 結果は 1 2  シングルクォートとダブルクォートの違いは、変数を含んだ場合にその値が  展開されるかどうか。  また、エスケープ・シーケンスも同様  `b バックスペース  `n 改行  `r キャリッジ・リターン  `t タブ 例) $her = "abc `" def" または $her = "abc "" def" また、文字を複数行に分けた場合の継続記号としても利用される。 $her = 10 ` + 20 ` + 30 複合演算子 $a += 2 は a$ = a$ + 2 $a -= 2 は a$ = a$ - 2 $a *= 2 は a$ = a$ * 2 $a /= 2 は a$ = a$ / 2 $a %= 2 は a$ = a$ % 2 インクリメメントとデクリメント ++ 変数に 1 を加算 -- 変数に 1 を減算 例) $a = $b = 1 $a = ++$b 結果は $a = 2、$b = 2 先に $b に 1 が加算される $a = $b = 1 $a = $b++ 結果は $a = 1、$b = 2 後から $b に 1 が加算される 多重代入 $a,$b,$c = 1,2,3 結果は $a=1 $b=2 $c=3 となる。 配列の場合は()を利用する $a,$b,$c = 1,(2,3),4 結果は $a=1 $b=2 3 $c=4 となる。 応用で値の入れ替えが可能。 $a,$b = $b,$a
条件分岐 if ([条件式]) { [処理] } elseif ([条件式]) { [処理] else { [処理] } switch([式]){ [条件1] {[処理]} [条件2] {[処理]} [条件3] {[処理]} default {[処理]} } ループ処理 for(初期化式; 終了条件; 増分式){[処理]} foreach(一時変数 in 配列、コレクション){[処理]} (foreach は % に置き換えることが出来る) while(条件式){[処理]} do{[処理]}while(条件式) 関数の作成 function add1 { return $args[0] + $args[1] } 実験は、 add1 1 2 など。 この場合、結果は 3 と表示される。 また、 function add2([int]$a, [int]$b) { return $a + $b } や、 function add2 { param([int]$a, [int]$b) return $a + $b } としても同じ結果が得られる。さらに値にデフォルト値を代入しておく事も可能。
デバッガの起動 Set-PSDebug -trace 2 ステップ実行 Set-PSDebug -step 文法チェック Set-PSDebug -strict
COM の利用 $変数名 = New-Object-ComObject ProgID ComObject は Com と省略可能。 IE を起動する $IE = New-Object-Com Internetexplorer.Application $IE.Visible = $True $IE.Navigate2("www.netdive.jp") $IE.Quit() メンバーの確認 $IE | Get-Member ※重要  getElementById でエラーが出る場合は、ダブルクォーテーションマークからシングルクォーテーションマークにすると正しく処理されるようです。  $doc.getElementByID("id") → $doc.getElementByID('id')
DB にアクセス Windows PowerShell を使用して Microsoft Access データベースからレコードを取得する方法はありますか http://www.microsoft.com/japan/technet/scriptcenter/resources/qanda/oct06/hey1002.mspx accdb にアクセスする場合のプロバイダ指定は "Microsoft.ACE.OLEDB.12.0" みたい。 SQL Server PowerShell プロバイダの使用 http://msdn.microsoft.com/ja-jp/library/cc281947.aspx
DOS コマンドを利用する 【PowerShell】$result = ipconfig /all これは便利! http://blogs.technet.com/junichia/archive/2010/02/17/3313228.aspx
テキスト ファイルの行数を特定 Windows PowerShell を使用してテキスト ファイルの行数を特定する方法はありますか http://www.microsoft.com/japan/technet/scriptcenter/resources/qanda/apr08/hey0428.mspx
260文字以上のパスを表示 普通に利用すると Windows は 256バイト(ドライブ名含めて260文字)以上のパスは表示できない。 検索するには unicode パス(\\?\)を利用し、API を直接叩くしかない。(NTFS は 32767 バイトまで管理できる。) PowerShell 2.0の新機能(6) ――他言語の利用 (1/2):CodeZine http://codezine.jp/article/detail/5007 pinvoke.net: findfirstfile (kernel32) http://www.pinvoke.net/default.aspx/kernel32/findfirstfile.html pinvoke.net: findnextfile (kernel32) http://www.pinvoke.net/default.aspx/kernel32.findnextfile pinvoke.net: WIN32_FIND_DATA (Structures) http://www.pinvoke.net/default.aspx/Structures/WIN32_FIND_DATA.html pinvoke.net: SetFileAttributes (kernel32) http://www.pinvoke.net/default.aspx/kernel32/SetFileAttributes.html ファイルまたはフォルダーは、Windows エクスプ ローラーで長いパスを持つ場合、ファイルのコピー操作が失敗します。 http://support2.microsoft.com/kb/2891362/ja Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class sampleClass{ [DllImport("kernel32.dll", CharSet=CharSet.Auto)] public static extern IntPtr FindFirstFile(string lpFileName, ref WIN32_FIND_DATA lpFindFileData); [DllImport("kernel32.dll", CharSet=CharSet.Auto)] public static extern bool FindNextFile(IntPtr hFindFile, ref WIN32_FIND_DATA lpFindFileData); [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] public struct WIN32_FIND_DATA{ public uint dwFileAttributes; public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime; public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime; public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime; public uint nFileSizeHigh;   public uint nFileSizeLow; public uint dwReserved0; public uint dwReserved1; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)] public string cFileName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=14)] public string cAlternateFileName; } public static WIN32_FIND_DATA FindFirstFile(string path, ref IntPtr ptr){ WIN32_FIND_DATA data = new WIN32_FIND_DATA(); ptr = FindFirstFile(path, ref data); return data; } [DllImport("kernel32.dll", CharSet=CharSet.Auto)] public static extern bool SetFileAttributes(string lpFileName, long dwFileAttributes); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow); public enum ShowWindowCommands: uint { Hide = 0, ShowNormal = 1, ShowMinimized = 2, ShowMaximized = 3, Maximize = 3, ShowNormalNoActivate = 4, Show = 5, Minimize = 6, ShowMinNoActivate = 7, ShowNoActivate = 8, Restore = 9, ShowDefault = 10, ForceMinimized = 11 } [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetForegroundWindow(IntPtr hWnd); } "@ #サブディレクトリまで探して 260文字以上のパスを表示 # 0 標準ファイル # 1 読み取り専用ファイル # 2 隠しファイル # 4 システムファイル # 8 ボリュームラベル # 16 フォルダ function directory([string]$path){ $a = new-object IntPtr $rtn = [sampleClass]::FindFirstFile($path, [ref]$a) while([sampleClass]::FindNextFile($a, [ref] $rtn)){ $filepath = $path.Replace("\\?\","").Replace("*","") $fullpath = $filepath + $rtn.cFileName if( (($rtn.dwFileAttributes -band 16) -eq 16 ) -and ` ($rtn.cFileName -ne "..") ){ if($fullpath.Length -gt 260){ $fullpath } directory('\\?\'+ $fullpath + "\*") } } } directory '\\?\c:\*' # Cドライブのルートからサブフォルダを調べる [sampleClass]::SetFileAttributes("c:\sample.txt", 0) #ファイルを標準ファイルに戻す #IEをアクティブ $ie = @(ps iexplore | ?{$_.MainWindowTitle})[0].MainWindowHandle [sampleClass]::SetForegroundWindow($ie) [sampleClass]::ShowWindow($ie, 1)
NTTルーターに実装されているような VPN 通知 実行時はタスクに登録して周期的に実行する必要があります。 <#********************************************************* * FILE: ip.ps1 * * IPアドレス通知用スクリプト * * * * スクリプトを実行できるようにポリシーの変更をしておく * * set-executionpolicy RemoteSigned * * 実行 * * powershell.exe -noexit & "ip.ps1" * *********************************************************#> $filename = $PSScriptRoot + "\ip.txt" #IPアドレス保存 $url = "http://kojikoji.net/testip.aspx" #IP確認サイト $username = "" #ログインアカウントの設定 $password = "" #ログインパスワードの設定 $myhost = "mail.netdive.jp" #メールサーバー $port = 587 #ポート $from = "" #送信者 $to = "" #通知先アドレス。複数の場合はカンマ区切り <#********************************************************* * IPアドレス取得       * *********************************************************#> $oldIP = "" $wc = New-Object System.Net.WebClient $st = $wc.OpenRead($url) $enc = [System.Text.Encoding]::GetEncoding("UTF-8") $sr = New-Object System.IO.StreamReader($st, $enc) $newIP = $sr.ReadToEnd() $sr.Close() <#********************************************************* * ファイル操作        * *********************************************************#> if( (Test-Path $filename) -eq $true){ $oldIP = Get-Content $filename } <#********************************************************* * メール送信         * *********************************************************#> if( $oldIP -ne $newIP ){ New-Item $filename -itemType File -Force -Value $newIP $subject = Get-date [string]$subject += " VPN接続用IPアドレスが変更になりました。" $body = "接続先: " + $newIP $sc = New-Object Net.Mail.SmtpClient $sc.Host = $myhost $sc.Port = $port $sc.Credentials = New-Object Net.NetworkCredential $sc.Credentials.UserName = $username $sc.Credentials.password = $password $sc.send($from, $to, $subject, $body) }
あとは、必要になったら追加する方向で…
ツール  Windows PowerShell Scriptomatic  http://www.microsoft.com/downloads/details.aspx?familyid=d87daf50-e487-4b0b-995c-f36a2855016e&displaylang=en  Visio 2007 用 Windows PowerShell スクリプト生成ツール  http://www.microsoft.com/japan/windowsserver2008/powershell-tool.mspx  Windowsコマンドシェル「PowerShell」をGUIで管理・実行できる「PowerGUI」  http://www.forest.impress.co.jp/article/2007/10/26/powergui.html  PowerShell Plus  http://www.powershellplus.com/
第3回 進化したPowerShell 2.0  1.Windows Serverの新しいシェル、PowerShell  http://www.atmarkit.co.jp/fwin2k/winsv2008r2/03powershell/03powershell_01.html 【レビュー】  【2008 R2体験記】開発者にも便利になったIIS 7.5 - PowerShellでの管理  http://journal.mycom.co.jp/articles/2009/12/22/win2008r2_u1/index.html 【コラム】  GUIユーザーのためのPowerShell入門  http://journal.mycom.co.jp/column/powershell/index.html
PowerShell DSCで始めるWindowsインフラストラクチャ自動化の基本:PowerShell Desired State Configuration(DSC)とは(前編) (1/2) - @IT http://www.atmarkit.co.jp/ait/articles/1405/22/news131.html