Вывод объекта сравнения Powershell 1 строка на элемент
Я пытаюсь вывести результат сравнения объекта. Я новичок в Powershell и, к сожалению, пока не знаю все подробности.
Моя команда выглядит следующим образом:
Compare-Object -referenceObject $(Get-Content "c:\temp\mek\123-first.txt") -differenceObject $(Get-Content "c:\temp\mek\123-second.txt") | %{$_.Inputobject} | sort-object | out-file "c:\temp\mek\results.txt"
Содержимое моих файлов выглядит следующим образом (просто сравнивая службы Windows):
имя системы ---------- ---- ----- --------- D7MCYP AdobeARMservice остановлен авто D7MCYP AdobeFlashPlayerUpdateSvc Остановлено вручную D7MCYP AeLookupSvc Остановлено руководство
Мои результаты сравнения объекта следующие:
BL3C4V wudfsvc остановлен авто BL3C4V wudfsvc Остановлено руководство D7MCYP AdobeARMservice Запуск Авто D7MCYP AdobeARMservice остановлен авто
Теперь, если кто-нибудь может помочь в выводе, сохранить первые 2 столбца для каждого сервера и различные значения столбцов 3,4 для новых столбцов (5,6). Также было бы хорошо, если бы я тоже получал титулы. Например:
Служба сервера перед состоянием до режима после состояния после режима BL3C4V wudfsvc Остановлено Авто Остановлено вручную D7MCYP AdobeARMservice Запуск Авто Остановлено Авто
1 ответ
Примечание. Приведенный ниже код является упражнением в разборе текстовых данных на объекты для более надежной и гибкой обработки.
В идеале, однако, обработка должна начинаться с объектов, а не с простого текста, поэтому начинаем с командлетов PowerShell, таких как Get-Service
а не вывод текста из внешних утилит предпочтительнее.
Предполагая, что все записи в каждом входном файле имеют соответствующую запись server + service-name в соответствующем другом файле:
$f1, $f2 = "c:\temp\mek\123-first.txt", "c:\temp\mek\123-second.txt"
Compare-Object (Get-Content $f1) (Get-Content $f2) | ForEach-Object {
$i = 0; $ht = @{}; $vals = -split $_.InputObject
foreach($col in 'Server', 'Service', 'State', 'Mode') {
$ht.$col = $vals[$i++]
}
$ht.Before = $_.SideIndicator -eq '<='
[pscustomobject] $ht
} | Group-Object Server, Service | ForEach-Object {
$ndxBefore, $ndxAfter = if ($_.Before) { 0, 1 } else { 1, 0 }
[pscustomobject] @{
Server = $_.Group[0].Server
Service = $_.Group[0].Service
'State Before' = $_.Group[$ndxBefore].State
'Mode Before' = $_.Group[$ndxBefore].Mode
'State After' = $_.Group[$ndxAfter].State
'Mode After' = $_.Group[$ndxAfter].Mode
}
} | Sort-Object Server, Service |
Format-Table
Замечания:
Выше форматирует вывод для отображения (используя
Format-Table
), не отправляя его в файл.
Вы можете добавить| Out-File "c:\temp\mek\results.txt"
сохранить то же представление в файл.Однако учтите, что команда - раньше
Format-Table
применяется - возвращает объекты с индивидуальными свойствами, поэтому вы можете выводить в файл в различных форматах, например, используяExport-Csv
, например.
Пример вывода:
Server Service State Before Mode Before State After Mode After
------ ------- ------------ ----------- ----------- ----------
D7MCYP AdobeFlashPlayerUpdateSvc Stopped Manual Stopped Auto
D7MCYP AeLookupSvc Stopped Manual Started Manual
Пояснение:
Используется один длинный конвейер, что делает код лаконичным и эффективным для памяти.
Трубопровод ломается следующим образом:
Сравнение:
Compare-Object
сравнивает массив строк из двух входных файлов, возвращаемыхGet-Content
звонки и выходы[pscustomobject]
экземпляры, представляющие найденные различия, со строковым свойством.SideIndicator
указание, находится ли линия под рукой (доступно через.InputObject
) является уникальным для LHS (1-й входной файл) -<=
- или RHS (2-й входной файл) ->=
Преобразование в пользовательские объекты:
Блок скрипта (
{ ... }
) перешел кForEach-Object
выполняется для каждого входного объекта (представлен как$_
).-split $_.InputObject
разбивает имеющуюся "разностную линию" на поля с помощью пробелов и сохраняет полученные поля в виде массива в$vals
,$ht
является вспомогательной хэш-таблицей, которая используется для сопоставления значений полей с именами полей.$ht.Before
добавляет булеву запись, чтобы указать, является ли линия разницы от "до файла" (1-й входной файл) или нет.[pscustomobject] $ht
преобразует aux. hashtable в пользовательский объект и выводит его (отправляет через конвейер).
Группировка:
Group-Object
используется для группировки результирующих объектов может быть общимServer
а такжеService
значения свойств, в результате чего[Microsoft.PowerShell.Commands.GroupInfo]
экземпляр, представляющий каждую группу.
Преобразование в комбинированные пользовательские объекты:
Снова,
ForEach-Object
используется для выполнения обработки объекта ввода.[pscustomobject] @{ ... }
используется для создания каждого комбинированного выходного объекта, снова используя вспомогательную хэш-таблицу.$_.Group
содержит входные объекты, которые формируют каждую группу - в нашем случае,$_.Group[0]
а также$_.Group[1]
это строки ввода, преобразованные в объекты, представляющие данную комбинацию сервер-сервис.По определению оба входных объекта имеют одинаковые
.Server
а также.Service
значения, так что вслепую$_.Group[0]
Значения для объединенного объекта вывода будут делать.В отличие от
* Before
а также* After
Свойства соответствующего входного объекта (из 1-го или 2-го файла), поэтому индексы массива$ndxBefore
а также$ndxAfter
выбираются соответственно через ранее добавленные.Before
имущество
Сортировка:
Sort-Object
сортирует результирующие объекты по указанным свойствам.
Форматирование вывода:
- Командлет форматирования вывода
Format-Table
обеспечивает сортировку объектов в виде таблицы.
- Командлет форматирования вывода