{"id":10811,"date":"2006-04-25T12:17:59","date_gmt":"2006-04-25T12:17:59","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2006\/04\/25\/a-bit-about-scriptblocks\/"},"modified":"2019-02-18T13:25:03","modified_gmt":"2019-02-18T20:25:03","slug":"a-bit-about-scriptblocks","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/a-bit-about-scriptblocks\/","title":{"rendered":"A bit about Scriptblocks"},"content":{"rendered":"<p class=\"MsoNormal\"><span>When scripting with MSH one of the most useful things to know about are scriptblocks (lambda functions). <span>&nbsp;<\/span>Scriptblocks are compiled bits of MSH script which you can pass around and invoke whenever you feel like it. <span>&nbsp;<\/span>They turn out to be so useful that if you look at the cmdlets you\u2019ll find a few that take scriptblocks (foreach-object, where-object, time-expression, select-object, format-table ).<span>&nbsp; <\/span>So how do we create scriptblocks?<span>&nbsp; <\/span>Well, if you\u2019ve ever used foreach-object you already know how to do it. <span>&nbsp;<\/span>Simply write some MSH inside { }<span>&nbsp; <\/span>and you\u2019re done.<span>&nbsp; <\/span>You can invoke them using &amp; or \u201c.\u201d for dot sourcing.<span>&nbsp; <\/span>Pipeline input will be in $input and your arguments will be in $args.<span>&nbsp; <\/span>Here\u2019s a quick demo: <\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Courier New\" size=\"3\"><font size=\"1\">MSH&gt;$script = { write-host <span>&#8220;The scriptblock has been invoked.&#8221;<\/span>; write-host <span>&#8220;Pipe: $input&#8221;<\/span>; write-host <span>&#8220;Args: $args&#8221;<\/span> }<br \/>MSH&gt;<span>1<\/span>,<span>2<\/span>,<span>3<\/span> | &amp; $script <span>4<\/span> <span>5<\/span> <span>6<\/span><br \/>The scriptblock has been invoked.<br \/>Pipe: <span>1<\/span> <span>2<\/span> <span>3<\/span><br \/>Args: <span>4<\/span> <span>5<\/span> <span>6<\/span><br \/>MSH&gt;<span>function<\/span> InvokeTheScript([scriptblock]$myScript) { &amp; $myScript }<br \/>MSH&gt;InvokeTheScript $script<br \/>The scriptblock has been invoked.<br \/>Pipe:<br \/>Args:<br \/>MSH&gt;InvokeTheScript { <span>1<\/span> + <span>1<\/span> }<br \/><span>2<\/span><br \/>MSH&gt;<span>1<\/span>,<span>2<\/span> | <span>foreach<\/span>&#8211;<span>object<\/span> $script<br \/>The scriptblock has been invoked.<br \/>Pipe: <span>1<\/span><br \/>Args:<br \/>The scriptblock has been invoked.<br \/>Pipe: <span>2<\/span><br \/>Args:<\/font><\/font><\/span><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Funny how that function declaration has something resembling a scriptblock after the parameters huh?<span>&nbsp; <\/span>Well\u2026 if you were to look at the function provider you\u2019d quickly find out that it is indeed a scriptblock. <span>&nbsp;<\/span>A named scriptblock, but a scriptblock nonetheless.<span>&nbsp; <\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Courier New\" size=\"1\">MSH&gt;get-item <span>function<\/span>:\\InvokeTheScript | get-member<\/p>\n<p>&nbsp;&nbsp; TypeName: System.Management.Automation.FunctionInfo<\/p>\n<p>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType&nbsp;&nbsp; Definition<br \/>&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp; &#8212;&#8212;&#8212;-<br \/>Equals&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Boolean Equals(<span>Object<\/span> obj)<br \/>get_CommandType Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.CommandTypes get_CommandType()<br \/>get_Definition&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.<span>String<\/span> get_Definition()<br \/>get_Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.<span>String<\/span> get_Name()<br \/>get_Options&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.ScopedItemOptions get_Options()<br \/>get_ScriptBlock Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.ScriptBlock get_ScriptBlock()<br \/>GetHashCode&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Int32 GetHashCode()<br \/>GetType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Type GetType()<br \/>set_Options&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.<span>Void<\/span> set_Options(ScopedItemOptions value)<br \/>ToString&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.<span>String<\/span> ToString()<br \/>MshDrive&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty System.Management.Automation.DriveInfo MshDrive=<span>Function<\/span><br \/>MshIsContainer&nbsp; NoteProperty System.Boolean MshIsContainer=False<br \/>MshPath&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty System.<span>String<\/span> MshPath=Microsoft.Management.Automation.Core\\<span>Function<\/span>::InvokeTheScript<br \/>MshProvider&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty System.Management.Automation.ProviderInfo MshProvider=Microsoft.Management.Automation.C&#8230;<br \/>CommandType&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.CommandTypes CommandType {get;}<br \/>Definition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp;&nbsp;&nbsp; System.<span>String<\/span> Definition {get;}<br \/>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp;&nbsp;&nbsp; System.<span>String<\/span> Name {get;}<br \/>Options&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.ScopedItemOptions Options {get;set;}<br \/>ScriptBlock&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.ScriptBlock ScriptBlock {get;}<\/p>\n<p>MSH&gt;(get-item <span>function<\/span>:\\InvokeTheScript).ScriptBlock<br \/>param([scriptblock]$myScript) &amp; $myScript<br \/><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>I\u2019d give you some really good examples of scriptblock usage but I don\u2019t know any.<\/span><span> JK, of course.<span>&nbsp; <\/span>Actually, a long time ago one of our PMs used scriptblocks in such an excellent way so I\u2019ll just point you guys to his post about it.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><a href=\"http:\/\/www.proudlyserving.com\/archives\/2005\/07\/monad_and_rss_p_2.html\">http:\/\/www.proudlyserving.com\/archives\/2005\/07\/monad_and_rss_p_2.html<\/a><\/span><\/p>\n<p>&#8211; Marcel<\/p>\n<p>[<i>Edit: Monad has now been renamed to Windows PowerShell.  This script or discussion may require slight adjustments before it applies directly to newer builds.<\/i>]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When scripting with MSH one of the most useful things to know about are scriptblocks (lambda functions). &nbsp;Scriptblocks are compiled bits of MSH script which you can pass around and invoke whenever you feel like it. &nbsp;They turn out to be so useful that if you look at the cmdlets you\u2019ll find a few that [&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":[],"class_list":["post-10811","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell"],"acf":[],"blog_post_summary":"<p>When scripting with MSH one of the most useful things to know about are scriptblocks (lambda functions). &nbsp;Scriptblocks are compiled bits of MSH script which you can pass around and invoke whenever you feel like it. &nbsp;They turn out to be so useful that if you look at the cmdlets you\u2019ll find a few that [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/10811","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=10811"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/10811\/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=10811"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=10811"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=10811"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}