Итак, надеюсь, кто-нибудь поможет мне пересечь финишную черту. Я собрал немного кода, по сути, полученный от гораздо более умного пользователя форума для аналогичной цели.
Я пытаюсь взять все регистрации приложений и их секреты/даты истечения срока действия сертификатов и поместить эту информацию в PSCustomObject.
Это фрагмент кода, который выполняет работу
# Loop through all apps and add to PSCustomObject
$uri = 'https://graph.microsoft.com/beta/applications?$select=displayName, passwordCredentials, id'
$result = do {
$Data = Invoke-RestMethod -Method Get -Uri $uri -Headers $Headers
$uri = $Data.'@odata.nextLink'
foreach ($app in $Data.value) {
$appUri = 'https://graph.microsoft.com/beta/applications?$select=displayName, passwordCredentials, id'
$allAppSecretsExpiry = do {
$cred = Invoke-RestMethod -Method Get -Uri $appUri -Headers $Headers
$appUri = $cred.'@odata.nextLink'
if ($cred) {
$cred.value.passwordCredentials.endDateTime
}
}
while ($appUri)
[pscustomobject]@{
displayName = $app.displayName
id = $app.id
Credentials = $allAppSecretsExpiry
}
}
}
while ($uri)
Затем я получаю список всех приложений и их идентификаторы, а также свойство даты истечения срока действия: я получаю все даты истечения срока действия для всех приложений, что-то вроде этого
APP1 {2025-05-15 17:55:57, 2024-08-13 08:55:07, 2026-04-15 09:06:50, 202…
APP2 {2025-05-15 17:55:57, 2024-08-13 08:55:07, 2026-04-15 09:06:50, 202…
APP3 {2025-05-15 17:55:57, 2024-08-13 08:55:07, 2026-04-15 09:06:50, 202…
APP4 {2025-05-15 17:55:57, 2024-08-13 08:55:07, 2026-04-15 09:06:50, 202…
Я уверен, что допустил ошибку в цикле foreach, но не понимаю, где именно.
Надеюсь, какая-нибудь добрая душа сможет мне помочь, и по пути я чему-нибудь научусь.
У участников службы может быть много секретов, вам не хватает внутреннего цикла $cred.value.passwordCredentials
, для каждого секрета по сути создается новый объект. это может помочь: gist.github.com/santisq/…
@SantiagoSquarzon спасибо за публикацию этой ссылки, она выглядит довольно интересно и выглядит лучшей версией того, что я пытаюсь сделать, хотя при запуске ее в своей среде я получаю сообщение об ошибке. Cannot convert argument "app", with value: "@{appId=4a29eb17-0f49-44ca-8140-XXXXXXXXXX; id=XXXXXXXX-4ee7-4625-9ac5-9feac574ad4b; displayName=<REDACTED>; .................. "System.Management.Automation.PSCustomObject" to type "System.Collections.Hashtable".""
Не думайте, что вы видели это раньше.
@thekevinkalis, поэтому эта ошибка заставляет меня думать, что вы не используете Invoke-MgGraphRequest
, а вместо этого используете Invoke-RestMethod
, потому что командлет Mg выводит хеш-таблицы в качестве вывода по умолчанию и Invoke-RestMethod
преобразует ответ Json в PSCustomObject. Использование Invoke-MgGraphRequest
важно в этом коде.
@SantiagoSquarzon Я нахожу потрясающим то, что вы можете сказать это только по сообщению об ошибке. Я стараюсь использовать «Invoke-RestMethod», насколько это возможно, но, очевидно, все еще изучаю особенности. Я не думаю, что существует быстрый/простой способ настроить ваш сценарий, чтобы он работал. Это немного выше моих средних способностей.
добавил ответ, хотя я рекомендую использовать Invoke-MgGraphRequest
, это действительно приятно, потому что вам не нужно заботиться об обновлении токена, он делает это за вас.
Основная проблема вашего кода заключается в том, что вам не хватает внутреннего цикла для прохождения каждого секрета (свойство .passwordCredentials
). Поскольку приложения могут иметь более одного секрета, в конечном итоге вы получаете один объект для каждого приложения со всеми секретами в виде массива. Исправить проблему довольно просто:
$invokeRestMethodSplat = @{
Method = 'GET'
Uri = 'https://graph.microsoft.com/v1.0/applications?$select=displayName, passwordCredentials, id'
Headers = @{
Authorization = 'Bearer {myTokenGoesHere}'
}
}
$result = do {
$Data = Invoke-RestMethod @invokeRestMethodSplat
$invokeRestMethodSplat['Uri'] = $Data.'@odata.nextLink'
foreach ($app in $Data.value) {
foreach ($secret in $app.passwordCredentials) {
[pscustomobject]@{
displayName = $app.displayName
id = $app.id
startDateTime = $secret.startDateTime
endDateTime = $secret.endDateTime
secretDisplayName = $secret.displayName
}
}
}
}
while ($invokeRestMethodSplat['Uri'])
# do stuff with `$result`
$result ...
Обратите внимание, что эта текущая реализация охватывает только секреты клиента (clientId + секретный пароль). Если вы хотите также включить сертификаты клиента, вам необходимо включить keyCredentials
в параметр $select
и добавить дополнительный внутренний цикл в $app.keyCredentials
.
Это было именно то, что я искал, спасибо. Кроме того, я впервые вижу, чтобы Invoke-RestMethod вызывался таким образом, поэтому спасибо, что научили меня чему-то новому.
Я рад, что это было полезно @thekevinkalis. обратите внимание, что эта текущая реализация распространяется только на секреты клиента (clientId + секретный пароль). если вы хотите также включить клиентские сертификаты, вам нужно включить keyCredentials
в свой $select
и вам нужно будет включить дополнительный внутренний цикл $app.keyCredentials
, как в сути, которой я поделился ранее. Если у вас есть дополнительные вопросы по этому поводу, не стесняйтесь задавать новые вопросы на этом сайте.
вы можете посмотреть этот сайт о PScustumObject Learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/…