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
$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
And these are the interfaces it implements
$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.
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.