Powershellで.netクラスを探す
Powershellで.netオブジェクトを扱っていると、名前空間のタイプが面倒。
というか、覚えてない。
例えば正規表現のクラス名と名前空間、覚えてます?タイポしない?
そんな時のために関数を書いてみた。
関数
$Profileにあると便利かと。
function Get-Types() { Param( [string]$Match, [string]$Name, [switch]$Private ) if($Name -ne $null -and $Name.length -gt 0) { $Match = '^' + $Name + '$' } $res = @() foreach($ass in [AppDomain]::CurrentDomain.GetAssemblies()) { foreach($t in $ass.GetTypes()) { if(($Private -or $t.IsPublic) -and $t.Name -match $Match) { $res += $t } } } return $res }
使い方
正規表現の例で。
正規表現のクラスだから「regex」とか入っているはず。
Get-Types regex
結果
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Regex System.Object True True RegexCompilationInfo System.Object True False RegexRunner System.Object True True RegexOptions System.Enum True False RegexRunnerFactory System.Object True False RegexStringValidator System.Configurat... True False RegexStringValidatorAttribute System.Configurat...
ああ、「Regex」クラスだった。
じゃ、staticの「Replace」を呼び出すか(ここでは-replace演算子は忘れる)
(Get-Types -Name Regex)::Replace('-1234567', '(?<=\d)(?=(\d{3})+$)', ',')
結果
-1,234,567
もちろん
(Get-Types Regex)[0]::Replace('-1234567', '(?<=\d)(?=(\d{3})+$)', ',')
もOK。
第一引数は-matchなので、クラス名の一部とかでも機能します。
続いて、管理者権限の有無を取得するスクリプト
(New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
長いよ!これが以下に
(New-Object ((Get-Types WindowsP).FullName)((Get-Types WindowsId)::GetCurrent())).IsInRole((Get-Types WindowsB)::Administrator)
Get-Typesに「gt」とか別名つけたら、もっと短いです。
環境によっては、上手くいかないかもしれません。
おそらく「Get-Types WindowsP」とかが複数を返してくる場合。
Get-Typesが一つしか返さないように調整すれば、通るはずです!
「.netリファレンスにあるのに、出てこない、うそつき!」という場合、アセンブリが読み込まれていない可能性があります。
Add-Typeしてやってください。
たとえば、「System.Windows.Forms.Form」
Get-Types -Name Form
iseで実行すると取得できますが、素のPowershellだと何も返ってきません。
アセンブリが読み込まれていないからです。
Add-Type -AssemblyName System.Windows.Forms
してから実行すれば、結果が得られます。
じゃあ、Add-Typeするアセンブリはどうやって取得するか、、、。
そこ、弱点ですね。
ま、、、
explorer $env:SystemRoot\assembly
でも見てくださいな。