Jump to content
DarrenWhite99

Batch Wrappers - Embedding Powershell or other files inside Batch Scripts

Recommended Posts

You can't directly run .ps1 files in remote monitors like you can .vbs and .bat files. But this applies beyond just remote monitors, .ps1 doesn't run universally like .vbs or .bat. A way to get PowerShell portable is to use a .vbs or .bat file to carry the PowerShell script.

Here are a couple of ways you can do this: The first is a generic way to embed text files inside a batch script. The embedded files are extracted and saved apart from the script. This example has two simple text files included. (See BATCH-WITH-EMBEDDED-FILEs.bat)

The second script method is a way to include PowerShell code directly inside a batch file. This can run anywhere like a batch and the PowerShell is interpreted directly without creating any secondary files. There is a trade-off, the output will not report the correct line number for any failures, and a script crash can result in no useful output. (Output is buffered. Write-Host will be output immediately. Write-Output will buffer until the script completes.) For this reason it is harder to develop and debug PowerShell wrapped in a batch file. So this method works best when you develop and test a PowerShell script as a separate file, and then simply dump the contents to the end of the Batch framework script. (See BATCH-WITH-EMBEDDED-POWERSHELL.bat)

I use method 1 when I need to include standalone files and want to move them all with one file. (An example is a batch script that imports a trusted publisher certificate. The certificate is carried inside the batch, but needs to be its own file for importing by certutil.) I use method 2 anytime I want a batch to run PowerShell. Several of my remote monitors in LabTech are .bat wrapped PowerShell scripts. I don't like creating a batch file that only turns around to create a separate PowerShell file. You have two files to clean up, etc.

Aside from the starter scripts, I included examples of how I have used both methods in real life.

The attachment has been moved. See https://www.labtechgeek.com/files/file/23-powershell-embedding-in-batch/

 

Share this post


Link to post
Share on other sites

Thanks Darren for all the super l33t methods of running PowerShell you've shared with us.

Here's another "hack" until Automate recognizes that PowerShell is useful. I use this command for my monitors. Change the $F to match your monitor script name and put your hostname in.

%windir%\system32\WindowsPowerShell\v1.0\PowerShell.exe -command "&{  $F = 'Dell_HealthCheck.ps1'; $P = \"$($env:windir)\LTSvc\$($F)\"; if (-not (Test-Path $P)) { Invoke-WebRequest -Uri \"https://labtech.YOURDOMAIN.com/LabTech/Transfer/Monitors/$($F)\" -OutFile $P} &$P  }"

To keep them updated I have a script that updates them based on group membership as part of our weekly maintenance script.

 

If you run into bugs, let me know, we've only been live on this for all our PS monitors for a week or two.

Share this post


Link to post
Share on other sites

One bit of extra info I can contribute here, having just gone through the same need to create Group monitors using Powershell (via wrapper in the same manner as @j0dan).  I realized that with a long Powershell script, we ran into issues converting it to a single line, due to linebreaks and other ugly characters. The solution was to convert our PS script into encoded text. 

This lovely bit of Powershell can be used to convert your PS1 script into batch-friendly Base64-encoded code:
http://community.idera.com/powershell/powertips/b/tips/posts/converting-powershell-to-batch
As posted, it actually will convert all .ps1's in a given folder, but you can widdle it down to a one-liner using the command Convert-PowerShellToBatch.

You can then drop this into a one-liner in your monitor's executable line using:

%windir%\system32\WindowsPowerShell\v1.0\PowerShell.exe -encodedCommand "paste_base64_encoded_code_here"

I've tested this in a few scenarios and it works beautifully. 

Share this post


Link to post
Share on other sites

Those are both good tips, but the solution I shared above doesn't require putting everything into a single line or encoding. It allows you to literally paste your powershell script inside of a batch file, the only limit being that debug output and interactive functionality is impaired. If you develop and troubleshoot a .ps1 script separately, you can wrap it into a batch without much difficulty since you shouldn't be testing/developing it at that point.

Share this post


Link to post
Share on other sites

Also, a tip on the Base64 encoding. If you try to convert manually, know only Unicode text can be converted to Base64 and be usable. If you use the examples in PowerShell to create the encoded commands it will convert them to Unicode for you, but if you are generating the script programatically (in SQL, etc.) you will need to handle the Unicode conversion before Base64 encoding yourself. (That's also why Base64 encoded PowerShell script seems about twice as large as you might expect, each character is 2 bytes instead of 1).

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...