<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1678611822423757&amp;ev=PageView&amp;noscript=1">
Defrag This

| Read. Reflect. Reboot.

Understanding PowerShell Scriptblocks

Adam Bertram| June 29 2018

| IT insights

understanding-powershell-scriptblocks

If you're not already familiar with scriptblocks, after reading this article, you'll begin to see them all over the place in PowerShell in the form of an opening and a closing curly brace.

Scriptblocks are an important and unique construct in PowerShell. Scriptblocks are essentially a portable unit of code that can be passed around and executed at will. 

A PowerShell scriptblock is an expression. An expression is a piece of code PowerShell knows how to execute. For example, PowerShell has the Invoke-Expression cmdlet. This cmdlet essentially "converts" a "non-expression" like a string to an expression. The string write-output 'foo' won't do anything at all even though it looks like it will but if that's passed to Invoke-Expression, PowerShell would run the code as you'd expect.

PS> Invoke-Expression -Command "write-output 'foo'"
foo

Learn how to automate IT tasks with PowerShell. Download this eBook. 

Now that I've got your mind around expressions, let's take it back to scriptblocks. Creating a scriptblock is as simple as enclosing some code in curly braces.

PS> $myscriptblock = { 1 + 1 }
PS> $myscriptblock.GetType().FullName
System.Management.Automation.ScriptBlock

Once you have that code in a scriptblock, it can be executed a few different ways. Two ways are by using the call operator and the Invoke-Command cmdlet as shown below.

PS> & $myscriptblock
2
PS> Invoke-Command -ScriptBlock $myscriptblock
2
PS>

Scriptblocks are also similar to functions. In fact, they sometimes referred to as anonymous functions. We can create a param block just like a function and pass the value for each parameter as positional parameters.

Also notice we can pass parameter arguments to the scriptblock by using the ArgumentList parameter too.

PS> $myscriptblock = { param($Number) 1 + $Number }
PS> & $myscriptblock 3
3
PS> Invoke-Command -ScriptBlock $myscriptblock -ArgumentList 3
3

Now that you know how to create and execute scriptblocks, let's now go into how variables work inside them. As you'll see, they aren't quite as intuitive as you might think.

Variables will naturally expand as you'd expect in scriptblocks.

PS> $variable = 'foo'
PS> $myscriptblock = { "$variable bar" }
PS> & $myscriptblock

However, there are circumstances where this will not work as you'd expect in certain scoping conditions around functions. You'll occasionally have the need to expand the variable in a string and then convert that expression to a scriptblock as shown below. Here I'm calling the Create() method on the scriptblock class to create a scriptblock from the string $variable bar.

$myscriptblock = [scriptblock]::Create("$variable bar")

Another trick to variables and scriptblocks is variable scoping. For example, if I set a variable's value outside of the scriptblock, create a scriptblock with that variable inside, you'll see that is it by reference. When the variable's value is changed outside of the scriptblock, it is changed inside of the scriptblock as well.

PS> $i = 2
PS> $scriptblock = { "Value of i is $i" }
PS> $i = 3
PS> & $scriptblock
Value of i is 3

Enhance your IT career by learning how to automate with Python. Get started  with this free Python guide.

If you need to ensure the variable's value is set static inside of the scriptblock, you'll need force PowerShell to create a copy of the scriptblock by running the GetNewClosure() method on the scriptblock. This forces a new copy which then sets the variable's value inside.

PS> $i = 2
PS> $scriptblock = { "Value of i is $i" }.GetNewClosure()
PS> $i = 3
PS> & $scriptblock
Value of i is 2

That's it for scriptblocks! I hope you've picked up a few pointers on how scriptblocks work and can make your PowerShell scripts a little bit better.

Topics: IT insights

Leave a Reply

Your email address will not be published. Required fields are marked *

THIS POST WAS WRITTEN BY Adam Bertram

Adam Bertram is a 20-year veteran of IT. He’s currently an automation engineer, blogger, independent consultant, freelance writer, author, and trainer. Adam focuses on DevOps, system management, and automation technologies as well as various cloud platforms. He is a Microsoft Cloud and Datacenter Management MVP and efficiency nerd that enjoys teaching others a better way to leverage automation.

Free Trials

Getting started has never been easier. Download a trial today.

Download Free Trials

Contact Us

Let us know how we can help you. Focus on what matters. 

Send us a note

Subscribe to our Blog

Let’s stay in touch! Register to receive our blog updates.