Checking parameter types in functions - modules with binary modules and script

Having compiled several PowerShell modules (both binary and script), there is still inconsistency between the two models that I cannot get. Perhaps one of you could shed light on this.

  • Imagine a function that takes a single DateTime value. In a script function, I would define this as the [DateTime] parameter; in a C # function, the parameter will be of type DateTime . So far so good.

  • Now imagine passing the DateTime function to a function to which an additional note property is added using Add-Member . Despite the fact that it is defined as [DateTime] , the script function parameter will gladly accept this value, since in fact it PSObject completes the original DateTime (and potentially containing additional elements), which is unpacked when used. Hope I use the correct terminology here. As expected, passing something other than a (wrapped) DateTime will fail, making the function more or less type safe.

  • The equivalent C # function defines the parameter as DateTime , so AFAIK does not have access to the additional parameter. After all, the only β€œinterface” provided by a parameter is of type DateTime .

  • Alternatively, I could define the parameter type of the C # function as PSObject , but then I would have to check my own type for PSObject BaseObject .

Is there a flaw in my logic? Or, more importantly, is there a way around this so that I can leave my binary module type to check for PowerShell?

Thank you very much in advance!

+7
c # type-conversion powershell
source share
1 answer

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 
+3
source share

All Articles