Команда Get-Service Powershell выводит служебный код вместо текстового статуса? - PullRequest
1 голос
/ 27 сентября 2019

У меня есть довольно простой код, который перебирает вывод Get-Service | Select Name, DisplayName, Status и затем форматирует его в объект json.Проблема, с которой я сталкиваюсь, состоит в том, что выполнение этой команды за пределами моего сценария powershell возвращает фактический текстовый статус (RUNNING, STOPPED и т. Д.), Но в сценарии статус числовой (1-4).В настоящее время я использую версию PS 5.1.18362.145

Сценарий:

$services = Get-Service | Select Name, DisplayName, Status

$services.ForEach({
    Add-Member -NotePropertyName 'table' -NotePropertyValue 'Status' -InputObject $_;
})

$payload = @{
    metrics = @($services)
} | ConvertTo-Json

Write-Output ($payload)

Пример вывода:

                    {
                        "Name":  "WPDBusEnum",
                        "DisplayName":  "Portable Device Enumerator Service",
                        "Status":  1,
                        "table":  "Status"
                    },
                    {
                        "Name":  "WpnService",
                        "DisplayName":  "Windows Push Notifications System Service",
                        "Status":  4,
                        "table":  "Status"
                    },
                    {
                        "Name":  "WpnUserService_8be1a",
                        "DisplayName":  "Windows Push Notifications User Service_8be1a",
                        "Status":  4,
                        "table":  "Status"
                    }

Я бы предпочел, чтобы Status оставалось текстовым, а нечисловой.Это что-то особенное для PS 5?

Ответы [ 2 ]

2 голосов
/ 27 сентября 2019

Свойство .Status из [System.ServiceProcess.ServiceController] указывает, что выходные данные командлета Get-Service имеют тип [System.ServiceProcess.ServiceControllerStatus], который является перечислением тип (производным от [System.Enum]): то есть он связывает символические имена с числовыми значениями;например, символическое имя Stopped связано с номером 1.

ConvertTo-Json сериализует такие значения перечисления как числа :

  • неизменно в Windows PowerShell.

  • по умолчанию в PowerShell Core ;вместо этого вы можете использовать символические имена (например, строки ), используя переключатель -EnumsAsStrings.

В Windows PowerShell вам необходимо явно преобразуйте символьные имена в строки перед , вызывая ConvertTo-Json, чего можно достичь с помощью вычисляемого свойства ;Вот упрощенный пример:

Get-Service | 
  Select-Object Name, 
                DisplayName, 
                @{ n='Status'; e={ $_.Status.ToString() } },
                @{ n='table'; e={ 'Status' } } | 
    ConvertTo-Json

Выше приведено что-то вроде следующего;обратите внимание, что свойство "Status" теперь содержит строки, представляющие символические имена типа перечисления:

{
    "Name":  "AppIDSvc",
    "DisplayName":  "Application Identity",
    "Status":  "Stopped",
    "table":  "Status"
},
{
    "Name":  "Appinfo",
    "DisplayName":  "Application Information",
    "Status":  "Running",
    "table":  "Status"
}
...

Применимо к вашему сценарию:

[pscustomobject] @{
  metrics = @(
    Get-Service | 
      select Name, 
             DisplayName, 
             @{ n='Status'; e={ $_.Status.ToString() } },
             @{ n='table'; e={ 'Status' } }
  )
} | ConvertTo-Json

Обратите внимание, как использоватьдостаточно одного трубопровода.

1 голос
/ 27 сентября 2019

Вы можете сделать что-то вроде этого:

$services = New-Object System.Collections.ArrayList
foreach ($service in (Get-Service)){
    $services.Add(@{"Name"= $service.Name; "DisplayName" = $service.DisplayName; "Status" = $service.Status.ToString()}) | Out-Null
}

$payload = @{
    metrics = @($services)
} | ConvertTo-Json

Write-Output ($payload)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...