Json.psm1
[Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidAssignmentToAutomaticVariable', 'IsWindows', Justification = 'IsWindows doesnt exist in PS5.1' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseDeclaredVarsMoreThanAssignments', 'IsWindows', Justification = 'IsWindows doesnt exist in PS5.1' )] [CmdletBinding()] param() $baseName = [System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath) $script:PSModuleInfo = Import-PowerShellDataFile -Path "$PSScriptRoot\$baseName.psd1" $script:PSModuleInfo | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ } $scriptName = $script:PSModuleInfo.Name Write-Debug "[$scriptName] - Importing module" if ($PSEdition -eq 'Desktop') { $IsWindows = $true } #region [functions] - [public] Write-Debug "[$scriptName] - [functions] - [public] - Processing folder" #region [functions] - [public] - [Format-Json] Write-Debug "[$scriptName] - [functions] - [public] - [Format-Json] - Importing" function Format-Json { <# .SYNOPSIS Formats a JSON string or PowerShell object. .DESCRIPTION Converts raw JSON strings or PowerShell objects into formatted JSON. Supports pretty-printing with configurable indentation or compact output. .EXAMPLE Format-Json -JsonString '{"a":1,"b":{"c":2}}' -IndentationType Spaces -IndentationSize 2 .EXAMPLE $obj = @{ user = 'Marius'; roles = @('admin','dev') } Format-Json -InputObject $obj -IndentationType Tabs -IndentationSize 1 .EXAMPLE Format-Json -JsonString '{"a":1,"b":{"c":2}}' -Compact .LINK https://psmodule.io/Json/Functions/Format-Json/ #> [CmdletBinding(DefaultParameterSetName = 'FromString')] param ( # JSON string to format. [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'FromString')] [string]$JsonString, # PowerShell object to convert and format as JSON. [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'FromObject')] [PSObject]$InputObject, # Produce compact (minified) output. [Parameter(ParameterSetName = 'FromString')] [Parameter(ParameterSetName = 'FromObject')] [switch]$Compact, # Indentation type: 'Spaces' or 'Tabs'. [Parameter(ParameterSetName = 'FromString')] [Parameter(ParameterSetName = 'FromObject')] [ValidateSet('Spaces', 'Tabs')] [string]$IndentationType = 'Spaces', # Number of spaces or tabs per indentation level. Only used if not compacting. [Parameter(ParameterSetName = 'FromString')] [Parameter(ParameterSetName = 'FromObject')] [UInt16]$IndentationSize = 4 ) process { try { $inputObject = if ($PSCmdlet.ParameterSetName -eq 'FromString') { $JsonString | ConvertFrom-Json -ErrorAction Stop } else { $InputObject } $json = $inputObject | ConvertTo-Json -Depth 100 -Compress:$Compact if ($Compact) { return $json } $indentUnit = switch ($IndentationType) { 'Tabs' { "`t" } 'Spaces' { ' ' * $IndentationSize } } $lines = $json -split "`n" $level = 0 $result = foreach ($line in $lines) { $trimmed = $line.Trim() if ($trimmed -match '^[}\]]') { $level = [Math]::Max(0, $level - 1) } $indent = $indentUnit * $level $indentedLine = "$indent$trimmed" # Check if the line ends with an opening bracket ('[' or '{') and is not a closing bracket ('}' or ']') or a comma. # This ensures that the indentation level is increased only for lines that introduce a new block. if ($trimmed -match '[{\[]$' -and $trimmed -notmatch '^[}\]],?$') { $level++ } $indentedLine } return ($result -join "`n") } catch { Write-Error "Failed to format JSON: $_" } } } Write-Debug "[$scriptName] - [functions] - [public] - [Format-Json] - Done" #endregion [functions] - [public] - [Format-Json] #region [functions] - [public] - [Import-Json] Write-Debug "[$scriptName] - [functions] - [public] - [Import-Json] - Importing" function Import-Json { <# .SYNOPSIS Imports JSON data from a file. .DESCRIPTION Reads JSON content from one or more files and converts it to PowerShell objects. Supports pipeline input for processing multiple files. .EXAMPLE Import-Json -Path 'config.json' Imports JSON data from config.json file. .EXAMPLE Import-Json -Path 'data/*.json' Imports JSON data from all .json files in the data directory. .EXAMPLE 'settings.json', 'users.json' | Import-Json Imports JSON data from multiple files via pipeline. .EXAMPLE Import-Json -Path 'complex.json' -Depth 50 Imports JSON data with a custom maximum depth of 50 levels. .LINK https://psmodule.io/Json/Functions/Import-Json/ #> [CmdletBinding()] param ( # The path to the JSON file to import. Supports wildcards and multiple paths. Can be provided via pipeline. [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('FullName')] [string[]]$Path, # The maximum depth to expand nested objects. Uses ConvertFrom-Json default if not specified. [Parameter()] [int]$Depth ) process { foreach ($filePath in $Path) { try { # Resolve wildcards and relative paths $resolvedPaths = Resolve-Path -Path $filePath -ErrorAction Stop foreach ($resolvedPath in $resolvedPaths) { Write-Verbose "Processing file: $($resolvedPath.Path)" # Test if the file exists and is a file (not directory) if (-not (Test-Path -Path $resolvedPath.Path -PathType Leaf)) { Write-Error "File not found or is not a file: $($resolvedPath.Path)" continue } # Read file content $jsonContent = Get-Content -Path $resolvedPath.Path -Raw -ErrorAction Stop # Check if file is empty if ([string]::IsNullOrWhiteSpace($jsonContent)) { Write-Warning "File is empty or contains only whitespace: $($resolvedPath.Path)" continue } # Convert JSON to PowerShell object if ($PSBoundParameters.ContainsKey('Depth')) { $jsonObject = $jsonContent | ConvertFrom-Json -Depth $Depth -ErrorAction Stop } else { $jsonObject = $jsonContent | ConvertFrom-Json -ErrorAction Stop } # Add file path information as a note property for reference if ($jsonObject -is [PSCustomObject]) { Add-Member -InputObject $jsonObject -MemberType NoteProperty -Name '_SourceFile' -Value $resolvedPath.Path -Force } # Output the object $jsonObject } } catch [System.Management.Automation.ItemNotFoundException] { Write-Error "Path not found: $filePath" } catch [System.ArgumentException] { Write-Error "Invalid JSON format in file: $filePath. $_" } catch { Write-Error "Failed to import JSON from file '$filePath': $_" } } } } Write-Debug "[$scriptName] - [functions] - [public] - [Import-Json] - Done" #endregion [functions] - [public] - [Import-Json] Write-Debug "[$scriptName] - [functions] - [public] - Done" #endregion [functions] - [public] #region Member exporter $exports = @{ Alias = '*' Cmdlet = '' Function = @( 'Format-Json' 'Import-Json' ) Variable = '' } Export-ModuleMember @exports #endregion Member exporter |