Prof. Powershell

PowerShell Syntax Elements Part 3: Braces

Here's how to properly use braces to define a scriptblock.

We've been looking at some of the different syntax punctuation you are likely to run into in PowerShell. I'm trying to come up with analogies to help you understand, but sometimes, like any language, you simply have to learn the use case. Today we'll look at braces, {}. Sometimes these are referred to as squiggle brackets. But these are use differently than a square bracket.

The most common use of braces is to define a scriptblock. Think of a scriptblock as a self-contained piece of PowerShell code that will write an object to the pipeline. It is sort of like an undefined function. A number of cmdlets make use of scriptblocks.

PS C:\> Get-Service -name ms* | where {$_.status -eq 'running'}

Status   Name               DisplayName                          
------   ----               -----------                          
Running  msiserver          Windows Installer                    
Running  MSSQLSERVER        SQL Server (MSSQLSERVER) 

I've retrieved all services that start with MS and piped them to Where-Object. This cmdlet uses a scriptblock for a filter. If the status property of the service is equal to "running," PowerShell sends it on to the pipeline. Otherwise it is discarded. When used in Where-Object, the scriptblock has to send True or False to the pipeline. Again, think of the scriptblock as a function.

Function Get-Running {
[cmdletbinding()]
Param([parameter(ValueFromPipeline=$True)]$Service)
if ($service.status -eq 'running') {
Write-Output $service
}
}

This would give me the same result, albeit with a lot more work.

Get-Service -name ms* | get-running

If you notice, the function uses {} to enclose the PowerShell commands. The same thing is happening in Where-Object, except in a much simpler manner, once you understand that $_ indicates a piped object. In this case, a service object. We also use braces to indicate scriptblocks with ForEach-Object.

PS C:\> "alice","bob","carol","david" | foreach {$_.substring(0,1)}
a
b
c
d

I've piped a collection of names and for each one (referenced by $_, I'm invoking the Substring() method). Remember why there are parentheses? By the way, to make your life more interesting, you can get the same results with this expression because each string is made up of an array of characters.

PS C:\> "alice","bob","carol","david" | foreach {$_[0]}
a
b
c
d

Or consider this:

PS C:\> $names = "alice","bob","carol","david"
PS C:\> ForEach ($name in $names) { $name[0] }
a
b
c
d

Again, same result. With the ForEach enumerator, the stuff in parentheses is "processed" by ForEach and for each object ($name), PowerShell executes the code in the squiggly brackets.

You will also see {} used to define a hashtable.

PS C:\> $hash = @{Title="Prof. PowerShell";Computername="MyPC"}
PS C:\> $hash

Name                           Value                                           
----                           -----                                           
Computername                   MyPC                                            
Title                          Prof. PowerShell

Hashtables have methods, which means I need to use parentheses.

 

PS C:\> $hash.Add("Shell","PowerShell")

As I've been saying all along, the best way to understand PowerShell punctuation, is to learn it in context. Let me leave you with this example.

$numbers = @(1,5,2,"a",4)
$results = @{}

Foreach ($r in $numbers) {
if ($r -is [int]) {
$results.Add(($r -as [string]),[math]::Round( (([math]::PI) * ($r * $r)),2))
<#

Or you can drop the parentheses which in this case doesn't make a difference

[math]::PI * $r * $r
#>
}
else {
Write-Warning "$r is not an integer"
}

} #foreach $r

$results
$results['2']

Again, hardly the greatest PowerShell code you've ever seen, but see if you can understand what it does and how the different PowerShell punctuation is being used. Learn in context and you'll have a much better PowerShell experience.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular