{"id":10021,"date":"2006-07-12T17:10:00","date_gmt":"2006-07-12T17:10:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2006\/07\/12\/indirectly-invoking-methods-via-variablenames\/"},"modified":"2019-02-18T13:21:33","modified_gmt":"2019-02-18T20:21:33","slug":"indirectly-invoking-methods-via-variablenames","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/indirectly-invoking-methods-via-variablenames\/","title":{"rendered":"Indirectly Invoking Methods Via Variablenames"},"content":{"rendered":"<p>PSMDTAG:FAQ: Can I specify a methodname using a variable? e.g. $x.$y()<\/p>\n<p>PSMDTAG:FAQ: Why do I get METHOD metadata when I specify a method without providing parentheses? <\/p>\n<p>One of the great things about Windows PowerShell is that it is a latebound language which allows you to do all sorts of incredibly powerful operations.&nbsp; Consider the following code which defines a function to&nbsp;display the properties of an object.&nbsp; The&nbsp;names of the properties&nbsp;come from a file passed into the function:<\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; <strong><font color=\"#000080\">function test ($obj, $file) {<br \/>&gt;&gt; foreach ($prop in cat $file) {&#8220;{0,-12} : {1}&#8221; -f $prop, $obj.$prop}<br \/>&gt;&gt; }<br \/><\/font><\/strong>&gt;&gt;<\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; <strong><font color=\"#0000ff\">cat properties.txt<br \/><\/font><\/strong>Name<br \/>ID<\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; <strong><font color=\"#000080\">test (get-process notepad) properties.txt<br \/><\/font><\/strong>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : notepad<br \/>ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 456<\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; <strong><font color=\"#000080\">cat properties2.txt<br \/><\/font><\/strong>Name<br \/>WS<br \/>NPM<br \/>Handles<\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; <font color=\"#000080\">test (get-process notepad) properties2.txt<\/font><br \/>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : notepad<br \/>WS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 7483392<br \/>NPM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 4520<br \/>Handles&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 50<\/font><\/p>\n<p>This works because you can specify $Obj.$Prop&nbsp; where $prop contains the name of the property you want to see.<\/p>\n<p>So how about Methods?&nbsp; Lets see how that works:<\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; $s=&#8221;This is a TEST&#8221;<br \/>PS&gt; $method=&#8221;ToUpper&#8221;<br \/>PS&gt; $s.$method()<br \/>Unexpected token &#8216;(&#8216; in expression or statement.<br \/>At line:1 char:12<br \/>+ $s.$method() &lt;&lt;&lt;&lt;<\/font><\/p>\n<p>It turns out the the parser does not handle this situation.&nbsp; <\/p>\n<p>But now try this:<\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; <strong><font color=\"#000080\">$s=&#8221;This is a TEST&#8221;<br \/><\/font><\/strong>PS&gt; <strong><font color=\"#000080\">$s.ToUpper()<\/font><\/strong><br \/>THIS IS A TEST<br \/>PS&gt; <strong><font color=\"#000080\">$s.ToUpper<\/font><\/strong><\/font><br \/><font face=\"Courier New\" size=\"1\">MemberType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Method<br \/>OverloadDefinitions : {System.String ToUpper(), System.String ToUpper(Cultu<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reInfo culture)}<br \/>TypeNameOfValue&nbsp;&nbsp;&nbsp;&nbsp; : System.Management.Automation.PSMethod<br \/>Value&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : System.String ToUpper(), System.String ToUpper(Cultur<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eInfo culture)<br \/>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : ToUpper<br \/>IsInstance&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : True<\/font><\/p>\n<p>What is happening is that if you specify a METHOD with parens, we call it.&nbsp; If you specify a method without parens, we return the metadata for that method.&nbsp; This can be a tad non-plussing at first but it turns out to be very useful at times.&nbsp; In particular, it allows you to do this:<\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; <strong><font color=\"#000080\">$s=&#8221;This is a TEST&#8221;<br \/><\/font><\/strong>PS&gt; <strong><font color=\"#000080\">$s.ToUpper.Invoke()<\/font><\/strong><br \/>THIS IS A TEST<br \/>PS&gt; <strong><font color=\"#000080\">foreach ($method in &#8220;ToUpper&#8221;,&#8221;ToLower&#8221;,&#8221;GetType&#8221;) {$s.$method.Invoke()}<\/font><\/strong><\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">THIS IS A TEST<br \/>this is a test<\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">IsPublic IsSerial Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BaseType<br \/>&#8212;&#8212;&#8211; &#8212;&#8212;&#8211; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8211;<br \/>True&nbsp;&nbsp;&nbsp;&nbsp; True&nbsp;&nbsp;&nbsp;&nbsp; String&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Object<br \/><\/font><\/p>\n<p><font face=\"Courier New\"><font size=\"2\">Enjoy!<\/font><\/font><\/p>\n<p><font face=\"Courier New\"><font size=\"2\"><\/font><\/font>&nbsp;<\/p>\n<p><font face=\"Courier New\"><font size=\"2\">Jeffrey Snover [MSFT]<br \/>Windows PowerShell\/Aspen Architect<br \/>Visit the Windows PowerShell Team blog at:&nbsp;&nbsp;&nbsp; <\/font><a href=\"http:\/\/blogs.msdn.com\/PowerShell\"><font size=\"2\">http:\/\/blogs.msdn.com\/PowerShell<\/font><\/a><br \/><font size=\"2\">Visit the Windows PowerShell ScriptCenter at:&nbsp; <\/font><a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\"><font size=\"2\">http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx<\/font><\/a><\/font><\/p>\n<p><font face=\"Courier New\" size=\"2\">PSMDTAG:INTERNAL: Indirectly invoking methods via variable Names<\/font><\/p>\n<p><font face=\"Courier New\"><font size=\"2\">PSMDTAG:LANGUAGE: Parser does not accept directly support variable substitution for method names<\/font><\/p>\n<p><\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>PSMDTAG:FAQ: Can I specify a methodname using a variable? e.g. $x.$y() PSMDTAG:FAQ: Why do I get METHOD metadata when I specify a method without providing parentheses? One of the great things about Windows PowerShell is that it is a latebound language which allows you to do all sorts of incredibly powerful operations.&nbsp; Consider the following [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[10,33,34],"class_list":["post-10021","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-faq","tag-language","tag-methods"],"acf":[],"blog_post_summary":"<p>PSMDTAG:FAQ: Can I specify a methodname using a variable? e.g. $x.$y() PSMDTAG:FAQ: Why do I get METHOD metadata when I specify a method without providing parentheses? One of the great things about Windows PowerShell is that it is a latebound language which allows you to do all sorts of incredibly powerful operations.&nbsp; Consider the following [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/10021","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=10021"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/10021\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=10021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=10021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=10021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}