15. December 2008
Andy Schneider
Out of the box in PowerShell, you cannot cast a string to a scriptblock.
1: 81# [scriptblock]"A String that can't be a SB"
2: Cannot convert value "A String that can't be a SB" to type "System.Management.Automation.ScriptBlock". Error: "Invalid
3: cast from 'System.String' to 'System.Management.Automation.ScriptBlock'."
4: At line:1 char:14
5: + [scriptblock] <<<< "A String that can't be a SB"
This is actually a good thing. To be able to take a string and arbitrarily execute it could definitely be a security risk. However, there are definitely times when you need to do this.
In my case, I am parsing a Windows Sharepoint list that has a set of ScriptBlocks and our code snippets that I need to execute. However, when I pull them from SharePoint, they are strings.
Originally, I was using Invoke-Expression because everything was running locally. But now, with PowerShell remoting becoming available with V2, I wanted to start using invoke-command. Invoke-Expression takes a string for the –command parameter. Invoke-Command takes a ScriptBlock as a –ScriptBlock paramater
Using an old V1 method, you can use the following function to convert a string to a script block.
1: function Convert-StringToScriptBlock {
2: param ([string]$string)
3: $scriptblock = $executioncontext.invokecommand.NewScriptBlock($string)
4: return $scriptblock
5: }
Below is a screen shot of using invoke-command with a string vs the scriptblock that we get back from this function.

As you know, Windows 7 (Demoed at PDC) has PowerShell enabled out of the box. Turns out there is a slightly easier way to do this in the new win7 build and it will very likely be here in CTP3 as well.
There is now a static method in the ScriptBlock class called Create().

So we can write a new V2 function (lets make it an advanced function for fun) using this new method.
1: function Convert-StringToScriptBlock {
2: param(
3: [parameter(ValueFromPipeline=$true,Position=0)]
4: [string]
5: $string
6: )
7: $sb = [scriptblock]::Create($string)
8: return $sb
9: }
Now with the ability to specify the [parameter] attribute and pass it in parameters like ValueFromPipeline we can easily pass in our string from the pipeline or directly via the parameter like we did in the V1 version.