Skip to content

Commit b39b5f4

Browse files
authored
Add ConvertTo-CliXml and ConvertFrom-CliXml cmdlets (PowerShell#21063)
1 parent 69dce12 commit b39b5f4

8 files changed

Lines changed: 539 additions & 19 deletions

File tree

src/Microsoft.PowerShell.Commands.Utility/commands/utility/XmlCommands.cs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,86 @@ private void CleanUp()
632632
#endregion IDisposable Members
633633
}
634634

635+
/// <summary>
636+
/// Implements ConvertTo-CliXml command.
637+
/// </summary>
638+
[Cmdlet(VerbsData.ConvertTo, "CliXml", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2280866")]
639+
[OutputType(typeof(string))]
640+
public sealed class ConvertToClixmlCommand : PSCmdlet
641+
{
642+
#region Parameters
643+
644+
/// <summary>
645+
/// Gets or sets input objects to be converted to CliXml object.
646+
/// </summary>
647+
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true)]
648+
public PSObject InputObject { get; set; }
649+
650+
/// <summary>
651+
/// Gets or sets depth of serialization.
652+
/// </summary>
653+
[Parameter]
654+
[ValidateRange(1, int.MaxValue)]
655+
public int Depth { get; set; } = 2;
656+
657+
#endregion Parameters
658+
659+
#region Private Members
660+
661+
private readonly List<object> _inputObjectBuffer = new();
662+
663+
#endregion Private Members
664+
665+
#region Overrides
666+
667+
/// <summary>
668+
/// Process record.
669+
/// </summary>
670+
protected override void ProcessRecord()
671+
{
672+
_inputObjectBuffer.Add(InputObject);
673+
}
674+
675+
/// <summary>
676+
/// End Processing.
677+
/// </summary>
678+
protected override void EndProcessing()
679+
{
680+
WriteObject(PSSerializer.Serialize(_inputObjectBuffer, Depth, enumerate: true));
681+
}
682+
683+
#endregion Overrides
684+
}
685+
686+
/// <summary>
687+
/// Implements ConvertFrom-CliXml command.
688+
/// </summary>
689+
[Cmdlet(VerbsData.ConvertFrom, "CliXml", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2280770")]
690+
public sealed class ConvertFromClixmlCommand : PSCmdlet
691+
{
692+
#region Parameters
693+
694+
/// <summary>
695+
/// Gets or sets input object which is written in CliXml format.
696+
/// </summary>
697+
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true)]
698+
public string InputObject { get; set; }
699+
700+
#endregion Parameters
701+
702+
#region Overrides
703+
704+
/// <summary>
705+
/// Process record.
706+
/// </summary>
707+
protected override void ProcessRecord()
708+
{
709+
WriteObject(PSSerializer.Deserialize(InputObject));
710+
}
711+
712+
#endregion Overrides
713+
}
714+
635715
/// <summary>
636716
/// Helper class to import single XML file.
637717
/// </summary>

src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ CmdletsToExport = @(
2525
'Get-TraceSource', 'Set-TraceSource', 'Add-Type', 'Get-TypeData', 'Remove-TypeData', 'Update-TypeData',
2626
'Get-UICulture', 'Get-Unique', 'Get-Uptime', 'Clear-Variable', 'Get-Variable', 'New-Variable',
2727
'Remove-Variable', 'Set-Variable', 'Get-Verb', 'Write-Verbose', 'Write-Warning', 'Invoke-WebRequest',
28-
'Format-Wide', 'ConvertTo-Xml', 'Select-Xml', 'Get-Error', 'Update-List', 'Unblock-File'
28+
'Format-Wide', 'ConvertTo-Xml', 'Select-Xml', 'Get-Error', 'Update-List', 'Unblock-File', 'ConvertTo-CliXml',
29+
'ConvertFrom-CliXml'
2930
)
3031
FunctionsToExport = @()
3132
AliasesToExport = @('fhx')

src/Modules/Windows/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ CmdletsToExport = @(
2424
'Add-Type', 'Get-TypeData', 'Remove-TypeData', 'Update-TypeData', 'Get-UICulture', 'Get-Unique', 'Get-Uptime',
2525
'Clear-Variable', 'Get-Variable', 'New-Variable', 'Remove-Variable', 'Set-Variable', 'Get-Verb', 'Write-Verbose',
2626
'Write-Warning', 'Invoke-WebRequest', 'Format-Wide', 'ConvertTo-Xml', 'Select-Xml', 'Get-Error', 'Update-List',
27-
'Out-GridView', 'Show-Command', 'Out-Printer'
27+
'Out-GridView', 'Show-Command', 'Out-Printer', 'ConvertTo-CliXml', 'ConvertFrom-CliXml'
2828
)
2929
FunctionsToExport = @()
3030
AliasesToExport = @('fhx')

src/System.Management.Automation/engine/serialization.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,45 @@ public static string Serialize(object source, int depth)
122122
return sb.ToString();
123123
}
124124

125+
/// <summary>
126+
/// Serializes list of objects into PowerShell CliXml.
127+
/// </summary>
128+
/// <param name="source">The input objects to serialize.</param>
129+
/// <param name="depth">The depth of the members to serialize.</param>
130+
/// <param name="enumerate">Enumerates input objects and serializes one at a time.</param>
131+
/// <returns>The serialized object, as CliXml.</returns>
132+
internal static string Serialize(IList<object> source, int depth, bool enumerate)
133+
{
134+
StringBuilder sb = new();
135+
136+
XmlWriterSettings xmlSettings = new()
137+
{
138+
CloseOutput = true,
139+
Encoding = Encoding.Unicode,
140+
Indent = true,
141+
OmitXmlDeclaration = true
142+
};
143+
144+
XmlWriter xw = XmlWriter.Create(sb, xmlSettings);
145+
Serializer serializer = new(xw, depth, useDepthFromTypes: true);
146+
147+
if (enumerate)
148+
{
149+
foreach (object item in source)
150+
{
151+
serializer.Serialize(item);
152+
}
153+
}
154+
else
155+
{
156+
serializer.Serialize(source);
157+
}
158+
159+
serializer.Done();
160+
161+
return sb.ToString();
162+
}
163+
125164
/// <summary>
126165
/// Deserializes PowerShell CliXml into an object.
127166
/// </summary>

0 commit comments

Comments
 (0)