【问题标题】:Under what circumstances would one need the information emitted when -NoTypeInformation is *not* passed to ConvertTo-Csv or Export-Csv?在什么情况下需要在 -NoTypeInformation *不 * 传递给 ConvertTo-Csv 或 Export-Csv 时发出的信息?
【发布时间】:2019-01-15 03:01:58
【问题描述】:

今天我突然想到,在这么多年习惯性地将-NoTypeInformation 传递给Export-Csv/ConvertTo-Csv 以防止发出不受欢迎的评论行之后,也许Import-Csv/ConvertFrom-Csv 能够如果我没有抑制该类型信息,则使用它们的原始属性类型(而不是所有它们都是 String)重建对象。我试了一下...

PS> Get-Service | ConvertTo-Csv

...而且,很长一段时间没有真正看到省略-NoTypeInformation 会发出什么,提醒它只包括输入对象的类型(实际上只是第一个对象),而不是类型成员...

#TYPE System.ServiceProcess.ServiceController
"Name","RequiredServices","CanPauseAndContinue","CanShutdown","CanStop","DisplayName","DependentServices","MachineName","ServiceName","ServicesDependedOn","ServiceHandle","Status","ServiceType","StartType","Site","Container"
...

比较类型信息序列化的结果,然后反序列化...

PS> Get-Service | ConvertTo-Csv | ConvertFrom-Csv | Get-Member


   TypeName: CSV:System.ServiceProcess.ServiceController

Name                MemberType   Definition
----                ----------   ----------
Equals              Method       bool Equals(System.Object obj)
GetHashCode         Method       int GetHashCode()
GetType             Method       type GetType()
ToString            Method       string ToString()
CanPauseAndContinue NoteProperty string CanPauseAndContinue=False
CanShutdown         NoteProperty string CanShutdown=False
CanStop             NoteProperty string CanStop=True
Container           NoteProperty object Container=null
DependentServices   NoteProperty string DependentServices=System.ServiceProcess.ServiceController[]
DisplayName         NoteProperty string DisplayName=Adobe Acrobat Update Service
MachineName         NoteProperty string MachineName=.
Name                NoteProperty string Name=AdobeARMservice
RequiredServices    NoteProperty string RequiredServices=System.ServiceProcess.ServiceController[]
ServiceHandle       NoteProperty string ServiceHandle=
ServiceName         NoteProperty string ServiceName=AdobeARMservice
ServicesDependedOn  NoteProperty string ServicesDependedOn=System.ServiceProcess.ServiceController[]
ServiceType         NoteProperty string ServiceType=Win32OwnProcess
Site                NoteProperty string Site=
StartType           NoteProperty string StartType=Automatic
Status              NoteProperty string Status=Running

...到序列化没有类型信息然后反序列化的结果...

PS> Get-Service | ConvertTo-Csv -NoTypeInformation | ConvertFrom-Csv | Get-Member


   TypeName: System.Management.Automation.PSCustomObject

Name                MemberType   Definition
----                ----------   ----------
Equals              Method       bool Equals(System.Object obj)
GetHashCode         Method       int GetHashCode()
GetType             Method       type GetType()
ToString            Method       string ToString()
CanPauseAndContinue NoteProperty string CanPauseAndContinue=False
CanShutdown         NoteProperty string CanShutdown=False
CanStop             NoteProperty string CanStop=True
Container           NoteProperty object Container=null
DependentServices   NoteProperty string DependentServices=System.ServiceProcess.ServiceController[]
DisplayName         NoteProperty string DisplayName=Adobe Acrobat Update Service
MachineName         NoteProperty string MachineName=.
Name                NoteProperty string Name=AdobeARMservice
RequiredServices    NoteProperty string RequiredServices=System.ServiceProcess.ServiceController[]
ServiceHandle       NoteProperty string ServiceHandle=
ServiceName         NoteProperty string ServiceName=AdobeARMservice
ServicesDependedOn  NoteProperty string ServicesDependedOn=System.ServiceProcess.ServiceController[]
ServiceType         NoteProperty string ServiceType=Win32OwnProcess
Site                NoteProperty string Site=
StartType           NoteProperty string StartType=Automatic
Status              NoteProperty string Status=Running

