{"id":3592,"date":"2013-05-22T00:01:00","date_gmt":"2013-05-22T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/05\/22\/variable-substitution-in-a-powershell-script-block\/"},"modified":"2013-05-22T00:01:00","modified_gmt":"2013-05-22T00:01:00","slug":"variable-substitution-in-a-powershell-script-block","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/variable-substitution-in-a-powershell-script-block\/","title":{"rendered":"Variable Substitution in a PowerShell Script Block"},"content":{"rendered":"<p><strong style=\"font-size: 12px\">Summary<\/strong><span style=\"font-size: 12px\">: Microsoft Scripting Guy, Ed Wilson, talks about performing variable substitution inside a Windows PowerShell script block.<\/span>\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\">&nbsp;Hey, Scripting Guy! &nbsp;I am trying to create a command. The command contains variables that I would like to assign prior to creating the command. However, when I get to the script block portion of my code, it does not do the variable substitution for the value the way an expanding string normally works. Can you help me?\n&mdash;SW\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\">&nbsp;Hello SW,\nMicrosoft Scripting Guy, Ed Wilson, is here. Last week at the first ever Northern Virginia PowerShell User Group, the Scripting Wife and I found a great little tea shop. I can&rsquo;t help but thinking about the scone I got there&mdash;it was pretty good.<\/p>\n<h2>Expanding variable values<\/h2>\n<p>One of the really cool things about Windows PowerShell is the expanding strings&mdash;I absolutely love them. It surely beats having to do lots of string concatenation like I had to do back in the VBScript days. To illustrate this technique, I assign a string to the value of a variable&mdash;in this case, the <strong>$a<\/strong> variable. I look at the value contained in the variable. This code is shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $a = &#8220;This is a string&#8221;<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $a<\/p>\n<p style=\"padding-left: 30px\">This is a string\nNow, by using the expanding string, I can see the value that is contained inside the <strong>$a<\/strong> variable. To suppress the variable expansion, I escape it with the grave accent character as shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; &#8220;The value of `$a is $a&#8221;<\/p>\n<p style=\"padding-left: 30px\">The value of $a is This is a string<\/p>\n<h2>The problem with a script block<\/h2>\n<p>If, on the other hand, I want to expand the value of a variable inside a script block, it does not work. This is shown in the code that follows.<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $a = &#8220;This is a string&#8221;<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $a<\/p>\n<p style=\"padding-left: 30px\">This is a string<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $b = {&#8220;The value of `$a is $a&#8221;}<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $b<\/p>\n<p style=\"padding-left: 30px\">&#8220;The value of `$a is $a&#8221;<\/p>\n<h2>Solving the problem with variable expansion in a script block<\/h2>\n<p>The solution to expanding a variable inside a script block is to do two things. First create the script block as an expanding string. This is shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $a = &#8220;This is a string&#8221;<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $a<\/p>\n<p style=\"padding-left: 30px\">This is a string<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $b = &#8220;The value of `$a is $a&#8221;<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $b<\/p>\n<p style=\"padding-left: 30px\">The value of $a is This is a string\nNow, I use the static <strong>Create<\/strong><em> <\/em>method from the <strong>[scriptblock]<\/strong> class. This will create a script block. To do this, I use the <strong>[scriptblock]<\/strong> class and then call the <strong>Create<\/strong><em> <\/em>method while passing the string contained in the <strong>$b<\/strong> variable. This is shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; [scriptblock]::Create($b)<\/p>\n<p style=\"padding-left: 30px\">The value of $a is This is a string\nI can confirm that it is in fact a script block by piping the results to the <strong>Get-Member<\/strong> cmdlet as shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; [scriptblock]::Create($b) | gm<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; TypeName: System.Management.Automation.ScriptBlock<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType Definition<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;-<\/p>\n<p style=\"padding-left: 30px\">CheckRestrictedLanguage Method&nbsp;&nbsp;&nbsp;&nbsp; void CheckRestrictedLanguage(System.Collection&#8230;<\/p>\n<p style=\"padding-left: 30px\">Equals&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; bool Equals(System.Object obj)<\/p>\n<p style=\"padding-left: 30px\">GetHashCode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; int GetHashCode()<\/p>\n<p style=\"padding-left: 30px\">GetNewClosure&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; scriptblock GetNewClosure()<\/p>\n<p style=\"padding-left: 30px\">GetObjectData&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; void GetObjectData(System.Runtime.Serializatio&#8230;<\/p>\n<p style=\"padding-left: 30px\">GetPowerShell&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; powershell GetPowerShell(Params System.Object[&#8230;<\/p>\n<p style=\"padding-left: 30px\">GetSteppablePipeline&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.SteppablePipeline&#8230;<\/p>\n<p style=\"padding-left: 30px\">GetType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; type GetType()<\/p>\n<p style=\"padding-left: 30px\">Invoke&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Collections.ObjectModel.Collection[psob&#8230;<\/p>\n<p style=\"padding-left: 30px\">InvokeReturnAsIs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Object InvokeReturnAsIs(Params System.O&#8230;<\/p>\n<p style=\"padding-left: 30px\">ToString&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; string ToString()<\/p>\n<p style=\"padding-left: 30px\">Ast&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.Management.Automation.Language.Ast Ast &#8230;<\/p>\n<p style=\"padding-left: 30px\">Attributes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.Collections.Generic.List[System.Attribu&#8230;<\/p>\n<p style=\"padding-left: 30px\">File&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; string File {get;}<\/p>\n<p style=\"padding-left: 30px\">IsFilter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; bool IsFilter {get;set;}<\/p>\n<p style=\"padding-left: 30px\">Module&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; psmoduleinfo Module {get;}<\/p>\n<p style=\"padding-left: 30px\">StartPosition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.Management.Automation.PSToken StartPosi&#8230;\nNow, the cool thing about this is that I can also store the script block into another variable. This is shown here:<\/p>\n<p style=\"padding-left: 30px\">$sb = [scriptblock]::Create($b)\nAfter I have stored the script block into the variable, I can also call any of the methods or properties of the script block. For example, here is the AST:<\/p>\n<p style=\"padding-left: 30px\">PS C:&gt; $sb.Ast<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ParamBlock&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">BeginBlock&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ProcessBlock&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">EndBlock&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : The value of $a is This is a string<\/p>\n<p style=\"padding-left: 30px\">DynamicParamBlock&nbsp; :<\/p>\n<p style=\"padding-left: 30px\">ScriptRequirements :<\/p>\n<p style=\"padding-left: 30px\">Extent&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : The value of $a is This is a string<\/p>\n<p style=\"padding-left: 30px\">Parent&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :\n<span style=\"font-size: 12px\">It is not horribly exciting in this example, but for more complex code, it is definitely exciting stuff. We have a great Hey, Scripting Guy! Blog post written by Bartek Bielawski, which offers several good ideas for further exploration: <\/span><a style=\"font-size: 12px\" href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2012\/09\/26\/learn-how-it-pros-can-use-the-powershell-ast.aspx\" target=\"_blank\">Learn How IT Pros Can Use the PowerShell AST<\/a><span style=\"font-size: 12px\">.<\/span>\nSW, that is all there is to using variable expansion and substitution in a Windows PowerShell script block.&nbsp; Join me tomorrow when I will talk about way cool Windows PowerShell stuff.\nI invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.\n<strong>Ed Wilson, Microsoft Scripting Guy<\/strong><span style=\"font-size: 12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about performing variable substitution inside a Windows PowerShell script block. &nbsp;Hey, Scripting Guy! &nbsp;I am trying to create a command. The command contains variables that I would like to assign prior to creating the command. However, when I get to the script block portion of my code, it [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,3,4,336,45],"class_list":["post-3592","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-scripting-guy","tag-scripting-techniques","tag-strings","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about performing variable substitution inside a Windows PowerShell script block. &nbsp;Hey, Scripting Guy! &nbsp;I am trying to create a command. The command contains variables that I would like to assign prior to creating the command. However, when I get to the script block portion of my code, it [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3592","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=3592"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3592\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=3592"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=3592"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=3592"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}