ConvertFrom-Json2Xml.psm1

$rootElementName = "root"
$listElementName = "element"

Function Get-SafeName([string]$name){
  $name = $name.Trim('-').Trim('.').Trim('_')
  $name = $name.Replace(' ','_')

  return $name
}

Function Convert-PSObjectToXml {
  param (
    [PSCustomObject]$object,
    [Int32]$depth = 1,
    [Int32]$indent = 1,
    [Boolean]$isTopLevel = $true
  )
  $indentString = " "
  $xmlString = ""

  if ($isTopLevel)
  {
    $xmlString += "<?xml version=`"1.0`" encoding=`"UTF-8`" ?>" + "`n"
    $xmlString += "<$(Get-SafeName $rootElementName)>" + "`n"

    if ($object -is [array]){
      foreach ($element in $object) {
        if ($element.GetType().Name -eq "PSCustomObject" -and $depth -gt 1) {
          $xmlString += "$($indentString * ($indent+1))<$(Get-SafeName $listElementName)>" + "`n"
          $xmlString += (Convert-PSObjectToXml $element -indent ($indent + 3) -depth ($depth + 1) -isTopLevel $false)
          $xmlString += "$($indentString * ($indent+1))</$(Get-SafeName $listElementName)>" + "`n"
        } else {
          $xmlString += "$($indentString * ($indent+1))<$(Get-SafeName $listElementName)>$($element)</$(Get-SafeName $listElementName)>" + "`n"
        }
      }
    }
  }

  foreach ($property in (Get-Member -InputObject $object -MemberType NoteProperty)) {
    $childObject = $object.($property.Name)

    if ($childObject.GetType().Name -eq "PSCustomObject" -and $depth -gt 1) {
      $xmlString += "$($indentString * $indent)<$(Get-SafeName $property.Name)>" + "`n"
      $xmlString += (Convert-PSObjectToXml $childObject -indent ($indent + 1) -depth ($depth + 1) -isTopLevel $false)
      $xmlString += "$($indentString * $indent)</$(Get-SafeName $property.Name)>" + "`n"
    }
    elseif ($childObject -is [array]) {
      $xmlString += "$($indentString * $indent)<$(Get-SafeName $property.Name)>" + "`n"
      foreach ($element in $childObject) {
        if ($element.GetType().Name -eq "PSCustomObject" -and $depth -gt 1) {
          $xmlString += "$($indentString * ($indent+1))<$(Get-SafeName $listElementName)>" + "`n"
          $xmlString += (Convert-PSObjectToXml $element -indent ($indent + 3) -depth ($depth + 1) -isTopLevel $false)
          $xmlString += "$($indentString * ($indent+1))</$(Get-SafeName $listElementName)>" + "`n"
        } else {
          $xmlString += "$($indentString * ($indent+1))<$(Get-SafeName $listElementName)>$($element)</$(Get-SafeName $listElementName)>" + "`n"
        }
      }
      $xmlString += "$($indentString * $indent)</$(Get-SafeName $property.Name)>" + "`n"
    } else {
      foreach ($element in $childObject) {
        $xmlString += "$($indentString * $indent)<$(Get-SafeName $property.Name)>$($element)</$(Get-SafeName $property.Name)>" + "`n"
      }
    }
  }

  if ($isTopLevel)
  {
    $xmlString += "</$(Get-SafeName $rootElementName)>"
  }

  return $xmlString
}

Function ConvertFrom-Json2Xml {
  [CmdletBinding()]
  Param
  ( 
    [Parameter(ValueFromPipeline)]
    [string]$jsonString
  )

  try{
    $ErrorActionPreference = "Stop"
    $json = $jsonString | ConvertFrom-Json
    $xml = Convert-PSObjectToXml $json -Depth 2048
    return $xml
  } catch {
    Write-Host "Error Occured while processing. Please ensure you passed a complete json string." -BackgroundColor Black -ForegroundColor Red
    Write-Host "Common error is piping an array of strings, instead of one string. Please use Get-Content file -Raw for a complete JSON string. `nError: $($_.Exception.Message)" -BackgroundColor Black -ForegroundColor Red
  }
}

New-Alias -Name JTX -Value ConvertFrom-Json2Xml