I'm always preaching about writing PowerShell scripts and functions with reuse and modularization in mind. You should never have to write the same block of code twice. But what about in the shell during your daily grind? Perhaps today you're dealing with some issue and periodically need to run a particular block of code. Now, you could run it once, make a note of the command number and then use Invoke-History throughout the day to keep running it. What I like to do in these situations is create a scriptblock which is assigned to a variable. Then I can invoke it anytime I want.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
A scriptblock is some set of PowerShell commands contained in a set of braces. It is important to remember that scriptblocks also have their own scope so be careful. Here's a simple example:
[cc lang="PowerShell"]
PS C:\> $running={get-service | where {$_.status -eq "Running"}}
[/cc]
If I look at the value of $running, I'll see my command. But now anytime I want to get a list of running services, I use the & operator to invoke it.
[cc lang="DOS"]
PS C:\> &$running
Status Name DisplayName
------ ---- -----------
Running AppMgmt Application Management
Running AudioEndpointBu... Windows Audio Endpoint Builder
Running AudioSrv Windows Audio
Running BFE Base Filtering Engine
Running BITS Background Intelligent Transfer Ser...
Running bthserv Bluetooth Support Service
Running CertPropSvc Certificate Propagation
Running cmdAgent COMODO Internet Security Helper Ser...
Running CryptSvc Cryptographic Services
...
[/cc]
The scriptblock is writing the service object to the pipeline and I can pipe its output to anything else.
[cc lang="DOS"]
PS C:\> &$running | sort displayname | select displayname -first 3
DisplayName
-----------
Application Management
Background Intelligent Transfer Service
Base Filtering Engine
[/cc]
Because I already have a scriptblock, I can also use it with commands like Start-Job and Invoke-Command which adds even more flexibility.
[cc lang="DOS"]
PS C:\> invoke-command $running -ComputerName Quark
Status Name DisplayName PSComputerName
------ ---- ----------- --------------
Running Appinfo Application Information quark
Running AudioEndpointBu... Windows Audio Endpoint Builder quark
Running Audiosrv Windows Audio quark
Running BFE Base Filtering Engine quark
Running BITS Background Intelligent Transfer Ser... quark
Running Browser Computer Browser quark
...
[/cc]
And even with scriptblocks I can build in flexibility with parameters.
[cc lang="DOS"]
PS C:\> $running={param($computername=$env:computername,$status="Running") get-service -computername $computername | whe
re {$_.status -eq $Status}}
PS C:\> &$running Quark Stopped | select -first 3
Status Name DisplayName
------ ---- -----------
Stopped AeLookupSvc Application Experience
Stopped ALG Application Layer Gateway Service
Stopped AppIDSvc Application Identity
[/cc]
Parameters are positional unless you use the parameter name. I recommend you give parameters default values.
You can make your scriptblock as simple or as complex as you need. If you find yourself using the same scriptblock over time, then it's best to turn it into a function or script. Create an alias to make it easier to run. But otherwise, take advantage of this little PowerShell nugget to increase your efficiency and maybe even have a little fun.
1 thought on “ScriptBlocks On the Fly”
Comments are closed.