4

I have a PowerShell script which installs a patch (contains set of files to be added) on a customer machine. For this, I have created a batch file which executes this PowerShell script.
For the customer to run this batch file, the PowerShell script file must be placed onto the customer machine as well.

The PowerShell script is in text format, which can be read and understood by the customer easily.

Can we convert this script file into some non-readable format (e.g. bin or exe), so that it is not readable by the customer?

3
  • 1
    If money is no object, get Powershell Studio from Sapien. It's got a one button compile option and I've built all sorts of crappy little GUI.EXE's with it. Commented Jan 6, 2014 at 7:16
  • Is your goal to obscure the script content from the customer, or to prevent them from altering it? Commented Jan 7, 2014 at 19:43
  • @alroc, I don't want my script file visible to customer. Commented Jan 8, 2014 at 3:32

3 Answers 3

8

You can convert the script to Base64 encoding, so that it's not immediately readable. To convert a PowerShell script file to a Base64 String, run the following command:

$Base64 = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes('c:\path\to\script file.ps1'));

To launch the Base64-encoded script, you can call PowerShell.exe as follows:

powershell.exe -EncodedCommand <Base64String>

For example, the following command:

powershell.exe -EncodedCommand VwByAGkAdABlAC0ASABvAHMAdAAgAC0ATwBiAGoAZQBjAHQAIAAiAEgAZQBsAGwAbwAsACAAdwBvAHIAbABkACEAIgA7AA==

Will return the following results:

Hello, world!
Sign up to request clarification or add additional context in comments.

3 Comments

For additional security maybe I would compress to gzip before encoding to base64. Then only decrypt in RAM via System.IO.MemoryStream and System.IO.Compression.GZipStream making it one step harder for customer's to read.
Base64 encoding won't be a good solution in my case because I have multiple ps1 files which are dependent on each other and are big in size.
This failed for me, I had to use Frimlik solution (with encoding)
5

I tried the solution proposed by @TrevorSullivan, but it gave me error

The term '????' is not recognized as the name of a cmdlet, function,
script file or operable program...

As I found out later there was a problem with bad encoding. I found somewhere another approach and when I combined those two, I got working PS command:

$Base64 = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes([System.IO.File]::ReadAllText("script.ps1")))

Then I can redirect the result to file:

$Base64 > base64Script.txt

from where I just copy the encoded command and paste it here instead of <Base64String>:

powershell.exe -EncodedCommand <Base64String>

and it works without any problem.

Comments

1

Thanks guys for your posts. I took @Frimlik's post and created my own script to automate the process. I hope this helps someone. Save the script to a ps1 file and run it.

Function Get-FileName($initialDirectory)
{
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null    
    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.initialDirectory = $initialDirectory
    $OpenFileDialog.ShowDialog() | Out-Null
    $OpenFileDialog.filename
}

Function EncodePS1ToBat {
    $ScriptToEncode = Get-FileName
    # Encode the script into the variable $Base64
    $Base64 = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes([System.IO.File]::ReadAllText($ScriptToEncode)))

    # Get the path and name to be used as output
    $filePath = Split-Path $ScriptToEncode -Parent
    $fileName = (Split-Path $ScriptToEncode -Leaf).Split(".")[0]

    # Output the encoded script into a batch file on the same directory of the origial script
    "@echo off`n powershell.exe -ExecutionPolicy Bypass -EncodedCommand  $Base64"  | 
    Out-File -FilePath "$filePath\$fileName`_Encoded.bat" -Force -Encoding ascii
}
# Call the funtion to encode the script to a batch file
EncodePS1ToBat

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.