...唯一的区别是TypeNameCSV:System.ServiceProcess.ServiceController(由#TYPE 注释指定的相同类型以CSV: 为前缀)更改为System.Management.Automation.PSCustomObject。所有成员都是相同的,所有属性都是 String 类型,并且在这两种情况下,您都反序列化了不包含原始对象的方法并且不以任何方式连接或代理原始对象的对象。

显然,Microsoft 认为不仅需要在 CSV 输出中包含这种类型的信息,而且应该默认这样做。由于我不能真正问“他们为什么这样做?”,我想知道这些信息如何可能有用?除了设置每个对象的TypeName 之外,*-Csv 序列化 cmdlet 是否将它用于其他任何用途?为什么我会希望这种类型的信息在 CSV 输出中“带内”传达,而不是仅仅...知道这个包含服务信息的文件来自 System.ServiceProcess.ServiceController 实例,甚至不是关心原始类型是什么,只要它具有我期望的属性?

我能想到的仅有的两个用例是,如果您收到由未知 PowerShell 脚本创建的 CSV 文件,那么拥有类型信息可以帮助确定用于生成数据的应用程序/库/模块,或者如果您有一个可笑的通用脚本,它试图根据类型信息刷新任意输入,就像这样......

Import-Csv ... `
    | ForEach-Object -Process {
        # Original type name of the first record, not necessarily this record!
        $firstTypeName = $_.PSObject.TypeNames[0];

        if ($firstTypeName -eq 'CSV:System.ServiceProcess.ServiceController')
        {
            Get-Service ...
        }
        elseif ('CSV:System.IO.DirectoryInfo', 'CSV:System.IO.FileInfo' -contains $firstTypeName)
        {
            Get-ChildItem ...
        }
        elseif ($firstTypeName -eq 'CSV:Microsoft.ActiveDirectory.Management.ADObject')
        {
            Get-ADObject ...
        }
        ...
    }

...但是这些都不是非常有说服力的例子,尤其是考虑到,正如我所指出的,这种类型的信息被认为非常重要,以至于默认包含在内。还有其他我没有想到的用例吗?或者这仅仅是“包含它而不需要它比需要它而不包含它更好(而且便宜)”的情况?

相关: PowerShell GitHub issue 讨论了将 -NoTypeInformation 设为未来版本(根据 cmdlet 文档为 6.0)的默认值,以及一个明显的共识,即没有意义永远忽略-NoTypeInformation

【问题讨论】:

  • 是的...... 10 年前的奇怪设计决定。我怀疑在 6.1 中,默认情况下该开关将关闭(考虑到它在当前环境中始终处于启用状态,并且您只会在他们忘记时诅咒导出 csvs 的系统管理员)

标签: powershell csv serialization typeinfo export-csv


【解决方案1】:

如果您有一个thing,它了解标头并且还知道如何构造该类型的other thing,那么可以想象,第一个thing 可以从字符串表示中创建一个或多个other things。我并不是说它很有用,但我说的是,如果 .csv 可能在另一种类型的文件可能不可用的情况下可用,那么这是一种潜在用途。出于与我在此处回答您的问题时提到的类似的原因,我可能确实这样做了,也可能没有这样做。

【讨论】:

  • 所以你的意思是,即使ConvertFrom-Csv/Import-Csv 不能或根本不将 CSV 数据重新水合为原始类型的实例,你可能有一个类/脚本/“事物”可以并使用 CSV 派生数据来初始化真实对象的属性?因此,“事物”能够构造类型和属性完全由 CSV 数据指定的对象,而不是硬编码。我可以看到;可能是一个包含 .csv 文件的目录,这些文件代表了构成应用程序数据的各种特定类型的集合?
  • 或所有相同类型的对象的集合。它有可能比 XML 或 JSON 更简洁,因为您将列...呃...属性名称仅列出一次,然后将所有值列在一个有序的行中。如果您有许多显示为逗号字符串的可选属性,则此值会下降一点,如果每行上的类型完全不同,则此值会下降。
猜你喜欢
  • 2015-02-20
  • 2014-08-03
  • 2016-01-20
  • 1970-01-01
  • 2014-12-13
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
  • 2016-12-31
相关资源
最近更新 更多