JSON is something that’s being used a lot. It’s easy to store and retrieve data. In this small blog post, I will show you how to do that 🙂
What is JSON?
JSON (JavaScript Object Notation) is an open standard file format and data interchange format that uses human-readable text to store and transmit data objects consisting of attribute-value pairs and arrays (or other serializable values). It is a common data format with diverse uses in electronic data interchange, including web applications with servers. (Source: Wikipedia)
How do you pronounce it?
Saw a video about that a while back, ‘How To Pronounce JSON by Douglas Crockford’ (The inventor of JSON), which you can find here. Two quotes from that video:
‘Almost everybody was saying “Jay-Sawn”, which is fine.‘
and
‘I think the correct pronunciation is probably “shason” ‘
Reading JSON files in PowerShell
You can read JSON files by using something like this:
$JSON=Get-Content .\install_apps.json | ConvertFrom-Json
In this example, I retrieved the contents of the install_apps.json file. When opened in Notepad, that looks like this:
{ "Apps": [ "Microsoft.SQLServerManagementStudio", "7zip.7zip", "Adobe.Acrobat.Reader.64-bit", "AnyConnect", "BraveSoftware.BraveBrowser", "Canonical.Ubuntu", "Cisco.CiscoWebexMeetings", "Citrix.Workspace", "Famatech.AdvancedIPScanner", "Fortinet.FortiClientVPN", "Git.Git", "GitHub.GitHubDesktop", "Google.Chrome", "Graphviz.Graphviz", "Insecure.Nmap", "JAMSoftware.TreeSize.Free", "Microsoft.AzureCLI", "Microsoft.AzureStorageExplorer", "Microsoft.DeploymentToolkit", "Microsoft.dotnetRuntime.3.1", "Microsoft.dotnetRuntime.5", "Microsoft.EdgeWebView2Runtime", "Microsoft.PowerBI", "Microsoft.Powershell", "Microsoft.PowerToys", "Microsoft.RemoteDesktopClient", "Microsoft.VisualStudioCode", "Microsoft.WindowsAdminCenter", "Microsoft.WindowsADK", "Microsoft.WindowsTerminal", "Mozilla.FireFox", "Notepad++.Notepad++", "Obsidian.Obsidian", "Ookla.Speedtest", "OpenVPNTechnologies.OpenVPNConnect", "Oracle.JavaRuntimeEnvironment", "PuTTY.PuTTY", "Python.Python.3", "Rufus.Rufus", "Teamviewer.Teamviewer", "Telerik.Fiddler", "WinSCP.WinSCP", "WiresharkFoundation.Wireshark", "Zoom.Zoom" ], "Features": [ "Containers-DisposableClientVM", "Microsoft-Windows-Subsystem-Linux", "TelnetClient", "TFTP" ......
When imported in the $JSON variable, it looks like this:
Apps : {Microsoft.SQLServerManagementStudio, 7zip.7zip, Adobe.Acrobat.Reader.64-bit, AnyConnect…} Features : {Containers-DisposableClientVM, Microsoft-Windows-Subsystem-Linux, TelnetClient, TFTP} FilesToClean : {*.lnk, desktop.ini} MicrosftVCRuntime : {Microsoft.VC++2008Redist-x86, Microsoft.VC++2008Redist-x64, Microsoft.VC++2010Redist-x64, Microsoft.VC++2010Redist-x86…} ProcessesToKill : {advanced_ip_scanner, OpenVPNConnect, PowerToys.Settings, PtSrv…} PowerShellCommands : {Update-Help -Confirm:$False -Force:$True -ErrorAction:SilentlyContinue} PowerShellModules : {AIPService, Az, Azure.AnalysisServices, Azure.Storage…} PowerShellProfile : {Import-Module Posh-Git, Set-PSReadlineKeyHandler -Key Tab -Function Complete, Set-PSReadLineOption -PredictionSource History, [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12} RSATTools : {Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0, Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0, Rsat.CertificateServices.Tools~~~~0.0.1.0, Rsat.DHCP.Tools~~~~0.0.1.0…}
It has multiple attributes (Apps, Features, FilesToClean, etc. ) and $JSON.Apps will look like this:
Microsoft.SQLServerManagementStudio 7zip.7zip Adobe.Acrobat.Reader.64-bit AnyConnect BraveSoftware.BraveBrowser Canonical.Ubuntu Cisco.CiscoWebexMeetings Citrix.Workspace Famatech.AdvancedIPScanner Fortinet.FortiClientVPN Git.Git GitHub.GitHubDesktop Google.Chrome Graphviz.Graphviz Insecure.Nmap JAMSoftware.TreeSize.Free Microsoft.AzureCLI Microsoft.AzureStorageExplorer Microsoft.DeploymentToolkit Microsoft.dotnetRuntime.3.1 Microsoft.dotnetRuntime.5 Microsoft.EdgeWebView2Runtime Microsoft.PowerBI Microsoft.Powershell Microsoft.PowerToys Microsoft.RemoteDesktopClient Microsoft.VisualStudioCode Microsoft.WindowsAdminCenter Microsoft.WindowsADK Microsoft.WindowsTerminal Mozilla.FireFox Notepad++.Notepad++ Obsidian.Obsidian Ookla.Speedtest OpenVPNTechnologies.OpenVPNConnect Oracle.JavaRuntimeEnvironment PuTTY.PuTTY Python.Python.3 Rufus.Rufus Teamviewer.Teamviewer Telerik.Fiddler WinSCP.WinSCP WiresharkFoundation.Wireshark Zoom.Zoom
But this was just a simple attribute and value JSON file, in the example below I read the contents of an Intune backup for an Endpoint Manager Win32 App. This looks like this:
@odata.context : https://graph.microsoft.com/beta/$metadata#deviceAppManagement/mobileApps/$entity @odata.type : #microsoft.graph.win32LobApp id : 3f0f40a3-4600-4647-b04f-9457ee036b41 displayName : VMware Tools description : VMware Tools publisher : VMware largeIcon : createdDateTime : 15-1-2022 16:07:18 lastModifiedDateTime : 31-3-2022 15:52:20 isFeatured : False privacyInformationUrl : informationUrl : owner : developer : notes : uploadState : 1 publishingState : published isAssigned : False roleScopeTagIds : {0} dependentAppCount : 0 supersedingAppCount : 0 supersededAppCount : 0 committedContentVersion : 1 fileName : install.intunewin size : 129835696 installCommandLine : install.cmd uninstallCommandLine : uninstall.cmd applicableArchitectures : x86,x64 minimumFreeDiskSpaceInMB : minimumMemoryInMB : minimumNumberOfProcessors : minimumCpuSpeedInMHz : msiInformation : setupFilePath : install.cmd minimumSupportedWindowsRelease : 1607 displayVersion : minimumSupportedOperatingSystem : @{v8_0=False; v8_1=False; v10_0=False; v10_1607=True; v10_1703=False; v10_1709=False; v10_1803=False; v10_1809=False; v10_1903=False; v10_1909=False; v10_2004=False; v10_2H20=False; v10_21H1=False} detectionRules : {@{@odata.type=#microsoft.graph.win32LobAppFileSystemDetection; path=C:\Program Files\VMware\VMware tools; fileOrFolderName=vmtoolsd.exe; check32BitOn64System=False; detectionType=exists; operator=notConfigured; detectionValue=}} requirementRules : {} rules : {@{@odata.type=#microsoft.graph.win32LobAppFileSystemRule; ruleType=detection; path=C:\Program Files\VMware\VMware tools; fileOrFolderName=vmtoolsd.exe; check32BitOn64System=False; operationType=exists; operator=notConfigured; comparisonValue=}} installExperience : @{runAsAccount=system; deviceRestartBehavior=suppress} returnCodes : {@{returnCode=0; type=success}, @{returnCode=1707; type=success}, @{returnCode=3010; type=softReboot}, @{returnCode=1641; type=hardReboot}…}
The Rules attribute has more data in it:
@odata.type : #microsoft.graph.win32LobAppFileSystemRule ruleType : detection path : C:\Program Files\VMware\VMware tools fileOrFolderName : vmtoolsd.exe check32BitOn64System : False operationType : exists operator : notConfigured comparisonValue :
You can use access that data in scripts like this:
$JSON.rules.path
Which returns ‘C:\Program Files\VMware\VMware tools’
More advanced information about the ConvertFrom-Json cmdlet can be found here
Writing JSON files in PowerShell
You can also output information to a JSON file using the ConvertTo-Json cmdlet. In the example below, I output the data from the Get-Childitem cmdlet to a JSON file (d:\temp\files.json) using ConvertTo-Json and Out-File:
Get-ChildItem | ConvertTo-Json | Out-File d:\temp\files.json
This outputs all files in the current directory to a JSON file:
[ { "Parent": { "Parent": "D:\\Temp\\IntuneBackup", "Root": "D:\\", "FullName": "D:\\Temp\\IntuneBackup\\Client Apps", "Extension": "", "Name": "Client Apps", "Exists": true, "CreationTime": "2022-03-31T11:03:14.2325468+02:00", "CreationTimeUtc": "2022-03-31T09:03:14.2325468Z", "LastAccessTime": "2022-08-09T14:14:31.1320904+02:00", "LastAccessTimeUtc": "2022-08-09T12:14:31.1320904Z", "LastWriteTime": "2022-03-31T13:25:02.6287275+02:00", "LastWriteTimeUtc": "2022-03-31T11:25:02.6287275Z", "LinkTarget": null, "Attributes": 16 }, "Root": { "Parent": null, "Root": "D:\\", "FullName": "D:\\", "Extension": "", "Name": "D:\\", "Exists": true, "CreationTime": "2022-01-28T20:12:25.3310114+01:00", "CreationTimeUtc": "2022-01-28T19:12:25.3310114Z", "LastAccessTime": "2022-08-09T14:14:31.1302723+02:00", "LastAccessTimeUtc": "2022-08-09T12:14:31.1302723Z", "LastWriteTime": "2022-07-12T22:29:31.1157868+02:00", "LastWriteTimeUtc": "2022-07-12T20:29:31.1157868Z", "LinkTarget": null, "Attributes": 22 }, "FullName": "D:\\Temp\\IntuneBackup\\Client Apps\\Assignments", "Extension": "", "Name": "Assignments", ....................
But… When running the command above, it shows a warning:
WARNING: Resulting JSON is truncated as serialization has exceeded the set depth of 2.
The output above shows that the depth value is not high enough to display everything. You can change that, but it has a maximum of 100. Rerunning the same command with a setting of 100 will still show you an error because the output still exceeds that maximum of 100 and will not show you more detail.
This is something you will have to consider: limit the things you want to store in the JSON file before writing to a file.
More advanced information about the ConvertTo-Json cmdlet can be found here.