【问题标题】:powershell piped input to export-csv different from -inputobject与-inputobject不同的powershell管道输入到export-csv
【发布时间】:2016-12-10 21:21:37
【问题描述】:

在 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 的内容不同?

(如果只有我……)

一个.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",,

两个.csv =

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

对于上下文,我试图将我的参数发送到 Export-CSV,但是当我传递 -InputObject 时遇到了这个问题,我无法通过管道输入然后发送其余参数。

谢谢。

【问题讨论】:

    标签: csv powershell


    【解决方案1】:

    这是预期的行为。

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

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

    查看这个的最好方法是使用Get-Member

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

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

    根据 cmdlet,您可能根本不会注意到差异,因为它同时处理这两种情况(请参阅我的回答末尾的管道函数)。

    但是对于Export-Csv,或者ConvertTo-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 不会失败,如果你给它一个非数组对象,它只会执行一次。

    【讨论】:

    • 抱歉,无法确定 cmets 的标记。 :-(
    • 太好了。不确定这是否会改变我对 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。是的? (经过测试,确实如此,但要确保我的概念超出了这个示例。)
    • 足够好... :-(
    • @EdChandler 顺便说一下,您可能想将edit real 问题纳入您的问题。也许有人会对此有答案?
    猜你喜欢
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 2018-11-28
    • 2017-10-19
    • 2022-01-09
    相关资源
    最近更新 更多