You are right and wrong - it all depends on whether the target parameter has a value type ( System.DateTime is a structure, for example) - in this case, everything is lost when the type is forced when the parameter is bound.
If, however, the parameter type is of reference type, you can resurrect the PSObject wrapper using PSObject.AsPSObject() .
I found the following example in pure (-ish) PowerShell for ease of replicability, but I find it adequately shows my point
Paste the following into your C # source file (e.g. TestCmdlets.cs ):
using System; using System.Management.Automation; namespace TestPSObject { // This will be our parameter type public class TestObject {} // This will be our reference type test cmdlet [Cmdlet(VerbsDiagnostic.Test, "PSObjectByRef")] public class TestPSObjectByRefCommand : Cmdlet { [Parameter(Mandatory=true)] public TestObject TestObject { get { return testObject; } set { testObject = value; } } private TestObject testObject; protected override void ProcessRecord() { // If this works, we should receive an object with // identical psextended properties WriteObject(PSObject.AsPSObject(this.TestObject)); } } // This will be our value type test cmdlet [Cmdlet(VerbsDiagnostic.Test, "PSObjectByValue")] public class TestPSObjectByValueCommand : Cmdlet { [Parameter(Mandatory=true)] public DateTime DateTime { get { return dateTime; } set { dateTime = value; } } private DateTime dateTime; protected override void ProcessRecord() { // If this works, we should receive an object with // identical psextended properties (hint: we won't) WriteObject(PSObject.AsPSObject(this.DateTime)); } } }
Now, in your shell, compile and import our test module:
Add-Type -Path .\TestCmdlets.cs -OutputAssembly TestPSObject.dll -OutputType Library Import-Module .\TestPSObject.dll
Then we create test objects and add a note property to them:
$TestObject = New-Object TestPSObject.TestObject $TestObject |Add-Member -MemberType NoteProperty -Name TestProperty -Value "Hi there!" $DateTime = Get-Date $DateTime |Add-Member -MemberType NoteProperty -Name TestProperty -Value "Hi there!"
Now they return the string value Hi there! when you search for the element TestProperty .
Now for the actual test:
$TestObjectAfter = Test-PSObjectByRef -TestObject $TestObject $DateTimeAfter = Test-PSObjectByValue -DateTime $DateTime
It will return Hi there! anyway Hi there! :
$TestObjectAfter.TestProperty
But it will not be:
$DateTimeAfter.TestProperty