Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to serialize/deserialize data back and forth between Windows PowerShell and PowerShell core?

I’ve been trying to find a solution to work with a specific cmdlet from ConfigCi built-in module that is incompatible with PowerShell core. The cmdlet is New-CIPolicyRule

I want to use it in my module that targets PowerShell 7.3+.

Here is the command that fails in PowerShell core but works in Windows PowerShell 5.1

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

$ScanLocation = "C:\Program Files\WindowsApps\*"
$RulesWildCards = New-CIPolicyRule -FilePathRule $ScanLocation
New-CIPolicy -MultiplePolicyFormat -FilePath .\policy.xml -Rules $RulesWildCards

This is the error message:

New-CIPolicy: Cannot bind parameter ‘Rules’. Cannot convert value "Microsoft.SecureBoot.UserConfig.Rule" to type "Microsoft.SecureBoot.UserConfig.Rule". Error: "Cannot convert the "Microsoft.SecureBoot.UserConfig.Rule" value of type "Deserialized.Microsoft.SecureBoot.UserConfig.Rule" to type "Microsoft.SecureBoot.UserConfig.Rule"."

The problem is exactly this command:

New-CIPolicy -MultiplePolicyFormat -FilePath .\policy.xml -Rules $RulesWildCards

So I thought why not just let Windows PowerShell handle it, like this:

$ScanLocation = "C:\Program Files\WindowsApps\*"
$RulesWildCards = New-CIPolicyRule -FilePathRule "$ScanLocation"
powershell.exe "New-CIPolicy -MultiplePolicyFormat -FilePath .\ss.xml -Rules `"$RulesWildCards`""

But nope, it’s not that easy, the error message is this:

New-CIPolicy : Cannot bind parameter ‘Rules’. Cannot convert the "Microsoft.SecureBoot.UserConfig.Rule" value of type "System.String" to type "Microsoft.SecureBoot.UserConfig.Rule".

I tried a bunch of combinations of the commands above but no luck

Then I tried importing and exporting the serialized data since IsSerial is True for the output of that command which is stored in $RulesWildCards variable

enter image description here

And these are the interfaces it implements

enter image description here

$ScanLocation = "C:\Program Files\WindowsApps\*"
$objectpolicy = New-CIPolicyRule -FilePathRule $ScanLocation
Export-Clixml -InputObject $objectpolicy -Path .\policyobj.xml
powershell.exe "New-CIPolicy -MultiplePolicyFormat -FilePath .\policy.xml -Rules $(Import-Clixml -Path .\policyobj.xml)"

Even that didn’t work.

I tried a few different things too but none of them worked.

I need a proper way to handle this problem so that I can apply the same solution every time I need to use this cmdlet in PowerShell core.

>Solution :

Try the following – note the use of a script block ({ ... }), -args to pass (invariably positional) arguments, and the reference to the first (and only) positional argument as $args[0] in the script block:

powershell.exe { 
  $RulesWildCards = New-CIPolicyRule -FilePathRule $args[0]
  New-CIPolicy -MultiplePolicyFormat -FilePath .\ss.xml -Rules $RulesWildCards
} -args 'C:\Program Files\WindowsApps\*'

Passing a script block ({ ... }) to the PowerShell CLI (which is only supported from inside a PowerShell session) – of either edition – triggers special behavior that tries to preserve type fidelity as much as possible, within the constraints of PowerShell’s XML-based cross-process serialization – see this answer for background information.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading