| Zrovna včera jsem v PowerShell potřeboval najít jednu Property. Věděl jsem její jméno, měl jsem jeden root objekt. V mém případě se jednalo o TMG objekt (fpc.root) a šlo mi o to, najít property UseLegacyErrorPagesDirectory, kterou se přepínají error pages z původní RTM verze na SP2 verzi. Tyhle informace jsem zjistil z change tracking, to je ok. Jenže kde ta property je, ve kterém objektu? Uvnitř TMG objektu je hromada property, žádná z nich to není. Většina těch properties jsou hlubší objekty. A mají další hlubší podobjekty. A někde tam to je.
Tak jsem si napsal prográmek. Dáte mu jeden objekt a on "rekurzivně" projede všechny property do hloubky. Projede samozřejmě jenom ty, které nejsou $null, ale to v daném problému nevadí.
Připadlo mě to jako zajímavý problém, protože to vyžaduje rekurzi a já jsem ji chtěl udělat bez rekurze, jen pomocí ArrayList seznamu. Navíc je to zajímavá ukázka, protože nemůžete ten seznam projíždět foreach cyklem, protože budete měnit jeho obsah uvnitř toho cyklu a to se nesmí.
function global:Get-MemberMap ([object] $startObj)
{
[Collections.ArrayList] $propertyMap = @()
$maxLevel = 4
[Collections.ArrayList] $objectsToProcess = @()
[void] $objectsToProcess.Add(@('', 0, $tmg))
while ($objectsToProcess.Count -gt 0) {
$oneObjPath = $objectsToProcess[0][0]
$oneObjLevel = $objectsToProcess[0][1]
$oneObj = $objectsToProcess[0][2]
$objectsToProcess.RemoveAt(0)
$properties = gm -i $oneObj -memb Property -EA SilentlyContinue | Select -Expand Name
$error.Clear()
foreach ($oneProperty in $properties) {
if (($oneProperty -ne '') -and ($oneProperty -ne $null)) {
$onePropertyPath = '{0}.{1}' -f $oneObjPath, $oneProperty
[void] $propertyMap.Add($onePropertyPath)
[void] $objectsToProcess.Add(@($onePropertyPath, ($oneObjLevel + 1), $oneObj.$oneProperty))
}
}
if ($oneObjLevel -eq $maxLevel) {
break
}
}
return $propertyMap
}
A nakonec to bylo až tady .ArrayPolicy.WebProxy.UseLegacyErrorPagesDirectory. |