powershell管道输入到export-csv不同于-inputobject

时间:2016-08-04 16:21:03

标签: csv powershell

在Powershell(3.0)中,当将对象换行为Export-CSV时,如果将-IncludeObject参数与同一对象一起使用,则会得到不同的结果。

示例:

$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"

对于上下文,我正在尝试将我的参数splat到Export-CSV,但是当我传递-InputObject时遇到这种情况,我无法管道输入然后splat其余的参数。

感谢。

1 个答案:

答案 0 :(得分:5)

这是预期的行为。

当你通过管道输入时,数组,集合,可枚举的东西等逐项处理。这通常是你想要的。

使用-InputObject时,它会将数组作为单个对象接受。

最好的方法是使用Get-Member

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

在第一次调用中,您将看到每个元素的数据类型和成员。在第二次调用中,您将看到集合对象的类型和成员。

根据cmdlet,您可能根本没有注意到差异,因为它处理这两种情况(请参阅我的答案末尾的管道功能)。

但是对于Export-CsvConvertTo-Json或其他序列化类型cmdlet,您需要这种差异;否则,当你想要时,很难明确地序列化数组。

证明它的另一种方式:

$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如果给它一个非数组对象就不会失败,它只会执行一次。