echo "testline1" > test.txt
echo "testline2" >> test.txt
$textContent = Get-Content .\test.txt
$json=ConvertTo-Json -InputObject $textContent -Depth 10
ConvertTo-Json should not hang and it should display proper error or exception
ConvertTo-Json cmdlet hangs
> $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
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-Contentshould 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.
Most helpful comment
@ikanni as a workaround you can do something like this:
I suggest opening a separate issue or locating an existing open issue and voting/commenting on it.