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

でも見てくださいな。