The Script Packager is a feature of the Admin Script Editor which allows you to bundle your scripts and any dependant files in a single executable for easy distribution. Further, you can set your script to run with alternate credentials and even leverage Windows file security features to protect your script's code from the user runing it. Read more about this feature and see an introduction video here.
Due to the fact that the feature is not simple to use until understood, it was not included in the trial version of the application. Below are answers to many frequently asked questions about the Script Packager:
Are packaged script passwords encrypted?
When you supply alternate credentials in the package settings, this is not placed in your script or available in text. The information is encrypted within the packaged executable (in fact the entire executable is encrypted).
If you are placing a name and password within your script, you may be safe too. I you are using alternate credentials the package executes the script and any additional files are extracted to the temp directory which is secured with EFS and NTFS (both optional but enabled by default) so that user still cannot view the code or any additional files extracted during execution.
How do I handle passing command line arguments to packaged scripts?
Because the script is not being run directly, objects like WScript.Arguments.Count will not work with packaged scripts. Packaged scripts store the command line used to execute them in an environment variable named %ASEEXEARGS%. This is a simple string which you may look to in your script to take action based on command line arguments passed to the executable.
$Args = Get-Content env:ASEEXEARGS
Write-Output("Args passed to indicate reboot request")
Set objShell = CreateObject("WScript.Shell")
Set objEnv = objShell.Environment("Process")
strPath = objEnv("ASEEXEARGS")
If Instr(strPath,"-reboot") Then
wscript.write ("Args passed to indicate reboot request")
Note: the ASE environment variables only exist while a packaged script is running, if you attempt to reference these variables in your code outside of a packaged script (such as running from ASE) these variables will not exist. To check for this condition programmatically, you can look at %ISEXE% to determine if the script is running as a packaged executable; if set to "1" you can assume the documented ASE variables will exist and may be referenced by your code.
What kind of security is provided to protect my script code?
The Script Packager™ was designed with security in mind...
Files in the executable package are encrypted.
On Windows 2000 and later systems, during execution files are placed in a specified directory that is restricted through use of Access Control Lists (ACLs) on NTFS drives. Additionally, the Windows Encrypted File System (EFS) is utilized to further protect files in this access restricted folder. After execution, these files and folders are removed.
On Windows 2000 and later systems, you may specify that the packages script is to be run with the credentials of an alternate user account.
Selling Scripts or Securing Scripts for Delivery Outside A Corporate Network
The EFS encryption is very secure with the caveat that you need to specify an account name and password in order to set the NTFS and EFS security. In other words, for an internal sys admin on a network it is an ideal solution. However, this will not work if you are planning on selling your scripts to customers since the EFS recovery agent for the domain would still be able to access the files while they were decrypted.
I've lost the source for my script but have the packaged executable, How do I extract my script?
Packaged scripts are not actually compiled, they are "packaged" into a self-extracting archive with some additional features and functionality. When a packaged script is run, it extracts itself to a specified location, executes, and then deletes itself. When the script is being run, it is decrypted and extracted in order to execute. This is your opportunity to get at the source files. Normally the location where the package is decompressed is %TEMP%, or specifically, a randomly numeric named subfolder of this location. Often scripts run and end too quickly to access this source so the trick would be to remove the permission to delete from this location.
So if you remove "Delete" permission from %TEMP% and then run the packaged script, it will extract, then run, but then fail to delete itself and you will then be able to browse to %TEMP%\######## (the number signs represent a random number) where you can see the source files.
If alternate credentials were specified when creating the package, it your own access to the files may be restricted. If it was created using alternate credentials with NTFS and/or EFS encryption enabled (they are both enabled by default when specifying alternate credentials) then keep in mind that you won't be able to access the files unless you're actually logged on with the alt credential account OR if your logged on account is an EFS recovery agent for the domain.
How can I hide the command prompt when running a VBScript?
Particularly when you use the ScriptForm Designer to create a graphical interface it can be undesirable to have the standard command prompt window appear when your script runs. To avoid this in a packaged script, change the process in the settings for the packaged script from cscript.exe (console interpreter) to wscript.exe (windows interpreter).
Are there any limitations to what I can specify for my package's filename?
To avoid possible issues with execution, refrain from including special characters in the names of packaged scripts. Because the file name is set as an environment variable value, including characters such as parenthesis can cause issues that prevent the script from successful execution.
My Packaged Script does not appear to run at all, what is going on?
If the script fails to run at all, you will find the reason why in the Windows Event log. On Windows NT and later systems, packaged scripts report success and failure to the Application Log.
If you have a path specified in the Process Name field, the script will fail to execute. This field should contain only the name of the interpreter itself (kix32.exe, cscript.exe, autoit3.exe, etc.)
If addressing network shares and using alternate credentials, specify a UNC path and not a mapped drive letter. The credentials of the specified account will not see mapped drives that belong to the user running the packaged script.
KiXtart and AutoIt Users: If the KiXtart (kix32.exe/wkix32.exe) or AutoIt (autoit3.exe) interpreter is not available on the system running the packaged script (in its %PATH%) you will want to include the interpreter in your package using the Additional Files option of the Script Packager.
Regarding Event Log Error Codes: Due to a lack of an installed messages DLL on client systems (currently not available) you will see some generic text in event log entries prior to the actual error message in the description text. Click here for details or see ASE help.
The following errors are reported if the packaged executable itself encounters a problem during execution:
-1 = packaged script attempted to unpack itself on a network drive (not supported)
-2 = packaged script could not process its configuration information (settings, paths, etc.)
-3 = packaged script executable is corrupt
-4 = packaged script attempted to apply credentials on a FAT volume
-5 = packaged script attempted to apply credentials on system older than Windows 2000
-6 = temporary target folder for script file storage is encrypted
If the package is able to run the script, but an error is returned when attempting to run your script an error of -10 is returned. A second event log entry will provide the Win32 error code that explains the error. If the error text is not included, use the Error Code Lookup utility in ASE to learn its meaning. Additionally, some commonly reported errors and explanations are documented in the ASE help file.
My packaged script runs, but has problems and does not execute as expected, what might be wrong?
The packaged script is simply executing the specified interpreter, and does not change your script in any way. However, because the script is running from a different location than from where the package is executed, referencing other files or utilities using Shell, Run, etc. will need to make use of our special environment variables to address external files.
When running with alternate credentials, the "current user" is that of the user specified for alternate credentials and not the account executing the package. To address the user profile area of the registry it is necessary to use our special environment variable in place of HKEY_CURRENT_USER references.
In both cases, using the "Packaged Executable" script template will provide you with a good start. Below is a quick summary of the environment variables available to ASE packaged executables; for more detail please see the ASE help file.
- %ISEXE% - is equal to "1" if the script is running from within a packaged executable.
- %ASEEXE% - is equal to the full path and filename of the packaged executable being run; use this when referencing files located alongside the packaged executable (do not specify no path, which infers "current directory").
- %ASEEXEPATH% - like ASEEXE, this is equal to the full path of the packaged executable being run, but ends with a backslash and does not include the executable filename in its value.
- %ASESCRIPTPATH% - is equal to the current directory of the executing script (in its temporary location). If you wish to reference files included with your package with the "Additional Files" feature, use this variable to specify their path for Shell/Run operations.
- %ASEEXEARGS% - equal to any arguments passed to the packaged executable when it was launched
- %ASEHKCU% - use this in place of HKEY_CURRENT_USER when using the "Alternate Credentials" feature of the Script Packager. HKCU points to the registry of the specified alternate account credentials. Using %ASEHKCU% will reference the registry of the user executing the packaged executable (HKEY_USERS\).
Note: ASEEXEPATH and ASESCRIPTPATH both end with a backslash (careful not to include an additional backslash in your strings!)
Be sure to expand environment variables as needed. In KiXtart, using an environment variable in a string expands it to its value by default. In VBScript the following method may be used:
Set oShell = CreateObject("WScript.Shell")
sBatPath = oShell.ExpandEnvironmentStrings("%ASESCRIPTPATH%")
oShell.Run sBatPath & "MyIncludedFile.exe"
Why might I not able to read the registry values I write on 64 bit systems when my script is packaged?
I am writing a tool that uses the registry as storage for all needed data. I am not able to read them out with the script is packaged but works fine with just the native vbscript.
amreglocation = "HKLM\Software\SAM"
logpath = WshShell.Regread(amreglocation & "\General\LogPath")
domainname = WshShell.Regread(amreglocation & "\General\DomainName")
accountdomain = WshShell.Regread(amreglocation & "\General\AccountDomain")
It is always a good idea to add some checking to see if your script sees the subkey expected before making use of values. However, this situation may be experienced if you are running a script packaged for 32bit on a 64bit system. On 64bit systems there is a separate registry node which would not be seen by a script executed as 32bit. When running natively with cscript, the adjustment is made automatically by the system. However, when packaging a script for 64bit systems, you'll need to create a 64bit package specifically.
One workaround that has been reported is to export your registry keys, edit them and then import them to the WOW6432Node.
Packaged scripts configured to run as 64bit packages may return error 216 (Failed to execute process in the context of the current user). When running packages on 32bit systems, be sure to have them set 32bit packages, or if size is not a concern to "autodetect".
What are some reasons I might see Error Code 2 when running my packaged script?
f you see the error "Failed to execute process. Error code 2" it usually means a dependency required to run your script is not available on the system where the packaged script is being executed. For example if your script is a KiXtart script, it requires KiX32.exe (or wKiX32.exe). There are a number of ways you can make this available on target systems:
1) Include KiX32.exe in a packaged script using the "Additional Files" feature.
2) In the additional files section of the ScriptPackager, check the box to automatically include the script interpreter (for KiXtart and AutoIt only, VBS and PS require installation).
3) Copy the file to the path on each target system. To automate this you might use a batch file that copies KiX32 to the system32 directory on systems where it is not found before executing. This is most common, but KiX32 can be placed in any directory listed in the target systems %PATH% variable.
Note: placing Kix32.exe in the same directory as a packaged executable will not work; packaged scripts are run in a subdirectory of %TEMP% and not in the same location as the packaged executable script.
4) If you are not using a packaged executable, you may place KiX32 on a network share such as NETLOGON and specify this as the location of KiX32 in any calls made to initiate the script.
There are certainly other ways to address this situation, but above are some comon solutions we have provided with ASE specifically as well as some general best practices.
Why might my packaged script unexpectedly cause a UAC prompt?
The fact that a script is packaged alone will not cause a UAC prompt. The most common cause for this behavior is in the chosen file name for the packaged executable. Any file containing some or all of the keywords "Install" or "Setup" will result in a UAC prompt as designed by Microsoft.