Chapter 11Lesson 04~145 minutes

CLIXML, Serialization, Deserialized Objects, and Type Fidelity

Understand PowerShell-oriented serialization with CLIXML, deserialized snapshots, method loss, depth, type fidelity, and credential security caveats.

Learning objectives

  • Define serialization and deserialization in practical PowerShell terms.
  • Use Export-Clixml and Import-Clixml in a disposable workspace.
  • Recognize deserialized snapshots and lost live methods.
  • Reason about serialization depth and nested fidelity.
  • Apply strict platform cautions to credential serialization.
  • Compare CSV, JSON, XML, and CLIXML using engineering criteria.

1. Serialization means turning object state into portable data

Serialization converts object state into a representation that can be stored or transmitted. Deserialization reconstructs an object-like representation from that data. The reconstructed result is not necessarily the original live object.

CLIXML is PowerShell's Common Language Infrastructure XML representation. It preserves more PowerShell-oriented structure and type metadata than CSV, but it still cannot freeze a running process, file handle, socket, or method implementation into a file.

2. Export-Clixml and Import-Clixml

$lab = Join-Path ([System.IO.Path]::GetTempPath()) 'ps-ch11-clixml'
New-Item -ItemType Directory -Path $lab -Force | Out-Null
$path = Join-Path $lab 'inventory.clixml'

$source = @(
    [pscustomobject]@{ Name='api'; Started=[datetime]'2026-08-11T12:00:00Z'; Ports=@(443,8443) }
    [pscustomobject]@{ Name='worker'; Started=[datetime]'2026-08-11T12:05:00Z'; Ports=@(5671) }
)
$source | Export-Clixml -LiteralPath $path
$restored = Import-Clixml -LiteralPath $path
$restored | Format-List

3. Deserialized objects are snapshots

When PowerShell serializes many objects, it records property values and type-name information. After import, the object is commonly labeled with a type name beginning with Deserialized.. Methods of the original live object are not restored.

$processPath = Join-Path $lab 'process.clixml'
Get-Process -Id $PID | Export-Clixml -LiteralPath $processPath
$copy = Import-Clixml -LiteralPath $processPath
$copy.PSTypeNames | Select-Object -First 3
$copy | Get-Member

4. Why methods cannot simply cross the boundary

A process object can expose methods because it is connected to a live operating-system process through runtime state. A file can record properties such as Id, name, and memory usage at one instant, but importing that file does not recreate the OS process or its live handle. This is the same concept you will meet again in remoting: serialization moves data, not executable object identity.

5. Serialization depth is a fidelity decision

Export-Clixml has a -Depth parameter. Nested data beyond the chosen depth may not preserve everything you expect. For configuration objects, inspect the round trip in tests instead of assuming a serializer preserves every nested detail.

$nested = [pscustomobject]@{
    Name='api'
    Runtime=[pscustomobject]@{
        Limits=[pscustomobject]@{ Cpu=2; MemoryMb=1024 }
    }
}
$nested | Export-Clixml -LiteralPath (Join-Path $lab 'nested.clixml') -Depth 5

6. Credentials: strong Windows-only warning

CLIXML is sometimes used to store PSCredential. On Windows, exported credential data can be protected with DPAPI so only the same user on the same computer can decrypt it. On Linux and macOS, Microsoft explicitly warns that exported credentials are stored as an encoded Unicode character array rather than encrypted. Therefore, do not treat CLIXML as a portable secret vault. Chapter 16 covers secret management properly.

This lesson does not ask you to create or export real credentials.

7. Same source object, different serialization contracts

$record = [pscustomobject]@{
    Name='api'
    Enabled=$true
    Started=[datetime]'2026-08-11T12:00:00Z'
    Ports=@(443,8443)
}
$record | ConvertTo-Csv -NoTypeInformation
$record | ConvertTo-Json -Depth 5
# XML/CLIXML are file-oriented or object-model-oriented formats with different fidelity goals.
FormatInteroperabilityNested dataPowerShell type fidelityHuman readability
CSVVery highPoorLowHigh for flat tables
JSONVery highStrongModerate/limitedHigh
XMLHighStrongSchema-dependentModerate
CLIXMLPowerShell-focusedStrongHigher for snapshotsLow to moderate

8. Choose format by consumer, not habit

Ask four questions: Who consumes the file? Does the data nest? Must types survive? Is the file intended for human review? A PowerShell-only cache may favor CLIXML; an API payload favors JSON; a spreadsheet handoff favors CSV; an existing enterprise schema may require XML.

9. Lab: compare round-trip behavior

$lab = Join-Path ([System.IO.Path]::GetTempPath()) 'ps-ch11-roundtrip'
New-Item -ItemType Directory -Path $lab -Force | Out-Null
$source = [pscustomobject]@{
    Name='api'
    Enabled=$true
    Started=[datetime]'2026-08-11T12:00:00Z'
    Ports=@(443,8443)
}

$source | Export-Csv -LiteralPath (Join-Path $lab 'data.csv')
$source | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath (Join-Path $lab 'data.json') -Encoding utf8
$source | Export-Clixml -LiteralPath (Join-Path $lab 'data.clixml')

$csv = Import-Csv -LiteralPath (Join-Path $lab 'data.csv')
$json = Get-Content -Raw -LiteralPath (Join-Path $lab 'data.json') | ConvertFrom-Json
$cli = Import-Clixml -LiteralPath (Join-Path $lab 'data.clixml')

[pscustomobject]@{
    CsvStartedType = $csv.Started.GetType().FullName
    JsonStartedType = $json.Started.GetType().FullName
    CliStartedType = $cli.Started.GetType().FullName
    CsvPorts = $csv.Ports
    JsonPortCount = @($json.Ports).Count
    CliPortCount = @($cli.Ports).Count
} | Format-List

Remove-Item -LiteralPath $lab -Recurse -Force

Expected observations

  • The CSV round trip demonstrates low type fidelity: date/time and array-shaped values become text representations.
  • The JSON round trip preserves nested/array shape well but does not promise arbitrary .NET object identity or methods.
  • The CLIXML round trip preserves richer PowerShell-oriented type information while remaining a deserialized snapshot.

10. Verification checklist

  • I can define serialization, deserialization, and a deserialized snapshot.
  • I can explain why live methods/process handles do not survive a file boundary.
  • I can state the Windows-only security guarantee for CLIXML credential encryption and the non-Windows warning.
  • I can justify choosing CSV, JSON, XML, or CLIXML for a stated consumer.

11. Common mistakes

  • Assuming deserialization recreates a live object with working methods.
  • Using CLIXML as a cross-platform secret vault.
  • Choosing CLIXML for an external system that expects an interoperable standard format.
  • Ignoring serialization depth for nested state.
  • Failing to test round-trip behavior with representative data.

12. Knowledge check

Question 1. What is serialization?

Question 2. Why does an imported process snapshot not have the original live process behavior?

Question 3. What prefix commonly appears in type names for deserialized PowerShell objects?

Question 4. Is CLIXML credential export encrypted on Linux and macOS?

Question 5. When is CLIXML most attractive?

13. Summary and next bridge

CLIXML is a PowerShell-focused snapshot format: richer than CSV, but still serialization rather than live-object teleportation. Treat credential behavior as platform-specific and never confuse encoded data with secret storage. Next, YAML brings DevOps-friendly configuration syntax—but also a dependency decision because conversion is not a built-in core cmdlet.

14. Authoritative references

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.