2020年9月11日金曜日

◆ActiveDirectoryの配列、非配列のプロパティを同列に扱う

ActiveDirectoryに限った話ではないのだが、ActiveDirectoryのプロパティを扱っていて気付いた現象。

ActiveDirectoryには単一値を持つプロパティと配列を取るプロパティがある。
どちらになるかはMSの決めなので使う側からすると複数入れたいのに単一値プロパティだったり、一つしかないのに配列のプロパティだったりする。

そこで配列の場合も先頭の要素しか使わずに、複数必要な場合はカンマで区切って入れる運用とした。

実はこのプロパティが配列と単一値と混在すると意識していなかったのだが、たまたま以下の様なロジックでうまくいっていた。

$aに様々なプロパティが入ってきて、

$b  =  if( $true ){ $a }

$aがstringでも要素数1のstring配列でも$bにはstringが入ってくれた。

これを故有って以下の様に変えたら$bを使う場所でエラーが発生。

if( $true) { $b = $a }

$b の型がstringではないというエラーだった。
よくよく考えてみればこのエラーは理解できるのだが、そもそもじゃあなぜ変更前はうまくいっていたんだ?と逆に疑問に思った。

結局これはどういうことかというと、最初のロジックの動作は以下の様なイメージ。

$b =  $a | %{ $_ }

要は値が詰めなおされている。
その際、$a の要素は1つなので$bの型は配列ではなく単なるstringになるのだ。


ここで、もう一つ今まで気づいていなかったことが発生。

$b にもともと値が入っていなければ最初のロジックで良いのだが、$bにもともと値が入っていて、ある条件の時だけ$aを設定したいといった時にこのロジックはうまくいかない。
どうも以下の様な動作をして$bの値をつぶしてしまうようだ。

$b = if( $true ){ $a } else { $null }

いままで結構Powershellを使ってきたがまだまだ気づいていないことがありますね。

結局今回のニーズでどのようなロジックがベストかは難しいところ。
以下の様なロジックを書いていたら、後から見た人にどちらかののIF文を削除される可能性もありそうですよね。

if( $hoge –eq $true ){
    $b = if( $hoge –eq $true) { $a }
}