Powershell: Serious Serialization |
by Jeff Hicks Copyright : JDH Information Technology Solutions, Inc. – all rights reserved
Today’s topic also comes from something that came across my social media stream. The question was ostensibly about one thing, but it was really about something else. The question was if there was a problem with Get-Process because when running this command, it seemed as if Get-Process was hung.Get-Process | Export-Csv -path d:\temp\process.csv You can try this yourself, but be prepared to wait. On my desktop this command completed, but it took over minutes in PowerShell 7. The issue isn’t Get-Process it is serialization.Serialization is the process of converting an object into a format that can be stored or transmitted and then reconstructed later. Typically this means writing an object to disk. In PowerShell, you can use the Export-Csv cmdlet, which converts objects into a CSV format. The problem with Get-Process is that it returns a large number of objects, and when you try to serialize them all at once, it can take a long time.Export-CsvThe other issue, is the format itself. CSV is a text format, and is designed for flat data. This is a great format for objects with simple properties such as strings and numbers. However, objects in PowerShell can be rich and have nested object properties. These do not serialize well to CSV.Here’s a simple example.Get-Service Bits | ConvertTo-CSV The ConvertTo-CSV cmdlet will serialize the object to a CSV format and write it to the pipeline. Unlike Export-Csv , which writes to a file. Look at the output.![]() PS C:\> Get-Service Bits | Select Name,Status,DisplayName,StartupType,DelayedAutoStart,UserName,Description,BinaryPathName,@{Name="ComputerName";Expression={$env:COMPUTERNAME}} | ConvertTo-CSV "Name","Status","DisplayName","StartupType","DelayedAutoStart","UserName","Description","BinaryPathName","ComputerName" "Bits","Stopped","Background Intelligent Transfer Service","Manual","True","LocalSystem","Transfers files in the background using idle network bandwidth. If the service is disabled, then any applications that depend on BITS, such as Windows Update or MSN Explorer, will be unable to automatically download programs and other information.","C:\WINDOWS\System32\svchost.exe -k netsvcs -p","PROSPERO" I also encourage you to consider your plans for the serialized data. What are you going to do with it? Are you going to import it into a database or an Excel file? Do you intend to re-import the data into a future PowerShell sessions? One of the benefits of serialization is that you can recreate objects from a PowerShell session on one computer to another. However, keep in mind that serialization only records the properties of the object. It does not record the methods or events. And when selecting properties to serialize, the reconstituted object will be a PSCustomObject .![]() Get-Item $profile | Export-CSV -IncludeTypeInformation -Path d:\temp\profile.csv The first line of the CSV file will contain the type information.#TYPE System.IO.FileInfo This is useful if you plan to re-import the data into a PowerShell session. The Import-Csv cmdlet will use this information to recreate the object.> In Windows PowerShell, type information is included by default unless you specify -NoTypeInformation . In PowerShell 7 it is the opposite. Type information is not included by default. You must specify -IncludeTypeInformation to include it.When you import the CSV file, the Import-Csv cmdlet will recreate the object and restore the object type.PS C:\> Import-Csv D:\temp\profile.csv | Get-Member TypeName: System.IO.FileInfo Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() Attributes NoteProperty string Attributes=Archive, ReparsePoint BaseName NoteProperty string BaseName=Microsoft.PowerShell_profile CreationTime NoteProperty string CreationTime=10/5/2020 3:50:19 PM CreationTimeUtc NoteProperty string CreationTimeUtc=10/5/2020 7:50:19 PM Directory NoteProperty string Directory=C:\Users\Jeff\Documents\PowerShell DirectoryName NoteProperty string DirectoryName=C:\Users\Jeff\Documents\PowerShell Exists NoteProperty string Exists=True Extension NoteProperty string Extension=.ps1 ... But there is a major caveat. Notice that all properties are recreated as strings. This will become an issue if you are importing many objects and want to sort or filter based on a DateTime or Boolean property. The properties will be strings so you may not get the results you expect.Let me re-iterate, there is nothing wrong with using the CSV format for serialization. As long as you keep the requirements and limitations in mind. Not to mention what you intend to do with the data.Be sure to read the help and examples for the CSV-related commands because there may be other features you want to take advantage ofCopyright : JDH Information Technology Solutions, Inc. – all rights reserved |
Deja una respuesta