Script Blocks

Running a set of commands between curly braces doesn't actually execute them:

# Outputs 'Clear-Host; Get-ChildItem' rather than executing the commands
{Clear-Host; Get-ChildItem}

The block can be executed by prefixing with &:

# Clears the host and lists child items
&{Clear-Host; Get-ChildItem}

Blocks can also be assigned to variables:

$commands = {Clear-Host; Get-ChildItem}
&$commands

To get the return value of a script block, wrap it in parens:

Clear-Host
$value = {41 + 1}
"The result is {0}" -f (&$value)    # Outputs 'The result is 42'
1 + &$value                         # Syntax error

If multiple commands are in a block, the first command not consumed will be returned:

# Outputs:
# Not returned
# Consumed the value 42
Clear-Host
$value = {42; Write-Host "Not returned"}
"Consumed the value {0}" -f (&$value)

Can use return to return a value, but any subsequent commands won't get executed:

# Outputs '42'
$value = {Clear-Host; return 42; Write-Host "This is ignored"}
&$value

One way to pass arguments to a script block is using the args array (useful if you have a variable number of arguments):

$qa = {
    $question = $args[0]
    $answer = $args[1]
    Clear-Host
    Write-Host "Here is your question: $question`nThe answer is: $answer"
}

&$qa "Is Powershell easy to learn?" "Yes!"

Here's the same block using the more readable params command:

$qa = {
    param ($question, $answer)
    Clear-Host
    Write-Host "Here is your question: $question`nThe answer is: $answer"
}

# Can optionally pass by name, order doesn't matter
# Note that you don't have to specify the full name, could instead use
# -q and -a. Nice for one-off scripts but not as readable.
&$qa -answer "Yes!" -question "Is Powershell easy to learn?"

If a value is expected but not passed, by default it is converted to null. Can also explicitly check for an empty value:

$qa = {
    param ($question, $answer)
    if (!$answer) { $answer = "Error: You must give an answer!" }
    Clear-Host
    Write-Host "Here is your question: $question`nThe answer is: $answer"
}

&$qa "What is the meaning of life?"

Can also specify default values for params:

$qa = {
    param ($question, $answer = "I don't know")
    Clear-Host
    Write-Host "Here is your question: $question`nThe answer is: $answer"
}

&$qa "What is the meaning of life?"

Can force params to specific types:

Clear-Host
$math = {
    param ([int] $x, [int] $y)
    return $x * $y
}

&$math 3 11
&$math 3 "x"    # Error

Use process to enable pipelining:

Set-Location "C:\Temp"
$onlyTextFiles =
{
    process
    {
        if ($_.Name -like "*.txt") { return $_.Name }
    }
}

Clear-Host
Get-ChildItem | &$onlyTextFiles

Can optionally include begin and/or end blocks for pre-/post-processing:

Set-Location "C:\Temp"
$onlyTextFiles =
{
    begin { $retval = "Here are the text files: `r`n"}
    process
    {
        if ($_.Name -like "*.txt")
        {
            $retval =$retval + "`t" + $_.Name + "`r`n"
        }
    }
    end { return $retval }
}

Clear-Host
Get-ChildItem | &$onlyTextFiles

Same example with param:

Set-Location "C:\Temp"
$onlyTextFiles =
{
    param ($headertext = "Here are the text files")
    begin { $retval = $headertext + ": `r`n" }
    process
    {
        if ($_.Name -like "*.txt")
        {
            $retval = $retval + "`t" + $_.Name + "`r`n"
        }
    }
    end { return $retval }
}

Clear-Host
Get-ChildItem | &$onlyTextFiles "Here are the files"

results matching ""

    No results matching ""