ParameterBindingArgumentTransformationException while attempting to pass an array of class objects to a function
See original GitHub issueSteps to reproduce
Module.psm1
class CosmosDbDatabase {
[string]$Name;
[bool]$Autoscale;
[int]$Throughput;
CosmosDbDatabase() {
}
CosmosDbDatabase([string]$Name, [bool]$Autoscale, [string]$Throughput) {
$this.Name = $Name;
$this.Autoscale = $Autoscale;
$this.Throughput = $Throughput;
}
}
function Invoke-MyFunction() {
[CmdletBinding()]
param(
[Parameter(Mandatory = $True)][CosmosDbDatabase[]]$Databases
)
# do stuff inside
}
Script.ps1
using module Module.psm1
Import-Module Module.psm1 -Force;
[hashtable]$arguments = @{
"Databases" = @(
# [CosmosDbDatabase]::new("Database1", $true, 4000),
# [CosmosDbDatabase]::new("Database2", $false, 400)
(New-Object CosmosDbDatabase -Property @{
"Name" = "Database1";
"Autoscale" = $true
"Throughput" = 4000;
}),
(New-Object CosmosDbDatabase -Property @{
"Name" = "Database2";
"Autoscale" = $false
"Throughput" = 400;
})
);
};
Invoke-MyFunction @arguments;
Expected behavior
I’m expecting the function to be invoked with all parameters bound successfully, given the fact that I’m using strong typing.
Actual behavior
I’m getting a ParameterBindingArgumentTransformationException saying
Cannot process argument transformation on parameter 'Databases'. Cannot convert the "CosmosDbDatabase" value of type "CosmosDbDatabase" to type "CosmosDbDatabase".
Trace-Command -Name ParameterBinding -Expression {Deploy-AzureCosmosDB @arguments} -PSHost;
yields
DEBUG: 2020-11-24 18:14:04.4883 ParameterBinding Information: 0 : BIND arg [System.Object[]] to parameter [Databases]
DEBUG: 2020-11-24 18:14:04.4884 ParameterBinding Information: 0 : Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: 2020-11-24 18:14:04.4887 ParameterBinding Information: 0 : ERROR: DATA GENERATION: Cannot convert the "CosmosDbDatabase" value of type "CosmosDbDatabase" to type "CosmosDbDatabase".
Apparently I’m attempting to pass a [System.Object[]]
? How can I ensure that the type is as expected?
I’ve checked Write-Host ($arguments["Databases"].GetType().FullName);
before the invocation of my function and got [CosmosDbDatabase[]]
in return as expected. Could this be happening during the splatting?
Callstack
" at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception) at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)"
Environment data
Name Value
---- -----
PSVersion 7.1.0
PSEdition Core
GitCommitId 7.1.0
OS Darwin 19.6.0 Darwin Kernel Version 19.6.0: Thu Oc…
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Issue Analytics
- State:
- Created 3 years ago
- Reactions:3
- Comments:17 (7 by maintainers)
Top Results From Across the Web
Trying and failing to pass an array of custom objects by ...
In the function the .Count I'm calling will increment as workstations are added to the list. But After the function is called the...
Read more >[SOLVED] Passing array of objects to a function - PowerShell
Solution: You can't pass an array of objects to the Process block that way - it will process the entire array at once...
Read more >Passing an array of objects to a function using the Pipleline
When I pass it an array of objects, I get "The input object cannot be found to any parameters for the command either...
Read more >Passing array of objects as parameter in C++
In the main() function, objects of the Student class are created: Here, the first array of objects is s[3] and the other one...
Read more >PowerShell - Few tricks about HashTables and Arrays I wish I ...
I've been working with PowerShell for a while now and like with most things I do I've learned it by doing and not...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
It’s a little bit more complicated than that. They can be modified (well sort of, a new type is generated and type resolution is changed to point to the new version) if they weren’t imported using
using module X
. For example, if the class is used purely for internal module logic and not exposed as a public API,Import-Module X -Force
will work in most cases. The new module session state will point to the new class just like expected.On the subject of adding a
using module X -Force
, the complication there is that it’s a parse time concept. There are a lot of bits in the compiler where the type is currently cached that would need to be invalidated. That’s not impossible, but getting that to work right is a large work item.Another problem that would need to be solved is subclasses. Lets say you have these files:
After the last line of
Main.ps1
, what doesBar
inherit now? Is the type recreated becauseBar2.ps1
has-Force
? Or are they just now incompatible with each other? What if the new version has breaking changes thatBar2.ps1
expects, butBar.ps1
doesn’t?Does your example repro the problem for you? I can’t get it to error.
Anyway, my guess without repro is that it’s related this these lines:
Try taking out the
Import-Module
line. There are some circumstances where you could be creating two instances of the module, importing the types from the first, and importing the commands from the second. That shouldn’t really happen outside of design time though.