PSCustomObject неправильно форматирует вывод - PullRequest
0 голосов
/ 23 апреля 2020

У меня проблемы с добавлением данных в PSCustomObject.

Мой скрипт использует Invoke-RestMethod для запроса данных из API, из которого я затем сохраняю переменную и использую Select-Object и Format-Table вывести это красиво. Первоначальная проблема, с которой я столкнулся, заключалась в том, что дата и время, возвращаемые в ответе, были в формате ISO8601, на который просто не приятно смотреть. Таким образом, используя приведенный ниже код, я отформатировал дату и время в гораздо более удобочитаемом формате и сохранил их в своем собственном PSCustomObject, однако я столкнулся с проблемой при возврате этого отформатированного datetime обратно в исходный PSCustomObject.

Перед использованием Add-Member для добавления данных в переменную PSCustomObject данные отображаются великолепно, однако, как только они добавляются обратно, я пытаюсь запустить команду, такую ​​как Select-Object или Format- В таблицу добавлена ​​куча отступов, которая полностью портит мой вывод при непосредственном доступе к значению, которое оно отображает, как и ожидалось. Я абсолютно застрял здесь, как решить эту проблему. (Приведенный ниже код запускается сразу после того, как я использую Invoke-RESTMethod и сохраняю возвращенные данные в переменной).

## Extracts the time property from the PSCustomObject and re-formats it to an easily readable format.
$datetime = $HTTPResponse.psobject.Properties.value | Select-Object -Property time
$uDateTimeRegex = $datetime -replace "[@]" -replace "[}]" -replace "[=]" -replace "[{]" -replace "time" -replace "[Z]" -split ' '

ForEach ($SplitTime in $uDateTimeRegex){
    $FormattedDateTimeArray = ($uDateTimeRegex).split('.') | Select-String -Pattern '[a-z]'
}

$CorrectDateTime = @()
$CorrectDateTime = for ($i=0; $i -lt $FormattedDateTimeArray.count; $i++) {
    [datetime]::ParseExact($FormattedDateTimeArray[$i], 'yyyy-MM-ddTHH:mm:ss', $null).ToString('HH:mm dd-MM-yyyy')
}

## Converts the newly created $CorrectDateTime array into a PSCustomObject
$CaseTimeObj = ForEach ($dt in $CorrectDateTime){

    [PSCustomObject]@{
        CaseDateTime = $dt
    }
}
## Uses a foreach loop and Add-Member to add the contents of PSCustomObject $CaseTimeObj to the pre-existing PSCustomObject created from the HTTP reponse
$objProperties = Get-Member -InputObject $CaseTimeObj -MemberType Property
foreach ($p in $objProperties){
    $HTTPResponse | Add-Member -MemberType NoteProperty -Name CaseDateTime -Value $CaseTimeObj.$($p.Name) -Force
}

## Selects required values from PSCustomObject variable and formats them for output
$HTTPOutput = $HTTPResponse.psobject.Properties.value | Select-Object -Property Title, userAssigned, id, CaseDateTime, environment | Format-Table @{L='Case Name';E={$_.Title}}, @{L='Assigned User';E={$_.userAssigned}}, @{L='Case ID';E={$_.id}}, @{L='Creation Time';E={$_.CaseDateTime}}, @{L='Client';E={$_.environment}} 

$HTTPOutput

Вывод с использованием вышеуказанного кода

Вывод с HTTP-ответом по умолчанию, без изменения даты и времени

Прямой доступ к значениям

Доступ к значениям с помощью Select-Object

EDIT, содержимое переменной $ datetime в соответствии с запросом:

PS > $datetime

time
----
2020-04-23T16:26:44.626Z
2020-04-23T16:27:47.511Z
2020-04-23T16:28:29.394Z
2020-04-23T16:28:58.413Z
2020-04-23T16:29:24.936Z
2020-04-23T16:29:59.462Z
2020-04-23T16:30:31.927Z
2020-04-23T16:31:07.173Z
2020-04-23T16:40:23.39Z

1 Ответ

0 голосов
/ 23 апреля 2020

Похоже, вы действительно слишком усложняете это.

Даты в $ HTTPResponse представлены в формате ISO8601, поэтому их очень легко преобразовать в объект datetime . * 1005. *

Вы можете сделать это либо с Get-Date '2020-04-23T16:26:44.626Z', либо с [datetime]::Parse('2020-04-23T16:26:44.626Z').

Оба метода приведут к объекту datetime, преобразованному в местное время . Если вам нужно, чтобы дата оставалась UT C, сделайте (Get-Date '2020-04-23T16:26:44.626Z').ToUniversalTime() или ([datetime]::Parse('2020-04-23T16:26:44.626Z')).ToUniversalTime()

Создание объекта datetime позволяет вам форматировать его любым удобным вам способом, даже ( IMO довольно странно) 'HH:mm dd-MM-yyyy' строковый формат.

Все это можно сделать в вычисляемом свойстве:

$HTTPOutput = $HTTPResponse.psobject.Properties.value | 
              Select-Object -Property @{Name = 'Case Name'; Expression = {$_.Title}}, 
                                      @{Name = 'Assigned User'; Expression = {$_.userAssigned}}, 
                                      @{Name = 'Case ID'; Expression = {$_.id}}, 
                                      @{Name = 'Creation Time'; Expression = { '{0:HH:mm dd-MM-yyyy}' -f [datetime]::Parse($_.time)}}, 
                                      @{Name = 'Client'; Expression = {$_.environment}}

# output on screen
$HTTPOutput | Format-Table -AutoSize

# if you like, output to CSV file
$HTTPOutput | Export-Csv -Path 'X:\TheOutput.csv' -NoTypeInformation

Если вам не нужно создавать массив объектов $ HTTPOutput и просто просто хотите отобразить на экране, тогда вы можете использовать те же вычисленные свойства непосредственно для Format-Table.

Это не вернет ничего, кроме данных на экране в формате таблицы:

$HTTPResponse.psobject.Properties.value |
Format-Table @{Name = 'Case Name'; Expression = {$_.Title}}, 
             @{Name = 'Assigned User'; Expression = {$_.userAssigned}}, 
             @{Name = 'Case ID'; Expression = {$_.id}}, 
             @{Name = 'Creation Time'; Expression = { '{0:HH:mm dd-MM-yyyy}' -f [datetime]::Parse($_.time)}}, 
             @{Name = 'Client'; Expression = {$_.environment}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...