2016-08-04 3 views
2

В Powershell (3.0), я получаю разные результаты при конвейерной передаче объекта в Export-CSV, чем я, если я использую параметр -IncludeObject с тем же объектом.powershell piped input to export-csv отличается от -inputobject

Пример:

$a = Get-Process | select -first 5 
$a | Export-CSV -Path '.\one.csv' 
Export-CSV -InputObject $a -Path '.\two.csv' 

Почему содержимое one.csv и two.csv разные?

(И в случае, если это только мне ...)

one.csv =

#TYPE System.Diagnostics.Process 
"__NounName","Name","Handles","VM","WS","PM","NPM","Path","Company","CPU","FileVersion","ProductVersion","Description","Product","BasePriority","ExitCode","HasExited","ExitTime","Handle","HandleCount","Id","MachineName","MainWindowHandle","MainWindowTitle","MainModule","MaxWorkingSet","MinWorkingSet","Modules","NonpagedSystemMemorySize","NonpagedSystemMemorySize64","PagedMemorySize","PagedMemorySize64","PagedSystemMemorySize","PagedSystemMemorySize64","PeakPagedMemorySize","PeakPagedMemorySize64","PeakWorkingSet","PeakWorkingSet64","PeakVirtualMemorySize","PeakVirtualMemorySize64","PriorityBoostEnabled","PriorityClass","PrivateMemorySize","PrivateMemorySize64","PrivilegedProcessorTime","ProcessName","ProcessorAffinity","Responding","SessionId","StartInfo","StartTime","SynchronizingObject","Threads","TotalProcessorTime","UserProcessorTime","VirtualMemorySize","VirtualMemorySize64","EnableRaisingEvents","StandardInput","StandardOutput","StandardError","WorkingSet","WorkingSet64","Site","Container" 
"Process","AATray","390","156721152","29769728","10678272","27600","C:\Program Files\IBM\ISAM ESSO\AA\AATray.exe","IBM Corporation","42.4166719","8.2.1.1143","8.2.1.1143","AccessAgent Tray Icon: Component of ISAM ESSO AccessAgent","ISAM ESSO AccessAgent","8",,"False",,"4844","390","7784",".","0","","System.Diagnostics.ProcessModule (AATray.exe)","1413120","204800","System.Diagnostics.ProcessModuleCollection","27600","27600","10678272","10678272","257536","257536","63672320","63672320","29806592","29806592","194101248","194101248","True","Normal","10678272","10678272","00:00:32.8070103","AATray","15","True","1","System.Diagnostics.ProcessStartInfo","8/2/2016 7:20:30 AM",,"System.Diagnostics.ProcessThreadCollection","00:00:42.4166719","00:00:09.6096616","156721152","156721152","False",,,,"29769728","29769728",, 
"Process","ac.activclient.gui.scagent","547","155099136","22593536","8478720","33184","C:\Program Files\ActivIdentity\ActivClient\ac.activclient.gui.scagent.exe","HID Global Identity Assurance","2.2932147","7,0,5,17","7,0","ActivClient Agent","${release.product.name}","8",,"False",,"3648","547","7872",".","0","","System.Diagnostics.ProcessModule (ac.activclient.gui.scagent.exe)","1413120","204800","System.Diagnostics.ProcessModuleCollection","33184","33184","8478720","8478720","274408","274408","62431232","62431232","22659072","22659072","168542208","168542208","True","Normal","8478720","8478720","00:00:01.8876121","ac.activclient.gui.scagent","15","True","1","System.Diagnostics.ProcessStartInfo","8/2/2016 7:20:30 AM",,"System.Diagnostics.ProcessThreadCollection","00:00:02.2932147","00:00:00.4056026","155099136","155099136","False",,,,"22593536","22593536",, 
"Process","accagt","166","508174336","17592320","25407488","26116",,,,,,,,"8",,,,,"166","2480",".","0","",,,,,"26116","26116","25407488","25407488","159440","159440","25657344","25657344","17694720","17694720","509747200","509747200",,,"25407488","25407488",,"accagt",,"True","0","System.Diagnostics.ProcessStartInfo",,,"System.Diagnostics.ProcessThreadCollection",,,"508174336","508174336","False",,,,"17592320","17592320",, 
"Process","acevents","506","140414976","22474752","8048640","30856","C:\Program Files\ActivIdentity\ActivClient\acevents.exe","HID Global Identity Assurance","42.6350733","5,0,4,4","5,0","ActivIdentity Event Service","ActivClient Services","8",,"False",,"3872","506","8256",".","0","","System.Diagnostics.ProcessModule (acevents.exe)","1413120","204800","System.Diagnostics.ProcessModuleCollection","30856","30856","8048640","8048640","249632","249632","61378560","61378560","22528000","22528000","157003776","157003776","True","Normal","8048640","8048640","00:00:24.6013577","acevents","15","True","1","System.Diagnostics.ProcessStartInfo","8/2/2016 7:20:34 AM",,"System.Diagnostics.ProcessThreadCollection","00:00:42.6350733","00:00:18.0337156","140414976","140414976","False",,,,"22474752","22474752",, 
"Process","acnamagent","395","98971648","14561280","6586368","28296",,,,,,,,"8",,,,,"395","2012",".","0","",,,,,"28296","28296","6586368","6586368","125784","125784","6647808","6647808","14594048","14594048","101597184","101597184",,,"6586368","6586368",,"acnamagent",,"True","0","System.Diagnostics.ProcessStartInfo",,,"System.Diagnostics.ProcessThreadCollection",,,"98971648","98971648","False",,,,"14561280","14561280",, 

