Often, I use .xml or .ini files to store settings that a PowerShell script uses. When I distribute my scripts to end users, sometimes, I want to make sure users cannot manually view or change the content of these config files.
Below is what I did to achieve the goal:
- Create a password protected zip file that contains the config file (.xml or .ini).
- rename the zip file from xxxxxx.zip to xxxxxx.bin
- In powershell script, use ICSharpCode.SharpZipLib.dll to unzip renamed zip file
- compile powershell script to exe so users cannot view the script to figure out the zip file password.
- read the content of the extracted config file
- delete extracted config file
To compile the powershell script, I can use one of these tools:
Below is a sample Powershell script (Zip-Test.PS1) I have written to read a xml file inside a renamed zip file:
$ziplib = Join-Path $FilePath "ICSharpCode.SharpZipLib.dll"
[System.Reflection.Assembly]::LoadFrom("$ziplib") | Out-Null
$ZipName = "Health-Check.bin"
$XmlName = "Health-Check.xml"
$xmlPath = Join-Path $FilePath $XmlName
$ZipPath = Join-Path $FilePath $ZipName
$objZip = New-Object ICSharpCode.SharpZipLib.Zip.FastZip
$objZip.Password = "password"
$objzip.ExtractZip($ZipPath, $FilePath, $XmlName)
if ((Test-Path $xmlPath))
$xml = (get-content $xmlPath)
Remove-Item $xmlPath -Force
The script extracts and reads the health-check.xml file and deletes health-check.xml straightaway, it happens so fast, it won’t be possible for end users to access the file. Below is the output from above sample code (content of my XML file):
One thing to keep in mind: in most of my scripts, I use
$thisScript = Split-Path $myInvocation.MyCommand.Path -Leaf
$scriptRoot = Split-Path (Resolve-Path $myInvocation.MyCommand.Path)
To determine the script name and location. $MyInvocation does not work anymore after I converted the Powershell script to EXE. Therefore, from my above example, I’m actually passing the directory location into the script as a parameter.