qshinoの日記

Powershell関係と徒然なこと

ComObject廃棄

ComObject廃棄

変数廃棄

Remove-Variable aaa

$x = New-Object -com Excel.Application
$x.Visible = $True
Start-Sleep 5
$x.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($x)

Remove-Variable x

参考

https://technet.microsoft.com/en-us/library/ff730962.aspx

wpfオブジェクト廃棄

.netの世界ではリファレンスカウンタ処理。参照解除を忘れずに。

https://social.msdn.microsoft.com/Forums/vstudio/en-US/afa6cc76-92f4-4144-99c5-e8f5fdc88029/how-dispose-wpf-controls?forum=wpf

.Net Com Object作成

https://msdn.microsoft.com/ja-jp/powershell/scripting/getting-started/cookbooks/creating-.net-and-com-objects–new-object-

Job Event for powershell

Powershell jobの終了通知

Register-ObjectEvent で終了通知可能。

Register-ObjectEvent $job -EventName StateChanged -SourceIdentifier ハンドラ名 -Action { アクション }

取扱物件は

  1. ターゲットジョブ
  2. ハンドラ
  3. ハンドラジョブ

ハンドラを登録するとハンドラジョブが作成される。よって終了通知の後処理は下記の3つ

  1. ハンドラ削除
  2. ターゲットジョブ破棄
  3. ハンドラジョブ破棄

上記を踏まえた基本の流れ。

  1. ターゲットジョブ起動
  2. ハンドラ登録
  3. 後処理1 (ハンドラジョブ)ハンドラ削除とターゲットジョブ破棄
  4. 後処理2 (メイン側など) ハンドラジョブ破棄

後処理1はハンドラジョブが実施。ハンドラジョブ終了後に、誰かが後処理2を実施。ハンドラジョブが自ジョブを破棄できない前提。

ハンドラジョブ破棄は、次回のジョブ実行前などに実施。

但し、ハンドラ削除前にハンドラジョブ破棄すると、ハンドラ削除に失敗する。仕方なく、毎回ハンドラ名を変えてハンドラ登録する。

破棄できないハンドラが残る点が気になる。PowerShell終了で見えなくなるが、悩ましい。

やってみた事

  1. ハンドラ登録すると、ハンドラジョブが作成される。
  2. NotStarted状態のハンドラジョブを破棄できない。
  3. Failed状態?のハンドラジョブなら破棄可能。
  4. ハンドラジョブを破棄すると、ハンドラを削除できない。

とにかく、ハンドラを削除できないのが宜しくない。最初にハンドラを削除し、その後にターゲットジョブ、ハンドラジョブを削除する。

ダメだったもの

Get-EventSubscriber -force | Unregister-Event -force

結局、Unregister-Event -Forceでもジョブが破棄されるとハンドラを削除できない。セッション終了まで待つしか無い

コード例

$job = Start-Job { 
Dir $env:windir *.jpg -r  -ea SilentlyContinue} -Name "WinDirの検索"

Register-ObjectEvent $job -EventName StateChanged  `
  -SourceIdentifier JobStateChanged `
  -Action { 
  Write-Host "JOb「$($sender.Name)」が $($event.TimeGenerated) に終了" 
  Write-Host "★結果は★"
  Receive-Job -Id ($sender.id) | Write-Host

  $global:sender1 = $sender
  $global:event1 = $Event
  $global:subscriber = $EventSubscriber
  $global:source = $SourceEventArgs
  $global:SourceArgs1 = $SourceArgs

  Unregister-Event -SourceIdentifier JobStateChanged
}

関連コマンド

Unregister-Event

先にRemove-Jobされると-Forceをつけてもエラーとなり破棄できない。永遠に破棄できない?

Unregister-Event失敗

Register-ObjectEventにより、Event-Jobが自動的に登録される。Unregisterする前にEvent-JobをRemove-Jobにより破棄すると、その後のUnregister-Eventがエラーする。しかも、Unregister-Event -Forceするとエラーは出ないが破棄できない。但し、Powershell Consoleを終了すると破棄される。

