Max script block size when passing to powershell.exe or invoke-command

This. This may be the most important piece of information I ever contribute to anyone automating Service Manager (SCSM).

If you’ve ever worked with Orchestrator, and specifically Orchestrator and SMLets, you know what a pain in the butt it is. No, seriously. Orchestrator (Also known as SCORCH or ORCH) is great in a lot of ways but miserable in others. For me, right now, it has a big flaw – working with PowerShell.

If you use the built-in “.Net Activity” to run a PowerShell script, it only runs in PowerShell version 2. No problem you say! Several people have written tutorials on how to drop from PowerShell 2 into PowerShell 3. Those examples are numerous, and are an excellent resource (See here, here, here, here, and many others).

There’s even a separate Orchestrator Integration Pack that allows you to run PS scripts easier in SCORCH. Cool beans.

Here’s where it gets ugly. Let’s say, I’m developing a script in the ISE because it’s awesome. That development is happening on a box that has PowerShell 3. PowerShell 3 has several cool functions in it that I happen to rely on (I know in many cases there are workarounds using PS2, but that’s not always the case!) and so when I paste the entire script into SCORCH and try to run it (like all those examples above tell us to do), I get errors galore.

It’s not that I’m doing anything different from the links above. Nope, not a thing. I’m just passing the entire script to a powershell.exe scriptblock (Or script block, I’ve seen it spelled both ways) or to invoke-command. That will, in theory, drop the entire script into PowerShell 3 land and the script can then proceed on its merry way.

Specifically, I get lovely errors like:

“System.Management.Automation.ApplicationFailedException: Program ‘powershell.exe’ failed to execute: The filename or extension is too long”

PSError

Such errors have been rectified by splitting up script blocks into smaller parts that can be passed on, and ensuring that only the absolute necessary items are passed to PowerShell or invoke-command. This then gets more complex, as you’re making multiple calls and passing multiple variables in and out. This takes more time, and good luck passing any objects in or out; they get deserialzed in that process and lose all access to any methods that the original object had. So now, we’re talking about passing strings between sessions, calling for objects inside the new PS3 session only to recreate the object we had in our existing PS2 session, just so we can run a method on it. This adds complexity, time, and lots of other not-fun things to our automation.

It turns out that both powershell.exe, and invoke-command have a limit on the size of the scriptblock. It’s been something that my co-workers and some of our implementation partners have run up against again, and again.

The size limit we kept hitting was one that we had only guessed at, one that was unknown, one that we tackled blindly… UNTIL TODAY.

There is a 12190 byte MAX limit of any script block passed to powershell.exe or invoke-command. 

The easiest way to see how big your block is, is to just copy it into Notepad++ and look at the ‘length’ value at the bottom of the editor window. That tells you the byte size of the resulting file (and therefore text), and as long as your script is less than 12190 bytes, it will be passed along with no errors to whatever you like

Go over that limit and you’ll be cast into a world of uncertainty and doubt where your ability to code succinctly is called into question!

And now you know 🙂