Вопрос или проблема
PowerShell-скрипты, которые я пишу, должны быть максимально совместимыми, поэтому при проверке состояния вещей я всегда предпочитаю использовать перечисления (4
), вместо строк (Enabled
). В 99% случаев строковое значение остается постоянным даже на локализованных версиях Windows, но всегда найдется одно устройство, на котором это не так, и на нем будет выполняться мой скрипт, что приведет к проблемам. Это нормально, пока я знаю, каким перечислениям соответствуют значения, но получение этой информации подобно вырыванию зубов.
Пример: Службы
Поиск “service state enum powershell” приведет вас сюда, где вы можете увидеть хорошую таблицу, перечисляющую значения для состояния службы, которые соответствуют значению, полученному из выполнения (get-service 'xyz').status.value__
. Это позволяет мне сказать
if ($value -eq 1)
вместо if ($value -eq 'enabled')
, что является гораздо более надежным сравнением.
Опять же, нормально, если вы знаете, что искать.
Собственно вопрос
Существует ли какая-то команда в PowerShell или сайт, который я могу использовать, чтобы вывести эти перечисления value__
? Сейчас я пытаюсь найти перечисление для значения state
из get-WindowsOptionalFeature
, и у меня ничего не выходит. Уж не для этого ли это так разрозненно? Я самоучка, поэтому надеюсь, что существует какой-то общедоступный репозиторий этих данных, который я просто пропустил.
Да, возможно просмотреть возможные значения.
$feature = Get-WindowsOptionalFeature -Online | Select-Object -First 1
$feature.State | Get-Member
В начале вывода сказано TypeName: Microsoft.Dism.Commands.FeatureState
Следующая команда предоставит вам список возможных значений в виде массива
[enum]::GetValues([Microsoft.Dism.Commands.FeatureState])
Результатом будет:
Disabled
DisablePending
Enabled
EnablePending
Superseded
PartiallyInstalled
DisabledWithPayloadRemoved
И вы можете использовать индекс вместо строки.
Get-WindowsOptionalFeature -Online | Where-Object { $_.State -eq 0 }
Вы также можете использовать перечисление напрямую
Get-WindowsOptionalFeature -Online | Where-Object { $_.State -eq [Microsoft.Dism.Commands.FeatureState]::Disabled }
.
Ответ или решение
Вопрос о получении значений value__
из перечислений (enum) в PowerShell действительно важен, особенно для автоматизации сценариев, которые должны быть совместимы на различных системах и локализациях Windows. Использование числовых значений из enum позволяет минимизировать риски, связанные с несоответствием строковых значений в локализованных версиях. В данной статье я подробно объясню, как эффективно работать с перечислениями в PowerShell, используя пример из поста, а также дам рекомендации для дальнейшей работы.
Теоретическая часть
В PowerShell перечисления (enum) представляют собой набор именованных констант, каждая из которых имеет числовое значение. Это позволяет программистам ссылаться на именованные состояния, не заботясь о возможных изменениях строковых представлений. Работая с перечислениями, вы обеспечиваете дополнительную стабильность и устойчивость к различным внешним изменениям, будь то локализация или обновления ПО.
Одним из часто встречающихся сценариев является проверка состояния служб или функций ОС. К примеру, если вам нужно проверить состояние службы, вы можете использовать числовые значения, которые представляют определенные состояния, такие как "включена", "выключена", "в процессе включения" и другие.
Пример
Возьмем пример, описанный в вопросе: необходимо получить значения состояния для опциональной функции Windows при помощи Get-WindowsOptionalFeature
. Для этого мы можем использовать метод GetValues()
из .NET Framework, который позволит вам перечислить все возможные значения enum:
$feature = Get-WindowsOptionalFeature -Online | Select-Object -First 1
$feature.State | Get-Member
На выходе вы получите данные о типе, здесь TypeName: Microsoft.Dism.Commands.FeatureState
. Вы можете получить все возможные значения enum с помощью следующей команды:
[enum]::GetValues([Microsoft.Dism.Commands.FeatureState])
Результат будет выглядеть так:
Disabled
DisablePending
Enabled
EnablePending
Superseded
PartiallyInstalled
DisabledWithPayloadRemoved
Эти значения можно использовать для написания более устойчивого к изменениям кода. Например:
Get-WindowsOptionalFeature -Online | Where-Object { $_.State -eq [Microsoft.Dism.Commands.FeatureState]::Disabled }
Применение и рекомендации
Использование перечислений вместо строковых сравнений повышает надежность и снижает вероятность ошибок, вызванных изменениями строк в разных локализациях. При написании скриптов на PowerShell, особенно тех, что планируются для широкого использования, рекомендуется:
-
Использовать одноманитные подходы: Всегда старайтесь работать с числовыми значениями или именами членов enum вместо строковых описаний.
-
Регулярно проверять документацию: Microsoft активно обновляет свои API и enum, поэтому регулярная проверка официальной документации и ресурсов, таких как MSDN или Microsoft Learn, жизненно важна.
-
Иметь локальную библиотеку: Собирайте подобные перечисления и их числовые значения в локальной базе знаний или файле справочника, чтобы ваши коллеги и вы могли быстро находить соответствующие числа и состояния.
-
Разработайте общий подход: Ведите журнал локальных изменений и примеры использования перечислений в вашем коде, это поможет новым членам команды быстро вникнуть в ваш код.
-
Тестируйте на разных локализациях: Если возможно, тестируйте ваши скрипты на различных локализованных системах. Хотя использование enum устраняет большинство проблем, всегда полезно убедиться, что никаких скрытых проблем не осталось.
В заключение, использование value__
из enum в PowerShell является мощной техникой для создания более надежных и универсальных скриптов. Однако не забывайте, что регулярная проверка изменений в платформе и общее понимание работы API позволит вам оставаться впереди и поддерживать свои проекты на высоком уровне.