with powershell I can get, with just one line (prerequisite) and using foreach, the date of last update of the folders and the difference in days, however, I need to get this information in a format for use via json and I can't display the value of $pasta with the value of $DiasV why when converting with "| convertto-Json" the result is not in the correct format (I'm validating via https://jsonformatter.org/json-parser).
foreach ($pasta in Get-ChildItem -Path C:\TEMP\ -Directory)
{
$ErrorActionPreference = 'SilentlyContinue';
$path = 'C:\TEMP\' $pasta '\EXAMPLE';
$start = Get-ChildItem -Path $path -File | Sort-Object -Property CreationTime | Select-Object -ExpandProperty LastWriteTime -Last 1;
$end = Get-Date; $DiasV = (New-TimeSpan -Start $start -End $end);
write $pasta.Name $pasta.LastWriteTime $DiasV.Days | ConvertTo-Json
}
Output:
[
"A123_1A_CAB",
{
"value": "\/Date(1649508388226)\/",
"DateTime": "sábado, 9 de abril de 2022 09:46:28"
},
0
]
[
"C166_5AND_BBB",
{
"value": "\/Date(1649610666329)\/",
"DateTime": "domingo, 10 de abril de 2022 14:11:06"
},
2
]
My intention is to get this output:
[
{
"pasta": "A123_1A_CAB"
"value": "\/Date(1649508388226)\/",
"DateTime": "sábado, 9 de abril de 2022 09:46:28"
"Dias": "0"
},
{
"pasta": "C166_5AND_BBB"
"value": "\/Date(1649610666329)\/",
"DateTime": "domingo, 10 de abril de 2022 14:11:06"
"Dias": "2"
}
]
I need help to solve this, already tried several ways without success.I'm still learning english.
CodePudding user response:
Your primary problem is that you want the output to be converted to a single JSON array:
By placing your
ConvertTo-Json
call inside yourforeach
loop, you're creating a separate JSON document in each iteration, which when combined as-is result in malformed JSON.Simply apply
ConvertTo-Json
to all your output objects, across all loop iterations instead; this is more easily accomplished if you switch to a single pipeline that uses theForEach-Object
cmdlet.Additionally, you need to encapsulate the pieces of information to report for each directory in an object whose properties contain the information:
To put it all together, with some optimizations:
Get-ChildItem -Path C:\TEMP\ -Directory |
ForEach-Object {
$ErrorActionPreference = 'SilentlyContinue';
$path = $_.FullName '\EXAMPLE';
$start = Get-ChildItem -LiteralPath $path -File |
Sort-Object -Property CreationTime |
Select-Object -ExpandProperty LastWriteTime -Last 1;
$end = Get-Date; $DiasV = ($end - $start).Days;
# Create a helper object for the "value" and "DateTime" properties.
$dateTimeCustom = $_.LastWriteTime | ConvertTo-Json | ConvertFrom-Json
# Output the pieces of information encapsulated in an object.
[pscustomobject] @{
pasta = $_.Name;
value = $dateTimeCustom.value;
DateTime = $dateTimeCustom.DateTime;
Dias = $DiasV
}
} | ConvertTo-Json
Note:
The only reason I've kept the
;
at the end of the statements is to facilitate transforming the code into a single line. As written, the;
are not necessary.Your output implies that you're using Windows PowerShell, where
ConvertTo-Json
serializes[datetime]
values as objects with two or three properties,.value
(a custom string representation based on the Unix epoch time representation, e.g.,"\/Date(1649508388226)\/"
),.DateTime
, a friendly display string, and - if the[datetime]
instance was obtained viaGet-Date
- additionally a.DisplayHint
property.To "flatten" these properties and make them direct properties of the output objects, a round-trip JSON conversion is used to create a helper object with those property values (
$dateTimeCustom = $_.LastWriteTime | ConvertTo-Json | ConvertFrom-Json
).Strictly speaking, that
ConvertTo-Json
in Windows PowerShell produces an object with properties for a[datetime]
instance - instead of just a single string such as"\/Date(1649508388226)\/"
- should be considered a bug, not least because round-tripping such an object does not result in a[datetime]
instance, but in a[pscustomobject]
instance with properties.value
and.DateTime
and situationally also.DisplayHint
(which we take advantage of here).The problem occurs, because
[datetime]
instances are decorated with a type-level ETSScriptProperty
member,.DateTime
, which, unfortunately, is included in the serialization, resulting in the two-property object representation at hand. If you were to remove the type data associated with[datetime]
, the problem would go away (but so would the property), e.g.:# Windows PowerShell only. # Note that if you were to use Get-Date output, *another*, # instance-level ETS property would come into play, .DisplayHint PS> Remove-TypeData System.DateTime; [datetime]::now | ConvertTo-Json "\/Date(1649702531387)\/" # e.g. - single string
Note that PowerShell (Core) 7 no longer uses this custom-object representation and instead serializes
[datetime]
instances as strings in ISO 8601 date-time format (e.g.,"2021-10-11T13:27:12.3318432-04:00"
)