Powershell: ConvertTo-Json cmdlet hangs with -Depth 10 for object created using Get-Content

Created on 13 Mar 2018  路  7Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

echo "testline1" > test.txt
echo "testline2" >> test.txt

$textContent = Get-Content .\test.txt
$json=ConvertTo-Json -InputObject $textContent -Depth 10 

Expected behavior

ConvertTo-Json should not hang and it should display proper error or exception

Actual behavior

ConvertTo-Json cmdlet hangs

Environment data

> $PSVersionTable
Name                           Value                                                                                        
----                           -----                                                                                        
PSVersion                      5.1.16299.248                                                                                
PSEdition                      Desktop                                                                                      
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                      
BuildVersion                   10.0.16299.248                                                                               
CLRVersion                     4.0.30319.42000                                                                              
WSManStackVersion              3.0                                                                                          
PSRemotingProtocolVersion      2.3                                                                                          
SerializationVersion           1.1.0.1                                                                                      

Area-Cmdlets-Utility Issue-Bug Resolution-Fixed

Most helpful comment

@ikanni as a workaround you can do something like this:

Get-Content C:\path\to\file.txt | %{$_.PSObject.BaseObject} | ConvertTo-Json

I suggest opening a separate issue or locating an existing open issue and voting/commenting on it.

All 7 comments

Hi @ikanni - I suspect it's not actually hanging - it's just descending very deeply into the object tree which takes a very, very long time. Just take a look at the output from:
ConvertTo-Json -InputObject $textContent -Depth 3
It's converting two PSObjects wrapping strings. These objects have a lot of extra metadata added by Get-Content:

[
  {
    "value": "testline1",
    "PSPath": "C:\\Users\\brucepay.REDMOND\\AppData\\Local\\Temp\\test.txt",
    "PSParentPath": "C:\\Users\\brucepay.REDMOND\\AppData\\Local\\Temp",
    "PSChildName": "test.txt",
    "PSDrive": {
      "CurrentLocation": "Users\\brucepay.REDMOND\\AppData\\Local\\Temp",
      "Name": "C",
      "Provider": {
        "ImplementingType": "Microsoft.PowerShell.Commands.FileSystemProvider",
        "HelpFile": "System.Management.Automation.dll-Help.xml",
        "Name": "FileSystem",
        "PSSnapIn": "Microsoft.PowerShell.Core",
        "ModuleName": "Microsoft.PowerShell.Core",
        "Module": null,
        "Description": "",
        "Capabilities": 52,
        "Home": "C:\\Users\\brucepay.REDMOND",
        "Drives": "C D E",
        "VolumeSeparatedByColon": true
      },
      "Root": "C:\\",
      "Description": "Windows",
      "MaximumSize": null,
      "Credential": {
        "UserName": null,
        "Password": null
      },
      :
      :

Each additional level of depth will introduce more fields that will then need to be serialized. To get to depth 10, you'll be nesting very deeply into the object tree and it will seem to hang. If you call Get-Content with the -Raw flag, your example completes immediately:

$textContent = Get-Content .\test.txt -Raw
$json=ConvertTo-Json -InputObject $textContent -Depth 10

Using -Raw tells Get-Content to not add all of the extra metadata, reducing the amount of work that needs to be done to serialize the objects.

Agree with @BrucePay that the cmdlet is doing what it is supposed to. Perhaps Get-Content should be returning an array of strings and not objects (separate issue).

The actual bug is that ConvertTo-Json doesn't implement StopProcessing() to Ctrl+C doesn't break out.

Perhaps Get-Content should be returning an array of strings and not objects (separate issue).

Get-Content does return an array of strings, but it adds several NoteProperties to the string, including PSDrive and PSProvider that point to objects.

> $s | gm

   TypeName: System.String

Name             MemberType            Definition
----             ----------            ----------
Clone            Method                System.Object Clone(), System.Object ICloneable.Clone()
...
PSChildName      NoteProperty          string PSChildName=test.txt
PSDrive          NoteProperty          PSDriveInfo PSDrive=F
PSParentPath     NoteProperty          string PSParentPath=F:\
PSPath           NoteProperty          string PSPath=F:\test.txt
PSProvider       NoteProperty          ProviderInfo PSProvider=Microsoft.PowerShell.Core\FileSystem
ReadCount        NoteProperty          long ReadCount=1

@SteveL-MSFT Looking at the code, I don't think StopProcessing() is appropriate because the thread is not blocked. Adding checks to Stopping in the inner loops should be sufficient.

@daxian-dbw Right - it would still return PSObjects but we could stop adding the extra metadata by default. This is a conceptually significant breaking change but in practice I don't think anyone would notice (except that Get-Content performance and memory foot print would suddenly improve.)

Marked as a bug for the need to support Stopping in the cmdlet.

@daxian-dbw @BrucePay @SteveL-MSFT Get-Content adds several NoteProperties, including PSDrive and PSProvider or extra metadata by default. Whether we will fix the Get-Content in future release to remove the several NoteProperties or extra metadata ? I understand it is breaking change.

@ikanni as a workaround you can do something like this:

Get-Content C:\path\to\file.txt | %{$_.PSObject.BaseObject} | ConvertTo-Json

I suggest opening a separate issue or locating an existing open issue and voting/commenting on it.

Was this page helpful?
0 / 5 - 0 ratings