two.csv =

#TYPE System.Object[] 
"Count","Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized" 
"5","5","5","1","System.Object[]","False","True","False" 

Для контекста, я пытаюсь восклицательный знак мои параметры для Export-CSV, но я столкнулся с этим, когда передаю -InputObject, и я не могу передать вход, а затем проложить остальные параметры.

Спасибо.

ответ

3

Это ожидаемое поведение.

Когда вы проходите через конвейер, массивы, коллекции, перечислимые вещи и т. Д. Обрабатываются по элементам. Обычно это то, что вы хотите.

Когда вы используете -InputObject, он принимает массив как отдельный объект.

Лучший способ увидеть это состоит в использовании Get-Member:

$a = Get-Process | select -first 5 
$a | Get-Member 
Get-Member -InputObject $a 

В первом вызове, вы увидите тип данных и членов каждого элемента. Во втором вызове вы увидите тип и элементы объекта коллекции.

В зависимости от командлета вы можете не заметить разницу вообще, поскольку она обрабатывает оба случая (см. Функцию конвейера в конце моего ответа).

Но в случае Export-Csv или ConvertTo-Json или других командлетов типа сериализации вы хотите эту разницу; в противном случае очень сложно сериализовать массив явно, когда захотите.

Другим способом продемонстрировать это:

$sb = { 
    $_ 
    Write-Verbose $_.Count -Verbose 
} 

$a | ForEach-Object -Process $sb 
ForEach-Object -Process $sb -InputObject $a 

При написании собственных функций трубопровода, общий способ обойти различные способы получения объекта является использование Process {} блока вместе с foreach:

function Test-Pipeline { 
[CmdletBinding()] 
param(
    [Parameter(ValueFromPipeline)] 
    $MyVal 
) 

    Process { 
     Write-Verbose $MyVal.Count -Verbose 
     foreach($v in $MyVal) { 
      $v 
     } 
    } 
} 

$a | Test-Pipeline 
# Process block gets called once for each element 

Test-Pipeline -MyVal $a 
# Process block gets called once total, with the variable being an array 

Это хорошо работает, потому что foreach не сбой, если вы даете ему один объект без массива, он просто выполняется один раз.

+0

Извините, у вас возникли проблемы с разметкой комментариев. :-( –

+0

Это замечательно. Не уверен, что это меняет мой подход к проблеме * real *, но просто для проверки моего понимания: 'a = Get-Process | select -first 5; $ a | Export-CSV -Path '. \ one.csv'; $ a |% -Begin {clc '. \ three.csv '} -Process {Export-CSV -InputObject $ _ -Path'. \ three.csv '-Append} ' ... и затем one.csv = three.csv. Да? (Протестировано, и это так, но хочу убедиться, что у меня есть концепция, выходящая за пределы этого примера.) –

+0

Достаточно хорошо ... :-( –

Смежные вопросы