PSCustomObject and Typename

Hi folks,

New to Powershell and the Powershell community. I’ve started learning Powershell in order to be a better IT engineer, specifically with VMware products.

I’ve began creating a library of cmdlets stored in .psm1 files that are essentially wrapper functions around Invoke-WebRequest to network intrastructure REST interfaces. The reply is in XML format. I successfully coded a ConvertFrom-XML cmdlet that converts the XML document to a PSCustomObject and then modifies the typename prior to outputting console. The intent for modifying the typename was to give it a more classified feel per custom object associated to the particular XML response.

My intent is to also pipe these custom objects between cmdlets and to enforce rigidity in certain cmdlets. Certain cmdlets need to have information from previous cmdlets in order to execute. Pretty simple concept but I’m struggling to execute this.

First - I can’t seem to get PSCustomObjects to get piped into the destination cmdlet’s parameter marked as ValueFromPipeline. I assign the variable’s typename to be System.Management.Automation.PSCustomObject, but then during execution of pipeling, I get the following error: “The input object cannot be bound to any parameters…”. I have experience with pipelining and I believe I’m following the rules but for some reason, this particular typename is not successfully binding.

Second - When attempting to assign the pipeline variable’s typename to the custom typename assigned to the PSCustomObject that was outputted by the previous cmdlet, PowerShell doesn’t understand the typename. I can understand this issue as the object hasn’t be defined anywhere (example: scripted classes, .NET or through extended Add-Type).

I don’t really want to statically write a bunch of Powershell classes as the amount of XML conversion and assignment to these static classes would be astronomical and I would also have to worry about version control. At the moment, I’m really enjoying the custom ConvertFrom-XML cmdlet that is doing a lot of the heavy lifting.



What you’re seeing is the difference between merely applying a type name, and defining an actually class. ValueFromPipeline, for example, really needs a defined class that it can locate in .NET.

Assigning a type name does not enforce rigidity; there’s nothing stopping something from adopting a type name, whether it complies with an interface contract or not. Everything you’re saying you want, is what classes do :). That doesn’t mean a scripted class can’t use Convert-FromXML, nor does it mean a class can’t inherit from the XmlDocument type (for example). But type names don’t do what you’re wanting.

Hi Don.

Thank you for your response. I found another thread with your reply with basically the same question but I wanted to be absolutely for sure.

Question - Why is PSCustomObject not considered a permissible .NET class in pipeline input processing?



Well, it is, but it’s not different than System.Object, really. Everything more or less descends from that. Look at -InputObject on Select-Object, for example - it accepts Object/PSObject/PSCustomObject (which are all essentially the same at that level). You’d normally just declare your parameter as [object] or [psobject]. PSCustomObject is, technically, a bit of an artificial/ad-hoc thing. Kinda like how you can have a System.Diagnostics.Process#Selected type name.

Don - Again, thank you.

Back to your usages of classes for my ConvertFrom-XML function. This is a recursive functions that looks for XML nodes that posses strings as the data type, and converts them into a hash table of properties (to be used during the New-Object PSObject -Property call). If the ConvertFrom-XML function comes across an XML node that is XML element, the function calls itself until the last sub- XML node is found and the rest are all strings and then rolls itself back up. In the end, a PSCustomObject is created with string properties and potentially nested PSCustomObjects. This works well with an unknown XML document.

Are you suggesting that I can someone take a script class and dynamically define it’s properties in the way that my PSCustomObject is built?