How do you get the output type from a powershell script with System.Management.Automation?

I am trying to figure out how to get the type specified in a powershell script [OutputType([int])] for example. I can find it in the parsed attributes but it's just treated as an attribute that has "[int]", so it's not seen as a type but just the string value. But there seems to be a OutputTypeAttribute class, but i can't find any information on how to get a hold of that.
13 Replies
Jothay
Jothay2y ago
If you are referring to reading this from C#:
var attr = instance.GetType()
.GetProperty("MyProp")
.GetCustomAttributes<OutputTypeAttribute>()
.SingleOrDefault()
var val = attr.Value;
var attr = instance.GetType()
.GetProperty("MyProp")
.GetCustomAttributes<OutputTypeAttribute>()
.SingleOrDefault()
var val = attr.Value;
That should get you the idea of how to get it
jcotton42
jcotton422y ago
@fjarilsmannen are you like looking at the syntax tree?
function Send-Greeting
{
[CmdletBinding()]
[OutputType([String])]
Param ($Name)

"Hello, $Name"
}

> $f = ${Function:Send-Greeting}
> $f.Ast.Body.ParamBlock.Attributes[1].PositionalArguments

TypeName StaticType Extent Parent
-------- ---------- ------ ------
String System.Type [String] [OutputType([String])]
function Send-Greeting
{
[CmdletBinding()]
[OutputType([String])]
Param ($Name)

"Hello, $Name"
}

> $f = ${Function:Send-Greeting}
> $f.Ast.Body.ParamBlock.Attributes[1].PositionalArguments

TypeName StaticType Extent Parent
-------- ---------- ------ ------
String System.Type [String] [OutputType([String])]
$f is a ScriptBlock
Fjärilsmannen
FjärilsmannenOP2y ago
@jothay Not sure what the property is here? @jcotton42 That's basically how i find it right now, though it's not a function but the script itself. But as you can see it doesn't show the proper type, it's seen as System.Type and TypeName is simply just the text it shows, so it will show whatever you write and doesn't indicate the actual type here it seems.
jcotton42
jcotton422y ago
well yeah, it's just the syntax tree if you want an actual System.Type instance, use something like Type.GetType(string typeNam) though, be aware it won't necessarily be a "real" type
Jothay
Jothay2y ago
For common stuff like that, you could switch case the type values and handle string, int, etc individually
jcotton42
jcotton422y ago
as OutputType allows strings in addition to type literals
Fjärilsmannen
FjärilsmannenOP2y ago
ah
jcotton42
jcotton422y ago
it's not uncommon to use a "fake" typename in custom powershell objects to allow for things like formatting rules to apply automatically
Fjärilsmannen
FjärilsmannenOP2y ago
hmm, is there some better way to se the output type? It's meant to be read from C# and i'm in control of the scripts, so just having a way to set a real type that can be read would be best. The same way you can with normal parameters. For example a dummy variable perhaps, not sure if those can be read though.
jcotton42
jcotton422y ago
I mean parsing from the AST is likely your best bet I don't think PowerShell has a public semantic model like C# does
Fjärilsmannen
FjärilsmannenOP2y ago
ah okay. How do i actually get TypeName from an ExpressionAst, i can see it when printing the whole object, but i can't access that property
jcotton42
jcotton422y ago
b/c it's actually TypeExpressionAst you need to cast it or do an is check
Fjärilsmannen
FjärilsmannenOP2y ago
Ah, got it, thanks:)!

Did you find this page helpful?