Public/ConvertTo-TestableData.ps1
function ConvertTo-TestableData { <# .SYNOPSIS Converts JSON or YAML data to PowerShell objects and writes them to a .ps1 file for dot-sourcing. .DESCRIPTION This function takes JSON or YAML input as a string, converts it to PowerShell objects (hashtables/PSCustomObjects), and writes the converted data to a PowerShell script file that can be dot-sourced. The output file will contain two variables based on the Name parameter. .PARAMETER InputObject The raw JSON or YAML data as a string to be converted. .PARAMETER Name The base name used to define the variable in the output file. Creates variable: $Name .PARAMETER Path The file path where the .ps1 file will be written. .PARAMETER From Specifies the input format of the data. Valid values are 'json' or 'yaml'. .PARAMETER Anonymize When specified, anonymizes sensitive data in the output by replacing strings, numbers, and dates with randomized but consistent values. .PARAMETER AsHashtable Converts the input data to hashtable format in the output. .PARAMETER AsPSCustomObject Converts the input data to PSCustomObject format in the output. .PARAMETER Force Overwrites the output file if it already exists. .PARAMETER Append Appends the output to the existing file instead of overwriting it. .EXAMPLE $jsonData = '{"users": [{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]}' ConvertTo-TestableData -InputObject $jsonData -Name "TestUsers" -Path "C:\temp\TestUsers.ps1" -From json This example converts a JSON string containing an array of user objects into a PowerShell script file. The output file will contain variables $TestUsers (the original JSON string) and $TestUsersObject (the converted PowerShell object), which can be dot-sourced for testing purposes. .EXAMPLE $yamlData = @" database: host: localhost port: 5432 name: testdb "@ ConvertTo-TestableData -InputObject $yamlData -Name "DatabaseConfig" -Path "C:\temp\DatabaseConfig.ps1" -From yaml This example converts a YAML string defining database configuration into a PowerShell script file. The resulting file will have $DatabaseConfig (original YAML) and $DatabaseConfigObject (converted PowerShell hashtable), allowing for easy testing of database-related code. #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'TestableData')] [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'AnonymizedTestableData')] [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'AnonymizedHashtableTestableData')] [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'AnonymizedPSCustomObjectTestableData')] [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'HashtableTestableData')] [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'PSCustomObjectTestableData')] [string]$InputObject, [Parameter(Mandatory = $true, ParameterSetName = 'TestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedHashtableTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedPSCustomObjectTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'HashtableTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'PSCustomObjectTestableData')] [string]$Name, [Parameter(Mandatory = $true, ParameterSetName = 'TestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedHashtableTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedPSCustomObjectTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'HashtableTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'PSCustomObjectTestableData')] [string]$Path, [Parameter(Mandatory = $true, ParameterSetName = 'TestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedHashtableTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedPSCustomObjectTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'HashtableTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'PSCustomObjectTestableData')] [ValidateSet('yaml', 'json')] [string]$From, [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedHashtableTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedPSCustomObjectTestableData')] [switch]$Anonymize, [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedHashtableTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'HashtableTestableData')] [switch]$AsHashtable, [Parameter(Mandatory = $true, ParameterSetName = 'AnonymizedPSCustomObjectTestableData')] [Parameter(Mandatory = $true, ParameterSetName = 'PSCustomObjectTestableData')] [switch]$AsPSCustomObject, [Parameter(Mandatory = $false)] [switch]$Force, [Parameter(Mandatory = $false)] [switch]$Append ) begin { # Input/Output function checks if(-not (Get-Command ConvertFrom-Json -ErrorAction SilentlyContinue)) { Write-Warning "ConvertFrom-Json cmdlet is not available. Please ensure you are running PowerShell 3.0 or later." return } if(-not (Get-Command ConvertTo-Json -ErrorAction SilentlyContinue)) { Write-Warning "ConvertTo-Json cmdlet is not available. Please ensure you are running PowerShell 3.0 or later." return } if(-not (Get-Command ConvertFrom-Yaml -ErrorAction SilentlyContinue)) { Write-Warning "ConvertFrom-Yaml cmdlet is not available. YAML input will not be supported unless the powershell-yaml module is installed." return } if(-not (Get-Command ConvertTo-Yaml -ErrorAction SilentlyContinue)) { Write-Warning "ConvertTo-Yaml cmdlet is not available. YAML output will not be supported unless the powershell-yaml module is installed." return } Write-Verbose "Starting conversion process for '$Name'" Write-Verbose "Output path: $Path" $InputData = "" } process { $InputData += $InputObject + "`n" } end { $InputData = $InputData.Trim() Write-Verbose "Received input data:`n$InputData" try { if($null -eq $InputData -or [string]::IsNullOrWhiteSpace($InputData)) { Write-Warning "InputObject cannot be null or empty." return } if($null -eq $Name -or [string]::IsNullOrWhiteSpace($Name)) { Write-Warning "Name cannot be null or empty." return } if($null -eq $Path -or [string]::IsNullOrWhiteSpace($Path)) { Write-Warning "Path cannot be null or empty." return } if((Test-Path -Path $Path) -and (-not $Force) -and (-not $Append)) { Write-Warning "The file at path '$Path' already exists. Use -Force to overwrite or -Append to append." return } if($null -eq $From -or [string]::IsNullOrWhiteSpace($From)) { Write-Warning "From parameter cannot be null or empty. Specify 'json' or 'yaml'." return } # Determine if input is JSON or YAML $convertedObject = $null switch($From) { 'json' { try { $convertedObject = $InputData | ConvertFrom-Json -ErrorAction Stop } catch { Write-Warning "Failed to convert from JSON: $($_.Exception.Message)" return } } 'yaml' { try { $convertedObject = $InputData | ConvertFrom-Yaml -ErrorAction Stop } catch { Write-Warning "Failed to convert from YAML: $($_.Exception.Message)" return } } default { Write-Warning "Invalid value for -From parameter. Use 'json' or 'yaml'." return } } if($null -eq $convertedObject) { Write-Warning "Conversion resulted in null object. Please check the input data." return } # Get the original type of the converted object $originalType = $convertedObject.GetType().Name Write-Verbose "Original object type: $originalType" # Always include original string data (preserve InputData exactly as provided) $originalString = $InputData # Generate converted object syntax based on format $convertedObjectSyntax = "" $dataTypeString = "" if($AsHashtable) { $hashtableData = ConvertTo-Hashtable -InputObject $convertedObject -Anonymize:$Anonymize $convertedObjectSyntax = Out-Determinizer -InputObject $hashtableData -Anonymize:$Anonymize } elseif($AsPSCustomObject) { $pscustomData = ConvertTo-PSCustomObject -InputObject $convertedObject -Anonymize:$Anonymize $convertedObjectSyntax = Out-Determinizer -InputObject $pscustomData -Anonymize:$Anonymize } else { $convertedObjectSyntax = Out-Determinizer -InputObject $convertedObject -Anonymize:$Anonymize } $outputContent = @" # Generated by ConvertTo-TestableData on $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') # Output format: $dataTypeString `$$Name = @' $originalString '@ `$${Name}Object = $convertedObjectSyntax "@ # Ensure the directory exists $directory = Split-Path -Path $Path -Parent if (-not (Test-Path -Path $directory)) { New-Item -Path $directory -ItemType Directory -Force | Out-Null Write-Verbose "Created directory: $directory" } # Write the content to file $outputContent | Out-File -FilePath $Path -Encoding utf8 -Force:$Force -Append:$Append # Write-Verbose "Successfully wrote testable data to: $Path" # Write-Host "Created PowerShell data file: $Path" -ForegroundColor Green # Write-Host "Variables created: `$$Name, `$${Name}Object" -ForegroundColor Green # Write-Host "Output format: $OutputFormat" -ForegroundColor Green # Write-Host "To use: . '$Path'" -ForegroundColor Cyan # Return information about what was created return [PSCustomObject]@{ OutputPath = $Path VariableNames = @($Name, "${Name}Object") OutputFormat = $OutputFormat OriginalType = $originalType Success = $true Force = $Force Append = $Append } } catch { Write-Error "Failed to convert data: $($_.Exception.Message)" return [PSCustomObject]@{ OutputPath = $Path VariableNames = @() DataType = 'Unknown' Success = $false Error = $_.Exception.Message ErrorStackTrace = $_.ScriptStackTrace } } } } |