PowerShell - Sort-Object - 1から10の数字を、2.1に近い順に並べかえる
1..10 | Sort-Object @{ Expression={[MATH]::Abs($_ - 2.1)}; Ascending = $true # expressionブロックの値が小さい順 }
実行結果
2 3 1 4 5 6 7 8 9 10
PowerShell - ForEach-Objectの多重使用 - CSVファイルを読み取りデータに1を加算して出力する
Get-Content ".\test.csv" | %{ ( # 1行ごとの処理 $_ -split "," | %{ # 1データごとの処理 [int]$_ + 1 } ) -join "," } | Write-Output
test.csv
1,2,3 4,5,6 7,8,9
結果
2,3,4 5,6,7 8,9,10
普通のプログラムっぽい書き方(ForEach-Objectは使用しない)
$lines = Get-Content ".\test.csv" foreach ($line in $lines) { $data = $line -split "," $ary = @() foreach ($datum in $data) { $ary += [int]$datum + 1 } Write-Host ($ary -join ",") }
CSVにヘッダがある場合
$isHeader = $true Get-Content ".\test.csv" | %{ if($isHeader){ $isHeader = $false $_ } else { ( $_ -split "," | %{ [int]$_ + 1} ) -join "," } }
PowerShell - Excelの操作
EXCEL用のCOMオブジェクトを作成して、あとはVBAと同じ感覚で操作できるっぽいです。
一点、配列やコレクションの括弧の形状がVBAだと( )ですが、[ ]にしないとメソッドと間違えられてエラーになるので注意。
$excel = New-Object -ComObject Excel.Application $excel.Visible = $true $book = $excel.Workbooks.Add() $sht = $excel.Worksheets[1] # 括弧の形状に注意 $sht.Name = "PowerShell" $sht.Cells(1,1).Value = "Hello World" $sht.Range("A2").Value = "PowerShell" $book.Save() $book.Close() $excel.Quit()
プロセスの解放
$excel = $null [GC]::Collect()
または
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sht)
PowerShell - GUIプログラム
ボタンをクリックすると文字を表示するプログラム。
デフォルトで使用できないクラスは、Add-Typeで読み込む。Formに設定したフォントはForm上の部品にも適用される。イベント登録はAdd_イベント名(処理)と記述する。
- System.Windows.Forms.Formクラス - MSDN
- System.Windows.Forms.TextBoxクラス - MSDN
- System.Windows.Forms.Buttonクラス - MSDN
- System.Drawing.Fontクラス - MSDN
Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing # Font #$font = New-Object Drawing.Font("MS Pゴシック",12) #$font = New-Object Drawing.Font("MS P明朝",12) #$font = New-Object Drawing.Font("MS 明朝",12) $font = New-Object Drawing.Font("MS ゴシック",12) # Form $form = New-Object Windows.Forms.Form $form.Text = "Hello" $form.Size = "400,500" $form.Font = $font # Text $txt = New-Object Windows.Forms.TextBox $txt.Location = "10,10" $txt.Size = "360,380" $txt.Multiline = $true $txt.ScrollBars = [Windows.Forms.ScrollBars]::Vertical $txt.Focus() # イベント動作 $proc1 = { $txt.AppendText("Hello Powershell World!!`r`n") } $proc2 = { $txt.AppendText("Focus In`r`n") } # Button $btn = New-Object Windows.Forms.Button $btn.Location = "40,400" $btn.Size = "300,30" $btn.Text = "Hello" $btn.Add_Click($proc1) $btn.Add_GotFocus($proc2) # Formに部品を追加 $form.Controls.Add($txt) $form.Controls.Add($btn) # 表示 $form.ShowDialog()
PowerShell - クラス
バージョン5からクラスが使用可能になったようです。
class Person { [string] $name [int] $age # コンストラクタ Person() { $this.name = "No Name" $this.age = 0 } Person([string]$name, [int]$age) { $this.name = $name $this.age = $age } # メソッド [string]getName(){ return $this.name } [int]getAge(){ return $this.age } [void]talk([string]$str){ Write-Host "${str}, I'm $($this.name), $($this.age) years old." } } $someone = New-Object Person Write-Host $someone.getName() # No Name Write-Host $someone.getAge() # 0 $taro = New-Object Person("Taro",20) $taro.talk("Hello") # Hello, I'm Taro, 20 years old.
継承
PowerShell - クロージャ
戻り値となるブロック内の変数$cntをscriptスコープ宣言することでfunction内の変数$cntへアクセスできるようになる?
function generator($step = 1){ $cnt = 0 return { $script:cnt += $step return $cnt }.GetNewClosure() } $a = generator &($a) # 1 &($a) # 2 &($a) # 3 $b = generator(2) &($b) # 2 &($b) # 4 &($b) # 6 &($a) # 4 &($b) # 8
PowerShell - 独自オブジェクトの作成
PSObjectにプロパティやメソッドを追加していくことで独自のオブジェクトが作成できます。
# Hashでプロパティを追加 $hash = @{name = "Taro"; age = 20} $obj = New-Object PSObject -Property $hash # Add-Memberでプロパティを追加 $obj | Add-Member -MemberType NoteProperty -Name str -Value "Hello" $obj | Add-Member -MemberType ScriptProperty -Name talk ` -Value {Write-Host "$($This.str), My Name is $($This.name)."} # プロパティのgetter/setterを追加 Add-Member -InputObject $obj ` -MemberType ScriptProperty -Name nenrei ` -Value { $this.age } ` -SecondValue { param($age) $This.age = $age } # メソッドを追加 Add-Member -InputObject $obj ` -MemberType ScriptMethod -Name greeting ` -Value { param($str) $This.str = $str } $obj.GetType() # IsPublic IsSerial Name BaseType # -------- -------- ---- -------- # True False PSCustomObject System.Object $obj.name # Taro $obj.age # 20 $obj.str # Hello $obj.talk # Hello, My Name is Taro. # プロパティを直接変更 $obj.name = "Jiro" $obj.talk # Hello, My Name is Jiro. # プロパティを直接変更 $obj.age = 25 $obj.age # 25 # プロパティsetterで変更 $obj.nenrei = 30 $obj.nenrei # 30 # プロパティをメソッドで変更 $obj.greeting("Good Morning") $obj.talk # Good Morning, My Name is Jiro.