Remove-Job

Running中のJobをRemove-Jobするとエラーになる。-Forceで破棄できる模様。

Remove-Job *

纏めて破棄。

Get-EventSubscriber

登録中のイベントハンドラー一覧表示。

Remove-Event

使った事なし

ジョブ状態

下記の6種類。PSv2.0

  • Blocked
  • Running
  • Completed
  • Failed
  • NotStarted
  • Stopped

参考

http://mtgpowershell.blogspot.jp/2010/11/blog-post_21.html?m=1

http://blog.powershell-from.jp/?p=121

http://blog.powershell-from.jp/?cat=32

http://dobon.net/vb/dotnet/vb2cs/event.html

以上

HostName, IPアドレス by powershell

ホスト名、IPアドレス取得

ホスト名

  1. [Net.Dns]::GetHostName()
  2. $Env:COMPUTERNAME
  3. hostname
  4. (Get-CimInstance -Class Win32_ComputerSystem).Name

IPアドレス

  1. Get-NetIPAddress
  2. [Net.Dns]::GetHostAddresses(‘’).IPAddressToString
  3. [Net.Dns]::GetHostAddresses(‘’).IPAddressToString[1]
  4. ipconfig | where{$_ -match “IPv4 Address… … … . . : (?.*)”} | %{$Matches.ip}

その他

Get-NetIPAddress | where{$_.InterfaceAlias -eq "Ethernet"} | select -ExpandProperty IPAddress

(Get-NetIPAddress | where InterfaceAlias -eq "Ethernet" | select -ExpandProperty IPAddress)

(Get-NetIPAddress | where{$_.InterfaceAlias -eq "Ethernet"}).IPAddress

参考

http://tech.guitarrapc.com/entry/2013/06/17/190601

書式出力 by powershell

書式付き出力

-f 演算子

書式文字列 -f 引数

例) “Hi, {0}! I give you {1:d2} Yen. rn” -f “Taro”, 20

書式文字一覧

c 通貨
d 10進数  精度は最小桁数
e 浮動小数点数 n.nen精度=小数部桁数
f 浮動小数点数 n.nnn 精度=小数点以下
g 浮動小数点数 ne±n 精度=有効桁数
n 3桁コンマ付き
p パーセント
r 精度維持
x 16進数
0 対応文字がない場合0表示
# 不要な場合表示されない

参考

https://msdn.microsoft.com/powershell/reference/5.1/Microsoft.PowerShell.Core/about/about_Operators

http://dobon.net/vb/dotnet/string/inttostring.html

http://d.hatena.ne.jp/newpops/touch/20051126/p1

http://dobon.net/vb/dotnet/string/inttostring.html

msdn

https://msdn.microsoft.com/ja-jp/library/system.string.format(v=vs.110).aspx

http://stackoverflow.com/questions/9904352/how-to-create-printf-effect-in-powershell

日付、連番をファイル名に by powershell

日付をファイル名に

$now = Get-Date -Format "yyyy-MMdd-HHmmss"
Write-Output "poi" | Out-File "memo-$now.txt"

連番をファイル名に

日付を打つのが面倒なので、連番をファイル名にする。先のが2行に対して2行多い4行。

$index = "index.txt"
(Get-Date -Format "yyyy-MMdd-HHmmss") + [Environment]::NewLine >> $index
$file = "memo-{0:00}.txt" -f  (Get-Content $index).length
"poi" >  $file

Get-Contentが行単位の配列を返すので、.lengthが行数を示す事を利用。

懸念点

  1. 文字列をリディレクト可能? ダメなら、Write-Output
  2. ディレクト先のファイル名が変数でも大丈夫? ダメならOut-File

Out-Fileを使って

何とか3行。

$index = "index.txt"
Write-output "Hi" > $index
write-Output "poi" | Out-File  ( "memo-{0:00}.txt" -f  (Get-Content $index).length)

以上

参考

http://tipstour.net/command/9075