Tuesday, October 30, 2018

Passing a Variable as a ScriptBlock in Powershell

Recently I was tasked with creating a deployment script which would run an executable with an argument. This is performed monthly, and we have just begun deploying it with SCCM. Originally, we would call the executable with its argument, but we find that the executable hangs and many manual fixes must be performed. For some reason, deployment with SCCM seemed to create this hanging executable situation more often than our previous (ancient) distribution method.

Previously, the unscripted deployment would simply call the executable with the argument. I do not want to rewrite my script every month, so my Powershell script should:
  • Accept an argument to pass the executable
  • Run the executable as a Job
  • Monitor the Job, retrying if it takes too long 
The problem was getting $Command = "my.exe /arg x" into a ScriptBlock. Using this syntax we get:

PS A:\> $Command = "my.exe /arg x"
PS A:\> Start-Job -ScriptBlock{ $Command }

Id  Name  PSJobTypeName  State    HasMoreData  Location   Command
--  ----  -------------  -----    -----------  --------   -------
1   Job1  BackgroundJob  Running  True         localhost  $Command

Obviously, our ScriptBlock is not "$Command", so we need to turn it into an acceptable form. To do this we create a ScriptBlock, and then call it into the Job without -ScriptBlock, as follows:

PS A:\> $Command = [scriptblock]::create("my.exe /arg x")
PS A:\> Start-Job $Command

Id  Name  PSJobTypeName  State    HasMoreData  Location   Command
--  ----  -------------  -----    -----------  --------   -------
3   Job3  BackgroundJob  Running  True         localhost  my.exe /arg x

As this is a monthly item, I would not hardcode the $Command with a static argument, I would instead accept an argument into my Powershell script, and then pass it as so (assigning a value for this example):

PS A:\> $arg = "y"
PS A:\> $Command = [scriptblock]::create("my.exe /arg $arg")
PS A:\> Start-Job $Command

Id  Name  PSJobTypeName  State    HasMoreData  Location   Command
--  ----  -------------  -----    -----------  --------   -------
5   Job5  BackgroundJob  Running  True         localhost  my.exe /arg y