Итерирование с помощью имен ключей из PSCustomObject
Я пишу script для моего сайта, который использует файл конфигурации JSON. JSON похож на следующее:
"Groups": {
"GroupOne": {
"NamingFilter": {
"Not":"<SITE>-MJ*",
"Has":"*WM,*WT"
}
},
"GroupTwo": {
"NamingFilter": {
"Has":"<SITE>-MJ*, *WC,*WL"
}
},
"GroupThree": {
"NamingFilter": {
"Not":"<SITE>-MJ*",
"Has":"*WI"
}
}
}
Чтобы преобразовать объект в нечто, что может прочитать PowerShell, я использую ConvertFrom-Json
, который преобразует его в тип PSCustomObject
Я нахожусь в точке, где мне нужно перебирать Groups
и получить каждое имя группы для вывода их и их соответствующего индекса в объекте config Groups
. То есть:.
1. GroupOne
2. GroupTwo
3. GroupThree
Самое дальнее, что я получил:
foreach ($group in $configObject.Groups) {
$group
}
и все это выводит то, что выглядит как обозначение PS:
@{GroupOne=; GroupTwo=; GroupThree=;}
Возможно ли это с типом PSCustomObject
? Я в первую очередь кодирую в JavaScript, поэтому, возможно, я упрощаю (или чрезмерную) проблему, поскольку это будет относительно легко.
Ответы
Ответ 1
Я думаю, что, возможно, просто вычислил это благодаря следующему сайту:
http://blogs.msdn.com/b/timid/archive/2013/03/05/converting-pscustomobject-to-from-hashtables.aspx
Используя Get-Member
, а затем -MemberType
выставляет каждую группу, а затем вы просто тянете
foreach ($group in $configObject.Groups) {
$groupName = $($group | Get-Member -MemberType *Property).Name
}
Выходы:
GroupOne
GroupTwo
GroupThree
Я открыт для любых других методов.
Update
Итак, я нашел другой путь, но единственным недостатком является то, что он не использует причудливый ConvertFrom-Json
CmdLet. Вместо этого он идет прямо в библиотеку .NET и использует его десериализатор и преобразует его в HashTable. Это полностью позволяет избежать путаницы с PSCustomObject. С hashtables IMO намного легче работать.
$JSON = Get-Content -Path path/to.json -Raw
$HT = (New-Object System.Web.Script.Serialization.JavaScriptSerializer).Deserialize($JSON, [System.Collections.Hashtable])
$HT.Groups.GetEnumerator() | ForEach-Object {
Write-Host "$($_.Key) : $($_.Value)"
}
Ответ 2
Решение
Я не уверен, как в начале версии вы можете это сделать, но это работает для меня в PowerShell 5.1... не стесняйтесь попробовать в более ранних версиях:
$ipinfo = Invoke-WebRequest 'http://ipinfo.io/json' -UseBasicParsing | ConvertFrom-Json
foreach ($info in $ipinfo.PSObject.Properties) {
$info.Name
$info.Value
'--' # <-- Seeing this double hash proves we're iterating fully.
}
Выходы
ip
1.2.3.4
--
hostname
No Hostname
--
city
Denton
--
region
Texas
--
country
US
--
loc
33.2148,-97.1331
--
org
AS589 University of North Texas
--
postal
76203
--
Все это делается с помощью PowerShell 4.0; ConvertTo-Json
и ConvertFrom-Json
были представлены в PowerShell 3.0; Я не тестировал PowerShell 3.0 или 5.0.
Другой пример
Попробуйте это для себя с помощью другого примера:
$ipinfo = ConvertFrom-Json (Invoke-WebRequest 'http://ipinfo.io/json' -UseBasicParsing)
foreach ($info in ($ipinfo.PSObject.Members | ?{ $_.MemberType -eq 'NoteProperty'})) {
$info.Name
$info.Value
'--'
}
Выходы
ip
1.2.3.4
--
hostname
No Hostname
--
city
Denton
--
region
Texas
--
country
US
--
loc
33.2148,-97.1331
--
org
AS589 University of North Texas
--
postal
76203
--
Этот и другие циклы PowerShell доступны в моем блоге.