PowerShell小ネタ

ネタ単品だと記事にするほどじゃないんだけど書きとめときたいやつ
それなりに溜まったので投下するんじゃ

開いてるウィンドウのタイトルをPowerShellで列挙する

意外と面倒になる予感があったんだけど、Get-Processだけでどうにかなったよ

ps | ? MainWindowHandle -NE 0 | select MainWindowTitle

一行で書けちゃうね

アプリケーションを再起動

Windows10のThunderbirdがスリープ解除後にメールを受信しなくなるっぽいのでさくっと再起動させたかったのね

ps thunderbird* | % {
    $_.CloseMainWindow()
    & $_.Path
}

kill じゃなくちゃんと終了させたかったら CloseMainWindow() すればいいらしい
こんなメソッドあったのね
あとはexe叩きなおせばOK

Hashtableからキャスト

New-Object psobject するより Hashtable から pscustomobject にキャストしたほうが早いらしい

PS> $hashtable = @{Foo = 123; Bar = 'abc'; Baz = $true}
PS> New-Object psobject -Property $hashtable
PS> [pscustomobject] $hashtable

Measure-Command したら確かに若干差がある
まぁこれは好きにすればいいんじゃないって感じなんだけど
Hashtable をキャストするって発想がなかったのでちょっと面白いなって

もしかしてメンバの型が合ってれば任意の型にキャスト出来るんじゃないかな?
やってみよう

PS> class Hoge
{
    [int]    $Foo
    [string] $Bar
    [bool]   $Baz
}

PS> [Hoge] $hashtable

Foo Bar  Baz
--- ---  ---
123 abc True

PS> ([Hoge] $hashtable).GetType()

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True     False    Hoge System.Object

ちゃんと Hoge 型になった!

zip圧縮の罠

Zipme
├Folder
│└File2.txt
└File1.txt

こんなふうにファイルが配置されてるとしてだね
ls から Compress-Archive にパイプしたい場合
フォルダあるから -Recurse したほうが良かろうとか、思うじゃん

ls .\Zipme\ -Recurse | Compress-Archive -DestinationPath Zipme.zip

結果

Zipme.zip
├Folder
│└File2.txt
├File1.txt
└File2.txt  <- お、お前ー!

ぎゃーし!

ls .\Zipme\ | Compress-Archive -DestinationPath Zipme.zip

-Recurse しなくても良かったようです

通知を出す

Windows10になって通知がアクションセンターに残るようになったし、ジョブの状況とか通知投げられたら素敵じゃん?
なんかやり方あるんだろうなーって探してたらそのものずばりっぽいモジュールがあった

導入は PackageManagement から、楽々です

PS> Find-Package -ProviderName PSModule -Name BurntToast | Install-Package

じゃあやってみようぜ

PS> New-BurntToastNotification "( ‘(I¥‘)" 'みなもちゃんかわいい!'
通知

通知

アクションセンター

アクションセンター

やったー!

と思ったけどこれ通知消えるとアクションセンターからも消える
アクションセンターからは消えないでほしいんだけど、そういう感じのパラメータない…ないね!
あとでちゃんと調べよう

別プロセスのシェルに入る

なんのこっちゃって思うじゃん、思った

PowerShellをふたつ立ち上げとこう、そんでだ

# PowerShell(2)
PS> $PID
12345

別のシェルのPIDを調べとこうね
12345 だったとします

メインで使う方のシェルは昇格しとく必要がある

# PowerShell(1) (管理者シェル)
PS> $PID
13579 # PIDは当然異なるよね
PS> Enter-PSHostProcess -Id 12345
[プロセス:12345]: PS C:\Users\stuncloud\Documents>
# ↑プロンプトが変わるぞ
[プロセス:12345]: PS C:\Users\stuncloud\Documents> $PID
12345 # 別のシェルのPIDになってますよ!!
[プロセス:12345]: PS C:\Users\stuncloud\Documents> Exit-PSHostProcess # 抜ける
PS> $PID
13579 # 戻ってきた

…なにこれ何に使うの!!
よくわからないけどすごいいりょくをひめているきがする!

( ‘(I¥‘)) …

と、これを書いた後に実際に仕事中使ってみる機会があったんだけど
なんと別のユーザーのプロセスでも構わず入っていけるぞすごい
具体的には

  1. リモートPCにユーザーXでローカルログオンして、PowerShellを起動しておく
  2. ユーザーXのPowerShellのPIDを調べる
  3. リモートPCにユーザーYの資格情報を使って Enter-PSSession する
  4. Enter-PSHostProcess -Id (ユーザーXのPowerShellのPID) する

で、リモートシェルからローカルで動いてるPowerShellに侵入?してしまったぞ
これで例えば cd HKCU:\ とかするとユーザーYではなくローカルログオンしているユーザーXのレジストリにアクセス出来ちゃう
すげーなおい…なんか悪さ出来そうですね!
ちなみに

PS> Start-Process -FilePath powershell -Credential ユーザーX

はエラーになってダメでした、まぁそりゃそうだよね
あ、もしかしてタスクスケジューラ使えばあるいは…?
しかしなるほどPowerShellを非表示で起動出来ないとかこれ考えるとなんか、うん

いやでもログオン中のユーザーの HKCU:\ 見たいーとか Cert:\CurrentUser 見たいーとかままあるのでこれはとても便利だ

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中