Integrating custom Software
The installation of software using opsi is managed either by the Client Agent or the setup program opsi-script. When packaging your own software for deployment through opsi, it’s necessary to create an opsi-script
script for each product. This script, along with the installation files and metadata, should be packed. As a result, you’ll get an opsi product which is then installed on the opsi server (see the chapter Adding Products (opsi Server)).
Tutorial: Creating an opsi-script Script
This tutorial serves as an introductory guide and should not be considered a complete substitute for formal training or a thorough study of the manuals. For more in-depth learning and resources, we recommend the following:
-
Training:
uib GmbH offers comprehensive opsi training courses in Mainz, on-site at your location, or online:
https://www.uib.de/en/training/opsi-training -
Manuals:
-
We provide a range of manuals in both German and English for different versions of opsi:
https://docs.opsi.org/ -
For this tutorial, the opsi-script chapter is particularly useful.
-
-
Blog:
Read the latest news about opsi, announcements, release notes, tips and tricks in our blog:
https://opsi.org/en/blog/ -
Wiki:
You can find our opsi Wiki here: https://wiki.opsi.org/ -
Support Forum:
The opsi forum (community support, announcements and news) can be found here: https://forum.opsi.org
Non-interactive software installation (Windows)
Basically, there are three different ways to integrate a software package into the automatic software distribution for Windows operating systems. Additionally, there’s a variant that uses the Windows Installer service:
-
Unattended/Silent Setup:
This approach involves using the original setup program and configuring it for non-interactive mode via command line parameters. A notable example is the silent installation of an MSI package using the/quiet
option of the msiexec tool. -
Interactive Setup with recorded Answers:
Begin by running the original setup program once to observe the window titles and the sequence of questions and responses during the setup. Record these details in a script. During software distribution, an automation tool such as AutoIt or AutoHotkey interacts with the setup program as dictated by the script. -
Recreate Setup Routine with
opsi-script
:
While the original setup program is active, use a tool like Process Monitor/Procmon to log all system changes. You then craft theopsi-script
script based on the logged data and the changes you’ve recorded.
opsi supports all three variants. In practice, a combination of several methods is often used. |
Structure of an opsi-script Script
The following sections will detail the key components of an opsi-script
script tailored for Windows computers. As an illustration, here is an example of a basic opsi-script
script:
[Actions]
WinBatch_tightvnc_silent_install
[WinBatch_tightvnc_silent_install]
"%ScriptPath%\tightvnc-1.3.9-setup.exe" /silent
An opsi-script
script is structured into two main types of sections: primary and secondary sections. Similar to INI files, each section is introduced by its name enclosed in square brackets.
The core activities of software installation are carried out in the secondary sections, which are invoked by the primary sections. Each secondary section is designated for specific topics and follows a unique syntax: the section name starts with the type, followed by a user-defined name.
In the provided example, the primary section [Actions]
triggers the secondary section [WinBatch_tightvnc_silent_install]
; this section belongs to the WinBatch
type. The contents of a WinBatch
section are executed using the Windows API. Here, the msiexec
tool is employed to install (/i
) the 64 bit version of TightVNC silently (using the /quiet
option). The /norestart
option is included to prevent the computer from rebooting after the installation, which is a specific requirement for TightVNC.
Primary Sections
-
Actions: The
[Actions]
section is essentially the main program, marking the commencement of script processing. -
Sub-Sections: Sections of the program required to be executed multiple times can be organized into sub-sections. These sub-sections can also be externalized into separate files for ease of use and reference.
The primary sections, which function as the main programs, dictate the script’s flow. In these sections, you can use variables, conditional statements, functions, and other programming constructs. For more detailed information on these elements, please refer to the section Important Commands for Primary Sections.
Secondary Sections
-
Files: For file operations, such as
-
Copying (with version control, recursive, etc.)
-
Deleting
-
Creating directories
-
etc.
-
-
WinBatch: For executing through the Windows API. Typically, setup programs are run in a non-interactive mode within these sections.
-
ShellScript: This section’s content is executed by the operating system’s standard shell. For Windows, this shell is
cmd.exe
, whereas for Linux and macOS, it’s typicallybash
. So, this is the place to put regular batch scripts. -
ExecWith: The content of this section is passed on to an external program (like an interpreter) for execution. For instance,
ExecWith
is used to integrate AutoIt scripts into theopsi-script
script. -
Registry: These sections contain specific instructions for modifying the Windows registry.
-
LinkFolder: These sections are used to create or delete shortcuts, such as those on the desktop or in the start menu.
Global constants
opsi-script
also supports the use of global constants. These constants act as placeholders and you can use them in primary and secondary sections. By employing global constants, you can ensure that paths are correctly set across various environments, such as systems with different languages or operating system versions.
Below are some examples of global constants:
-
%ProgramFiles64Dir%:
c:\program files
at 64 Bit -
%ProgramFiles32Dir%:
c:\program files (x86)
at 64 Bit -
%SystemRoot%:
c:\windows
-
%System%:
c:\windows\system32
-
%opsiTmpDir%:
c:\opsi.org\tmp
-
%ScriptPath%: <path to running script>
Example: installing TightVNC
In order to illustrate this concept, let’s consider another example script. For installing the program, a silent execution of setup.exe
in the secondary section WinBatch_tightvnc_silent_install
would typically suffice. However, if the installation is repeated, an interactive dialog will appear (because of a running service). In such cases, AutoIt can be used to automatically close the dialog box:
[Actions]
Message "Installing tightvnc 1.3.9 ..."
ExecWith_autoit_confirm "%ScriptPath%\autoit3.exe" WINST /letThemGo
WinBatch_tightvnc_silent_install
KillTask "autoit3.exe"
[WinBatch_tightvnc_silent_install]
"%ScriptPath%\tightvnc-1.3.9-setup.exe" /silent
[ExecWith_autoit_confirm]
; Wait for the confirm dialog which only appears if tightvnc was installed before as service
; Waiting for the window to appear
WinWait("Confirm")
; Activate (move focus to) window
WinActivate("Confirm")
; Choose answer no
Send("N")
More details on using AutoIt with opsi you will find here:
Automated Answers for the setup program.
Important Commands for Primary Sections
The next sections provide a concise overview of the fundamental commands used in primary sections of opsi-script
scripts. This includes the use of variables, statements, conditional statements, functions, and more. For a comprehensive reference and detailed explanations, please refer to the opsi-script chapter.
String Variables
- Variable Declaration
-
DefVar <variable name> [= <initial value>]
- Variable Assignment
-
Set <variable name> = <value>
In the following example, a variable $ProductId$
is declared and assigned the value "firefox"
:
DefVar $ProductId$
Set $ProductId$ = "firefox"
Alternatively, it’s shorter to write:
DefVar $ProductId$ = "firefox"
The handling of string variables differs between primary and secondary sections. In primary sections, string variables are treated as independent objects. However, in secondary sections, they are replaced by the content of the variable before the section is executed. This distinction is crucial, especially when copying and pasting string expressions within the script. |
Consequently, string variables can only be declared and assigned values in primary sections. When combining variables and strings into a string expression, the operator "+"
is required:
"Installing "+ $ProductId$ +" ..."
In secondary sections, string variables are replaced by the content of the variable before the section is executed:
"Installing $ProductId$ ..."
This has the advantage that you can easily work with opsi-script
variables in sections that are executed outside the script (ExecWith
, ShellScript
).
Statements: Message and ShowBitmap
To display text during installation, use the command Message <string>
. Here, substitute <string>
with the specific text message you wish to show:
Message "Installing "+ $ProductId$ +" ..."
Instead of text messages, you can also display graphics using the ShowBitmap
statement. The images should be in BMP, JPG, or PNG formats, ideally sized at 160 x 160 pixels. Additionally, you can include a caption with the subtitle
parameter:
ShowBitmap "%ScriptPath%\python.png" "Python"
Conditional Statements: if, elseif/else, and endif
You can conditionally execute code based on specific criteria:
-
if
: This initiates the conditional statement. If the specified condition is true, the script executes the instructions within the subsequent block. If the condition is false, the block is bypassed. -
;statement(s)
: These are the instructions executed when the condition in theif
statement is true. This block can contain one or multiple statements that run only if the specified condition is met. -
elseif <condition>
: This is an optional part. If the condition in theif
statement isn’t met, this condition is then evaluated. If it’s true, the script executes the instructions in the subsequent block. It allows for additional, sequential conditions to be checked if earlier conditions aren’t fulfilled. -
else
: This optional section executes if all the preceding conditions are false. It acts as a fallback, containing instructions that run when none of the previous conditions are met. -
endif
: This marks the end of the conditional structure, indicating the conclusion of the conditional checks.
if <condition>
;statement(s)
[elseif <condition>
;statement(s)]
[
else
;statement(s)
]
endif
Functions
-
HasMinimumSpace: Checks for free space on the hard disk.
-
FileExists: Checks if a file or directory exists.
Comments, Errors and Logging
-
Comment Marker: Lines starting with a semicolon (
;
) are not interpreted. -
Comment: Writes a comment to the logfile.
-
LogError: Writes an error message to the logfile.
-
IsFatalError: Cancels the execution of the running script and reports the installation as failed.
Condition for Execution
-
requiredOpsiscriptVersion: This specifies the minimum version of
opsi-script
that is required for the script to function properly:
requiredOpsiscriptVersion >= "4.12.3.6"
Other important opsi-script Functions
-
String Lists: String lists are quite powerful and particularly useful for processing output from external programs (refer to the section Processing String Lists for more details).
-
Function
ExitWindows
: This function is used to restart or shut down the system and exitopsi-script
.-
ExitWindows /Reboot
: Triggers a system reboot upon completion of the script. -
ExitWindows /ImmediateReboot
: Executes an immediate system reboot. -
ExitWindows /ImmediateLogout
: Immediately terminates script processing and exitsopsi-script
.
-
-
Product Properties: Certain products may require the configuration of options, which are evaluated on a client-specific basis at runtime (see section Creating opsi Products for more information).
Access to the property values is provided through the GetProductProperty
function:
if GetProductProperty("example-property", "no") = "yes"
Files_copy_extra_files
endif
-
Encoding: Use UTF-8 encoding in your scripts and place the instruction at the beginning of the file:
encoding=utf8
Special Commands for Windows
-
GetOS
: This function retrieves the operating system type. It returns values such asLinux
,Windows_NT
(covering Windows NT through Windows 11), ormacOS
. -
GetMsVersionInfo
: This function provides detailed information about the internal Windows version. For instance, Windows 7 is identified as "6.1", while Windows 11 is recognized as "10.0", etc. -
GetMsVersionName
: This function returns the commercial version name of a Windows system. For example, Windows 7 returns "7.0", and Windows 11 returns "11.0", and so on. -
getMSVersionMap
: This function locally queries the operating system information and records it into a string list.
For more comprehensive details about these string functions, refer to the section String Functions which return the OS Type. |
Example: Windows Template opsi-template
You can create this template with the opsi-setup-detector
tool (see the section opsi-setup-detector: Creating a Script).
Scripts created by opsi-setup-detector using the template channel: 'training'
setup.opsiscript
: Installations-Skript/Script for Installation; ----------------------------------------------------------------
; This is an opsi-script file.
; See https://opsi.org https://uib.de
; This code was originally created by opsi-setup-detector 4.3.1.2
; ----------------------------------------------------------------
encoding=utf8
;here we start
[Actions]
;check if the running opsiscript version is not too old
requiredOpsiscriptVersion >= "4.12.5.0"
;fetch helper libraries
importlib "uib_exitcode.opsiscript"
importlib "osd-lib.opsiscript"
; ----------------------------------------------------------------
comment "retrieve infos from script environment"
; ----------------------------------------------------------------
; the values are found automatically when the script is running
;
DefStringList $productInfos$ = getProductMap
DefVar $ProductId$ = getValue("id", $productInfos$)
DefVar $ProductName$ = getValue("name", $productInfos$)
DefVar $OS$ = GetOS
; the operating system, in which the interpreter is running
; supported values are "Windows_NT", "Linux", "MacOS"
; ----------------------------------------------------------------
comment "put fixed infos into the script (maybe produced by the setup detector maybe manually)"
; ----------------------------------------------------------------
; the values can be manually edited or automatically suggested by the opsi setup detector
;
DefVar $InstallDir$ = "%ProgramFiles32Dir%\<path to the product files>"
; dependent on the installes software it could be
; "%ProgramFiles64Dir% [,,,]
; "%ProgramFilesSysNatives% [,,,]
DefVar $MinimumSpace$ = "5 MB"
DefVar $MsiId$ = "00000"
DefVar $UninstallProgram$ = "uninstall.exe"
DefVar $ExitCode$
DefVar $ErrorString$
DefVar $targetprogram$
set $targetprogram$ = ""
; ---------------------------------------------------------------
comment "inform the user at the PC about product installation"
; ----------------------------------------------------------------
; for a better visual appearance, show some graphic (at most of size 160x160 [px] )
; we set a image path which could be as follows
DefVar $ImagePath$ = "%ScriptPath%\" + $ProductId$ + ".png"
ShowBitmap $ImagePath$ $ProductName$
Message "Installing " + $ProductId$ + " ..."
; ----------------------------------------------------------------
comment "check if the script is adequate to the environment"
; ----------------------------------------------------------------
if not ($OS$ = "Windows_NT")
logError "Installation aborted: wrong OS version: only Windows"
isFatalError "wrong OS"
; Stop process and set installation status to failed
endif
if not(HasMinimumSpace ("%SystemDrive%", $MinimumSpace$))
LogError "Not enough space on %SystemDrive%, " + $MinimumSpace$ + " on drive %SystemDrive% needed for " + $ProductId$
isFatalError "No Space"
; Stop process and set installation status to failed
endif
; ---------------------------------------------------------------
comment "uninstall an existing installation if possible"
; ---------------------------------------------------------------
if FileExists("%ScriptPath%\delinc.opsiinc")
comment "Start uninstall part"
include_insert "%ScriptPath%\delinc.opsiinc"
endif
; show a title for the installation
Message "Installing " + $ProductId$ + " .."
DefVar $installerSourceDir$ = "%SCRIPTPATH%"
; ---------------------------------------------------------------
comment "run the setup program"
; ----------------------------------------------------------------
; the call to the installer is more stable if we set the path
ChangeDirectory $installerSourceDir$
; call the setup program
Winbatch_install
; ---------------------------------------------------------------
comment "check the result"
; ----------------------------------------------------------------
; check the outcome of the call, produce either a "failed" state of the script or log the result
set $ExitCode$ = getlastexitcode
if "true" = isGenericExitcodeFatal($exitcode$, "true", $ErrorString$ )
LogError $ErrorString$
isfatalerror $ErrorString$
else
Comment $ErrorString$
endif
; ---------------------------------------------------------------
comment "do tasks which supplement the installation"
; ----------------------------------------------------------------
;e.g. copy some files
Files_install /sysnative
;e.g. configure some registry entries
Registry_install /sysnative
;e.g.. supplement or remove start menu or desktop links
LinkFolder_install
; ---------------------------------------------------------------
; end of actions section
; ---------------------------------------------------------------
; ---------------------------------------------------------------
; ---------------------------------------------------------------
[Winbatch_install]
; Choose one of the following examples as basis for your installation
; You can use $LicenseKey$ var to pass a license key to the installer
;
; === Nullsoft Scriptable Install System ================================================================
; "%ScriptPath%\Setup.exe" /S
;
; === MSI package =======================================================================================
; You may use the parameter PIDKEY=$Licensekey$
; msiexec /i "%ScriptPath%\some.msi" /l* "%opsiLogDir%\$ProductId$.install_log.txt" /qb-! ALLUSERS=1 REBOOT=ReallySuppress
;
; === InstallShield + MSI=====================================================================================
; Attention: The path to the logfile should not contain any whitespaces
; "%ScriptPath%\setup.exe" /s /v" /l* %opsiLogDir%\$ProductId$.install_log.txt /qb-! ALLUSERS=1 REBOOT=ReallySuppress"
; "%ScriptPath%\setup.exe" /s /v" /qb-! ALLUSERS=1 REBOOT=ReallySuppress"
;
; === InstallShield =====================================================================================
; Create setup.iss answer file by running: setup.exe /r /f1"c:\setup.iss"
; You may use an answer file by the parameter /f1"c:\setup.iss"
; "%ScriptPath%\setup.exe" /s /sms /f2"%opsiLogDir%\$ProductId$.install_log.txt"
;
; === Inno Setup ========================================================================================
; http://unattended.sourceforge.net/InnoSetup_Switches_ExitCodes.html
; You may create setup answer file by: setup.exe /SAVEINF="filename"
; You may use an answer file by the parameter /LOADINF="filename"
; "%ScriptPath%\setup.exe" /sp- /silent /norestart /nocancel /SUPPRESSMSGBOXES
[Files_install]
; Example of recursively copying some files into the installation directory:
;
; copy -s "%ScriptPath%\files\*.*" "$InstallDir$"
[Registry_install]
; Example of setting some values of an registry key:
;
; openkey [HKEY_LOCAL_MACHINE\Software\$ProductId$]
; set "name1" = "some string value"
; set "name2" = REG_DWORD:0001
; set "name3" = REG_BINARY:00 af 99 cd
[LinkFolder_install]
; Example of deleting a folder from AllUsers startmenu:
;
; set_basefolder common_programs
; delete_subfolder $ProductId$
;
; Example of creating a shortcut to the installed exe in AllUsers startmenu:
;
; set_basefolder common_programs
; set_subfolder $ProductId$
;
; set_link
; name: $ProductId$
; target: <path to the program>
; parameters:
; working_dir: $InstallDir$
; icon_file:
; icon_index:
; end_link
;
; Example of creating a shortcut to the installed exe on AllUsers desktop:
;
; set_basefolder common_desktopdirectory
; set_subfolder ""
;
; set_link
; name: $ProductId$
; target: <path to the program>
; parameters: <some_param>
; working_dir: $InstallDir$
; icon_file: <path to icon file>
; icon_index: 2
; end_link
[Winbatch_uninstall]
; Choose one of the following examples as basis for program uninstall
;
; === Nullsoft Scriptable Install System ================================================================
; maybe better called as
; Winbatch_uninstall /WaitforProcessending "Au_.exe" /Timeoutseconds 10
; "$UninstallProgram$" /S
;
; === Inno Setup ========================================================================================
; "$UninstallProgram$" /silent /norestart /SUPPRESSMSGBOXES /nocancel
[Files_uninstall]
del -sf "$InstallDir$\"
[Sub_check_exitcode_generic]
set $ExitCode$ = getlastexitcode
if "true" = isGenericExitcodeFatal($exitcode$, "true", $ErrorString$ )
LogError $ErrorString$
isfatalerror $ErrorString$
else
Comment $ErrorString$
endif
delinc.opsiinc
: Deinstallations-Skript (Include)/Script for Deinstallation (Include); ----------------------------------------------------------------
; This is a opsi-script file.
; See https://opsi.org https://uib.de
; This code was originally created by opsi-setup-detector 4.3.1.2
; ----------------------------------------------------------------
encoding=utf8
Message "Check for existing installation of " + $ProductId$ + " ..."
DefVar $MsiId$ = '{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'
DefVar $UninstallProgram$ = $InstallDir$ + "\uninstall.exe"
; ---------------------------------------------------------------
comment "run the uninstall program"
; ----------------------------------------------------------------
if FileExists($UninstallProgram$)
comment "Uninstall program found, starting uninstall"
Winbatch_uninstall
set $ExitCode$ = getlastexitcode
if "true" = isGenericExitcodeFatal($exitcode$, "true", $ErrorString$ )
LogError $ErrorString$
isfatalerror $ErrorString$
else
Comment $ErrorString$
endif
endif
if not (getRegistryValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" + $MsiId$ , "DisplayName","32bit") = "")
comment "MSI id " + $MsiId$ + " found in registry, starting msiexec to uninstall"
Winbatch_uninstall_msi
set $ExitCode$ = getlastexitcode
if "true" = isMsiExitcodeFatal($exitcode$, "true", $ErrorString$ )
LogError $ErrorString$
isfatalerror $ErrorString$
else
Comment $ErrorString$
endif
endif
comment "Delete files"
if not(($InstallDir$ = '') or ($InstallDir$ = 'unknown'))
Files_uninstall
endif
comment "Cleanup registry"
Registry_uninstall
comment "Delete program shortcuts"
LinkFolder_uninstall
;-----------------------------------------------------
uninstall.opsiscript
: Deinstallations-Skript/Script for Deinstallation; ----------------------------------------------------------------
; This is a opsi-script file.
; See https://opsi.org https://uib.de
; This code was originally created by opsi-setup-detector 4.3.1.2
; ----------------------------------------------------------------
encoding=utf8
;here we start
[Actions]
;check if the running opsiscript version is not too old
requiredOpsiscriptVersion >= "4.12.5.0"
;fetch helper libraries
importlib "uib_exitcode.opsiscript"
importlib "osd-lib.opsiscript"
; ----------------------------------------------------------------
comment "retrieve infos from script environment"
; ----------------------------------------------------------------
; the values are found automatically when the script is running
;
DefStringList $productInfos$ = getProductMap
DefVar $ProductId$ = getValue("id", $productInfos$)
DefVar $ProductName$ = getValue("name", $productInfos$)
DefVar $OS$ = GetOS
; the operating system, in which the interpreter is running
; supported values are "Windows_NT", "Linux", "MacOS"
; ----------------------------------------------------------------
comment "put fixed infos into the script (maybe produced by the setup detector maybe manually)"
; ----------------------------------------------------------------
; the values can be manually edited or automatically suggested by the opsi setup detector
;
DefVar $InstallDir$ = "unknown"
; dependent on the installes software it could be
; "%ProgramFiles64Dir% [,,,]
; "%ProgramFilesSysNatives% [,,,]
DefVar $MinimumSpace$ = "0 MB"
DefVar $MsiId$ = "00000"
DefVar $UninstallProgram$ = "uninstall.exe"
DefVar $targetprogram$
; ---------------------------------------------------------------
comment "inform the user at the PC about product installation"
; ----------------------------------------------------------------
; for a better visual appearance, show some graphic (at most of size 160x160 [px] )
; we set a image path which could be as follows
DefVar $ImagePath$ = "%ScriptPath%\" + $ProductId$ + ".png"
ShowBitmap $ImagePath$ $ProductName$
Message "Uninstalling " + $ProductId$ + " ..."
; ----------------------------------------------------------------
comment "check if the script is adequate to the environment"
; ----------------------------------------------------------------
if not ($OS$ = "Windows_NT")
logError "Installation aborted: wrong OS version: only Windows"
isFatalError "wrong OS"
; Stop process and set installation status to failed
endif
; ---------------------------------------------------------------
comment "uninstall an existing installation if possible"
; ---------------------------------------------------------------
if FileExists("%ScriptPath%\delinc.opsiinc")
comment "Start uninstall part"
include_insert "%ScriptPath%\delinc.opsiinc"
endif
[Winbatch_uninstall]
; Choose one of the following examples as basis for program uninstall
;
; === Nullsoft Scriptable Install System ================================================================
; maybe better called as
; Winbatch_uninstall /WaitforProcessending "Au_.exe" /Timeoutseconds 10
; "$UninstallProgram$" /S
;
; === Inno Setup ========================================================================================
; "$UninstallProgram$" /silent /norestart /SUPPRESSMSGBOXES /nocancel
[Winbatch_uninstall_msi]
msiexec /x $MsiId$ /qb-! REBOOT=ReallySuppress
[Files_uninstall]
; Example for recursively deleting the installation directory:
;
; del -sf "$InstallDir$\"
[Registry_uninstall]
; Example of deleting a registry key:
;
; deletekey [HKEY_LOCAL_MACHINE\Software\$ProductId$]
[LinkFolder_uninstall]
; Example of deleting a folder from AllUsers startmenu:
;
; set_basefolder common_programs
; delete_subfolder $ProductId$
;
; Example of deleting a shortcut from AllUsers desktop:
;
; set_basefolder common_desktopdirectory
; set_subfolder ""
; delete_element $ProductId$
; ----------------------------------------------------------------
; ----------------------------------------------------------------
Creating opsi Products
The following sections outline the steps for packaging software, specifically for creating opsi products. The fundamental process involves:
-
Creating the basic framework of a package using the
opsi-setup-detector
(refer to section opsi-setup-detector: Creating a Script). -
Testing the
opsi-script
script (see section Testing and improving a Script). -
Using the opsi PackageBuilder (oPB) to transform the initial form into a complete opsi package, which is then stored on the opsi server.
Preparation
To create opsi packages, you will require the following tools:
Installing opsi-setup-detector
The opsi-setup-detector
is currently available for Windows, Linux, and macOS. You can install this program directly through opsi. It’s one of the standard localboot products and is typically available on the opsi server. If it’s not already installed, you can deploy the product using the following command:
opsi-package-updater install opsi-setup-detector
The localboot product opsi-setup-detector also requires the installation of the product opsipackagebuilder_wlm , because the setup detector uses the PackageBuilder (if available).
|
You should therefore also install the product opsipackagebuilder_wlm
:
opsi-package-updater install opsipackagebuilder_wlm
You can then deploy the two products to the desired clients, for example, using the opsi-configed
management interface.
For Windows computers, we provide the setup detector as a stand-alone package, which can be installed independently of opsi: https://tools.43.opsi.org/stable/ |
Differences Across Windows, Linux, and macOS
While the opsi-setup-detector
generally operates similarly across Windows, Linux, and macOS, there are distinct differences in how it analyzes installation files, using various auxiliary programs specific to each operating system:
-
On Windows, detailed analyses of Inno Setups are conducted using the integrated tool
innounpack.exe
. Such in-depth analysis of Inno Setups is thus exclusive to the Windows environment. -
For working with the Windows Installer XML (commonly known as the WiX Toolset), the integrated tool
Dark.exe
is employed under Windows. Therefore, this level of detailed analysis is also specific to Windows. -
On Linux systems,
.deb
or.rpm
packages are analyzed using the standard package management tools on Linux. Consequently, this type of detailed analysis is possible only on Linux systems.
Installing opsi PackageBuilder
The opsi PackageBuilder (oPB) is available for Windows, Linux, and macOS.
The product opsipackagebuilder_wlm
is one of the opsi standard products. If it is not yet installed on your server, use this command to install it:
opsi-package-updater install opsipackagebuilder_wlm
You can proceed to deploy the localboot product to the clients, for instance, using the opsi-configed
management interface.
Alternative approach to using the product:
You can install the opsi PackageBuilder (oPB) either as an opsi product on the opsi server and then deploy it to clients via opsi-configed
. Alternatively, you can use one of the installation packages available at forum.opsi.org - opsi PackageBuilder.
The opsi PackageBuilder (oPB) is a community-driven product, developed by Holger Pandel. Many thanks! |
You can find the source code and license details at GitHub: opsi PackageBuilder (oPB).
Installing opsi-logviewer
The opsi-logviewer
is compatible with Windows, Linux, and macOS and is a component of the opsi-configed
management interface.
The opsi-configed
package is one of the standard opsi products and is typically pre-installed on your opsi server. If it’s not already installed, you can do so with this command:
opsi-package-updater install opsi-configed
You can find an executable version of the management interface opsi-configed for Windows, Linux, and macOS on our website at opsi Tools.
|
opsi-setup-detector: Creating a Script
The following sections explain in detail how to use the opsi-setup-detector
to analyze a setup file and create an opsi product.
Start and Condfigurartion
On Windows, you can launch the opsi-setup-detector
from the Start menu, where it is located at opsi.org / opsi-setup-detector. For macOS users, the opsi-setup-detector
can be accessed via Programs, while on Linux, it is typically found in the start menus at System Tools. Additionally, on most Linux desktop environments, you have the option to directly enter the full path to the executable file (/opt/opsi-setup-detector/opsisetupdetector
) in a quick launcher ([Alt]+[F2]) or terminal window.
In Windows, the opsi-setup-detector can be conveniently started directly from the Explorer. By right-clicking on an installation file for an application, you will find an option in the context menu that allows you to initiate the tool for analysis.
|
Upon the initial launch of the program, a configuration dialog will appear. It’s essential to provide information for the following three entries:
-
fullName
: Enter your full name as you wish it to appear in thechangelog.txt
file. -
email_address
: Provide your email address, which will also be included in thechangelog.txt
file. -
workbench_Path
: Specify the path to the directory where you will create the opsi packages.
Ideally, this should be the path to the share where your opsi server’s workbench is mounted (see the chapter Samba).
Additionally, you can configure further (optional) settings. For the opsi web service opsiconfd
(https://<opsi-server>:4447
, see the chapter The opsiconfd Service), you should complete the following fields:
-
Service_URL
: Enter the URL of the opsi web service, formatted ashttps://<opsi-server>:4447
. -
Service_user
: Specify the username required for connecting to the opsi web service. -
Service_pass
: Input the password associated with theService_user
for the web service connection. Skip this, and the theopsi-setup-detector
will prompt for it when necessary.
Possible security risk: Even if the password is stored in encrypted form, it can still be decrypted after analyzing the (open) source code. |
Other optional settings include:
-
control_in_toml_format
: Check this box if you want to create acontrol
file in TOML format (refer to the section Example: control File for more details).
Attention: This option requires at least opsi 4.3! -
dependencies_for_all_actionrequests
: This setting determines whether dependencies should be allowed for action requests other thansetup
.
Attention: This feature requires at least opsi 4.3 and should be used with extreme caution! -
preferMsiUninstall
: If the analyzed file is an wrapper around a MSI file: Should we use the uninstall code for the msi or the uninstall program from the installer ?
For a comprehensive explanation of all the available settings, refer to the chapter [opsi-setup-detector configuration. |
Once the configuration is saved, you will see the start page.
Online Help
Click on the question mark to display the online help.
A click to this question mark icon will open the general or context sensitive online help pages.
Select the task that fits your needs. The dialog offers tasks for Windows, Linux, and macOS, as well as options that are operating system-independent. There is also a dedicated section for packages designed for multi-platform compatibility.
The following tasks are available for Windows:
-
Analyze File and create opsi Package: Starting from a setup file, the entire process is executed until an opsi package is created (see the section Analyze File and Create a Package).
-
Analyze 2 Files (32 / 64 bit) and create O. Package: The procedure is similar, but here two setup programs for the two architectures (32 bit and 64 bit) are queried and analyzed. The product receives an additional property:
install_architecture
(possible values:32bitonly
,64bitonly
,both
, andsystemspecific
). -
Create an opsi Package Template: Doesn’t ask for a setup file, but creates an opsi template product for Windows and takes the information from the product configuration.
-
Analyze File and Create Package 'with user': Similar to Analyze File and create opsi Package, creates the package for an installation with a logged in user (see section opsi_template_with_userlogin). The product receives additional properties:
-
execution_method
, possible values:loginOpsiSetupUser
,runAsOpsiSetupUser
, andrunOpsiScriptAsOpsiSetupUser
. -
boolean properties:
uninstall_before_install
,copy_files_locally
, anddebug
-
-
Create an opsi Package Template 'with user': Doesn’t ask for a setup file, but creates an opsi template product for an installation with a logged in user and takes the information from the product configuration.
Analyzing File & Creating the Package
The following sections describe how to analyze a setup file and create an opsi product from it. To do this, click the Analyze File and Create opsi Package button on the start page (Figure 6, “opsi-setup-detector Start Page”). Then navigate to the desired installer file in the file selection dialog. The opsi-setup-detector
starts the analysis immediately.
Analysis
The opsi-setup-detector
uses his own engine and the tool Detect it Easy (DIE)
for analysis. Files that can be detected based on their file name extension will not be analyzed.
After successfully analyzing a setup file, you will see this dialog:
If the analysis was not successful, you will see this dialog instead:
No installer type could be detected in the selected file.
Now, you have the option to either terminate the process by clicking on Cancel or to proceed with creating the package by selecting an installer type from the drop-down menu.
Or you will see this dialog:
A installer type was detected, but the opsi-setup-detector
has no information how to handle this type.
Now, you have the option to either terminate the process by clicking on Cancel or to proceed with creating the package by selecting an installer type from the drop-down menu.
Should the analysis prove successful, a window might pop up providing additional details about the identified installer type. This informational window is typical for installer types like InstallShield, Qt Installer, or InstallAnywhere.
If the analysis has been successful, the opsi-setup-detector
will display the result:
On the 1. Setup tab, you will find detailed information and various functions as follows:
-
Detected Setup type: Type of installer detected
-
Prefer Silent Install: Activate this checkbox to prefer a silent installation to an unattended installation (if possible).
-
MST allowed: Should additional
mst
files be used to customize the settings for Microsoft Windows Installer (MSI) applications? -
Info: Link with further information about the installer
-
Setup File: Path and name of the analyzed setup file
-
MST File: To specify the MST file to be integrated into the MSI call
-
MsiId: Product code for MSI installers or installers that contain MSI
-
MsiName: Product name for MSI installers or installers that contain MSI; stored in the registry as DisplayName.
-
MsiUpgrade: Upgrade code for MSI installers or installers that contain MSI
-
Software version: Version of the software to be installed (if this can be determined)
-
Setup file size MB: Size of the setup file in MB
-
Required Space MB: Estimated value (size of the setup file times 6), can be adjusted if necessary
-
InstallDir: Directory where the software will be installed, assuming it is correctly identified. If the installation directory is not accurately recognized, you can manually specify the correct directory by clicking the folder icon next to this field to open a file selection dialog. Standard paths like
C:\program Files
orC:\program Files (x86)
are automatically substituted with the relevantopsi-script
constants, such as%ProgramFiles32Dir%
. -
Install Command: This represents the command determined for a non-interactive installation. The specifics of this command vary depending on whether the Prefer Silent Install checkbox is selected.
-
Uninstall Command: The command determined for a non-interactive uninstallation. The specifics of this command vary depending on whether the Prefer Silent Install checkbox is selected.
See also: Configuration: preferMsiUninstall -
Uninstall Program: Program detected for uninstallation; if not detected correctly, you can open a file selection dialog via the folder icon next to the field and navigate to the desired application. MSI files do not (usually) have an uninstall program.
-
Target Program: Main executable of the software being installed. It’s commonly used for creating desktop shortcuts or start menu entries. The main program is not automatically determined. If the software is already installed on the computer, you can select the executable file using the folder icon to open a selection dialog.
After the analysis is complete, any values that have been determined can be adjusted or supplemented as needed. Once you have made any necessary changes, click on the Next Step button to proceed to the first tab of the product configuration.
There is a high probability that the values obtained from the analysis might be incomplete or partially incorrect. After conducting an initial installation, it is crucial to thoroughly review and verify the accuracy of values such as InstallDir, Uninstall Program, Target Program, and Software Version in your script! |
Product Configuration 1
Make the following settings on this tab:
-
opsi Product ID: This is the identifier for the new opsi package, generated from the product name specified in the opsi Product Name field. Spaces and special characters in the product name are replaced with hyphens. You can modify the suggested product ID.
-
Import control File: Click on this button to open a file selection dialog allowing you to import data from an existing
control
file (control, control.toml
) into your current project. Note that information like version numbers, script names, or required disk space is not imported. -
opsi Product Name: This field allows you to correct or adjust the name of the software that is being installed.
-
Product Version: Here, you can correct the version number that was determined from the setup file’s name. It should only include digits and periods, as it is used for the versioning of the opsi package.
-
Package Version: This version number differentiates between opsi products that contain the same software version but may have varying scripts or properties. Like the product version, it should only contain digits and periods.
-
Description: In this field, provide a brief description of the application. With opsi 4.3 and later, this text can be formatted using Markdown. An editing area is provided on the left side and a preview on the right.
-
Advice: Provide extra details about the software, such as its origin, download link, licensing information, etc. Starting with opsi 4.3, this text can be formatted using Markdown. An editing area is provided on the left side and a preview on the right.
-
Template Channel: Choose from the following templates in the drop-down menu to generate the scripts:
-
default: Serves as the standard and fallback option. If another selected template does not provide the necessary files for your project, default will be automatically employed. Key scripts of the product include:
setup.opsiscript
,uninstall.opsiscript
,declarations.opsiinc
,sections.opsiinc
, anddelinc.opsiinc
. -
training: Offers a simple structure with detailed comments; key scripts for the product are
setup.opsiscript
,uninstall.opsiscript
, anddelinc.opsiinc
. -
structured: Defaults to default; not useed in version 4.2.2 and above.
-
custom: Initially empty, this template provides space for your own template files. To use custom templates, copy them to the
opsi-setup-detector/custom/template-files/
directory on the depot server, and then reinstall theopsi-setup-detector
on the relevant clients.
-
At the bottom of the window, there are several checkboxes that allow you to integrate additional code and settings for specific purposes:
-
Support custom directory: This option adds an extra directory named
custom
to the product, which can hold (customer-specific) customizations. When a new version of the package is installed on the server, thiscustom
directory will not be overwritten. The included code provides templates to include files from this directory (see the section Custom Directory). -
Install from local temp dir: With this option, the installation files are initially copied to a local, temporary directory and installed from there. This approach is especially beneficial for components that might disrupt the network connection during installation, such as drivers (see the section Local, temporary Directory).
-
Handle License Key: This option generates an additional property dedicated to managing license keys (see the section License Key).
-
DesktopIcon: This creates an additional boolean property (defaulted to
false
) to manage the creation of desktop icons (see the section Desktop Icon). -
Customize Profile: This option includes a
ProfileActions
section in the code, allowing for customizations in local user profiles. For an in-depth explanation, refer to the section Customize local User Profiles. -
Uninstall_before_install: This creates an additional boolean property (defaulted to
true
) to control if we should uninstall before we try to install. (see section Uninstall_before_install).
Priority and Dependencies
You can define priorities and dependencies more precisely on the Product Configuration 2 tab:
For "standard" application software, it’s usually unnecessary to configure anything in this section, and you can proceed by clicking on Next Step. |
The following settings can be adjusted on this tab:
-
Priority: This setting affects the installation order. Possible values range from 100 (indicating early installation) to -100 (signifying late installation). For application software, a priority of 0 is generally recommended. Note that the installation order can also be influenced by dependencies between products.
-
Dependencies: This area allows you to specify dependencies among products. If your opsi server’s access credentials are saved in the configuration, the tool will attempt to connect to the server. If the password hasn’t been stored for security reasons, a password prompt will appear at this stage (see the section Defining Dependencies).
-
Properties: Here you can define variable properties of the producti (see the section Defining Propertys).
Defining Dependencies
Click the button Add Dependency to open the Depency Editor:
Here you can make the following settings:
-
create dependency for which action request: The default selection here is setup. Starting with opsi 4.3, other action requests are also supported, including
uninstall
,update
,always
,custom
, andonce
. Exercise caution with this setting to avoid creating unsolvable or contradictory conditions!
This drop-down menu is only active if the dependencies_for_all_actionrequests option has been enabled in the opsi-setup-detector configuration (refer to section Start and Condfigurartion for more details).
|
-
productid of the dependent product: Through the drop-down menu, you can select the product that has a dependency. If there’s an active connection to the opsi server, the dialog will indicate this in green and will list the installed products. If the connection is not established, a red message will appear, and you’ll need to manually enter the product ID.
-
Require Mode: This setting is disabled when creating a meta product to prevent illogical configurations. There are two selectable options in this area:
-
Action: This option requests an ActionRequest (like setup) to be set for the product with which there is a dependency.
-
State: This refers to the product’s state that has a dependency (such as installed). If the status is different, the product is set to setup.
-
The actual order of installation is determined by a combination of the dependencies and the priority assigned to the products (see the section Dependencies and Order). |
Defining Propertys
On the Product Configuration 2 tab, you can define modifiable properties (variables) for the product. To do this, simply click on the Add Property button:
Field/Function | Description | Notes |
---|---|---|
Property Name |
Name of the product variable |
Displayed as an identifier in the |
Property Type |
Type of the variable |
Possible values are Text and Boolean. |
Multivalue |
Number of values |
Determines whether the variable can take exactly one or multiple values; available only for Text type. |
Editable |
Values can be overwritten |
Specifies whether the default values can be overwritten with new or additional values or not; available only for Text type. |
Possible Values |
Input values |
A comma-separated list of possible input values. If set to True, you can later add to this list in |
Default Values |
Default value |
For Text type: a free text field. For Multivalue type: a multiple-choice selection. |
Selecting Product Icon
On this tab, you can select an icon for the product that will be displayed during installation:
Should you decide to skip this optional step, the opsi-setup-detector will default to selecting an icon with gears and automatically proceed to the next tab.
|
To select a different icon, click on the open icon folder button located on the right side of the windowi to open a selection dialog where you can navigate to the folder containing your preferred icons. Initially, you will be directed to the 128x128 folder, which includes a variety of icons provided with the opsi-setup-detector
under a free license. Once you open this folder, all available icons will be displayed on the left side of the window, allowing you to choose one for your product.
Creating the Product
After you have finished configuring the product, you can proceed to create it using the options provided on the last tab.
The following options are available on this tab:
-
Path to opsi-work-bench: Displays the directory you configured during setup for the workbench share on your opsi server. This can be either a drive letter or a UNC path.
-
Check workbench path button: Use this to verify whether the workbench share is accessible.
-
Create mode: Choose how the package should be created:
-
create opsi product files: This option will create (if not already existing) the directory structure for the new opsi product on the workbench. It also generates or copies the necessary files for the package.
-
create opsi product files and build package: In addition to creating the directory structure, this option attempts to build the package on the opsi server. If the build and install checkbox is selected in the Build Mode area on the right, the product will be installed on the server after being built. If the connection to the opsi web service is configured, the service is contacted, and if necessary, it will prompt for the password.
-
The building and installation process via the web service only works if the opsiconfd is of version 4.2.0.287 or newer. If the service is either unavailable or outdated, the opsi PackageBuilder (non-GUI version) will step in to create the package.
|
-
create opsi product files and start the interactive PackageBuilder creates the directory tree for the new opsi product (if it doesn’t exist on the workbench) and starts the opsi PackageBuilder in an interactive mode. You need to exit this application explicitly to return to the
opsi-setup-detector
.-
Build Mode: There are two options here, which define the actions performed when you select Create opsi Package:
-
-
build: This option solely creates the opsi package, similar to the
opsi-makepackage
command. -
build and install: This option not only creates the opsi package (
opsi-makepackage
) but also installs it, equivalent to the commandopsi-package-manager --install <package>
.-
Create opsi Package: Click on this button to start the build process. If there is an opsi product with the same name, you will see the following dialog:
-
-
Rebuild Package only: This button initiates the building of the opsi package without re-generating the opsi files first. Hence, it’s a convenient option for rebuilding a package after making modifications to the script in an external editor.
During the creation of the opsi product, the opsi-setup-detector
records all the information you’ve entered into a file named opsi-project.osd
, located in the root directory of the product.
At a later stage, you can reopen an opsi-project.osd file with the opsi-setup-detector if you need to make adjustments to an already existing package.
|
Opening an existing Project
To open an existing project structure as a project with the opsi-setup-detector
, there are two approaches:
-
For products created with the
opsi-setup-detector
: Navigate to the File menu, then select Open, and select theopsi-project.osd
file located in the root directory of the project. -
For products not created with the
opsi-setup-detector
: Open thecontrol
file (eithercontrol
orcontrol.toml
) via the menu entry File / Open Control File. It’s located in theOPSI
directory of the product.
The second method provides less comprehensive information, particularly regarding the setup file used by the installer.
Testing and improving a Script
There are two distinct methods for testing and enhancing a product:
-
Test the script you’ve developed without installing it on the opsi server or deploying it to a client (Standalone Tests).
-
Evaluate the entire product by installing it on the server and deploying it to a client (Integrated tests).
The instructions that follow are based on the assumption that the product you are testing was created using the opsi-setup-detector .
|
Standalone Tests
Start the application opsi-script-gui
:
-
Windows: Double-click to open
opsi-script.exe
. If the client agent is installed on your computer, locate the program at C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-script\opsi-script.exe. Otherwise, manually copy the contents of theopsi-script\windows\x86\
directory from the\\<opsiserver>\opsi_depot
share to your Windows computer.
On Windows 10, you should right-click the opsi-script.exe file in Explorer and choose Run as administrator from the context menu.
|
-
Linux: Start
/opt/opsi-script/opsi-script-gui
. -
macOS: Launch the application via the /Applications/opsi-script menu.
Upon starting the application, you will be presented with the following window:
Use Select Script to choose the script you’re looking to test. Next, click Start to execute the script on your computer. Alternatively, for a syntax check, select Test_Syntax. This action checks the script for syntax errors but does not run it on your computer (see the section Checking the Script Syntax).
To observe how opsi-script
interprets the script, you can use the opsi-logviewer
.
Adjust the log level using the slider in the bottom right corner of the opsi-logviewer to display more or fewer details.
|
If you need to modify the script, you have a couple of options for editing:
-
Open the project in the opsi PackageBuilder and use the editor provided there.
-
Alternatively, use a text editor like jEdit that supports
opsi-script
syntax highlighting. This feature is typically included in the basic setup of the opsi products.
Now, you can save the changes and keep the editor open. Simply switch back to the opsi-script window and click on the Start button again; there’s no need to reselect the script. To observe the modifications, refer to the opsi-logviewer
. You can refresh the log by choosing Reload from the right-click context menu or by clicking the reload button on the toolbar.
To fine-tune your scripts to perfection, you can repeat these steps as needed:
-
Edit and save the script in your text editor.
-
Run the script (again) in
opsi-script
. -
Check the updated logs to confirm the impact of your changes.
Integrated tests
For the integrated tests, roll out the product on a test client:
-
Open the script
setup.opsiscript
in an editor and make changes if necessary; save the changes:-
Open the project in opsi PackageBuilder and start the editor provided here.
-
Use a text editor such as jEdit with
opsi-script
syntax highlighting (included in the basic setup of the opsi products).
-
-
Build the product:
-
Variant 1: Open the project in opsi PackageBuilder and click on the Build button.
-
Option 2: Open a terminal on the opsi server or log in via SSH, e.g. with PuTTY. Switch to the workbench (
/var/lib/opsi/workbench
) and then to the project directory. Call the following command:
opsi-makepackage
-
-
Install the product on the opsi server:
-
Variant 1: Click on the Install button in the opsi PackageBuilder.
-
Variant 2: Run the following command in the project directory in the terminal:
opsi-package-manager -i <myproctid_version.opsi>
Replace<myproctid_version.opsi>
with the name of the opsi package (as it was output during the build process).
-
-
Deploy the product via the
opsi-configed
management interface:-
Select the test client on the Clients tab.
-
Select the product on the Localboot products tab. If your opsi package does not appear there (which is normal after the first installation), press the button on the very left of the toolbar or select File / Reload all data from the menu.
-
Set the product to setup and save the changes.
-
Start the client or call up on_demand from the context menu for running clients.
-
Wait until the product has been installed on the client.
-
Switch to the Logfiles tab and then to instlog and view the log file.
-
Adjust the log level using the slider in the bottom right corner to display more or fewer details. |
To further customize your scripts, you can repeat these steps:
-
Edit the script in the editor and save your changes.
-
Build the product.
-
Install the product on the server.
-
Deploy the product on the client.
-
Check the log file.
opsi PackageBuilder: Modifying a Script
Launch the opsi PackageBuilder (oPB) from the start menu. If you encounter difficulties (particularly when using a KDE desktop environment), you might need to start the program from a terminal instead. Simply input any path, and if an error message appears indicating that the path was not found, acknowledge it to proceed:
opsipackagebuilder --path /home
When you start opsi PackageBuilder for the first time, it will be in offline mode because it hasn’t yet established a connection with the opsi server:
Initial Configuration
To set up the opsi PackageBuilder, click on the Settings button.
Configure the following on the General tab:
-
Config server: Input the fully qualified domain name (FQDN) of your opsi config server, such as
opsi.mycompany.org
. -
opsiadmin User: Enter the username of an administrator with access to the opsi service. This account should be a part of the
opsiadmin
group (refer to the section Users and Groups). -
opsiadmin Password: Provide the corresponding password for the opsiadmin user. This password will be encrypted and is not visible. It’s essential for the opsi PackageBuilder to communicate with the opsi server.
-
4.0.4 or newer: Activate this checkbox.
-
SUDO without password: This is the default setting; accept it as it is.
-
Package maintainer: Enter your full name. This will be included in the changelogs.
-
Mail address: Provide your email address here; it will also be featured in the changelogs.
On the Program tab, configure the following settings:
-
Activate the checkbox Extended changelog editor.
-
Select a Development folder; enter the full path to the directory in which the opsi packages are to be created. Ideally, this is the path to the mounted share with the opsi workbench. Optionally, you can select Use existing network drive.
-
Script eEditor: Choose the text editor for script editing according to your operating system:
-
Windows: Accept the default setting (path to the oPB ScriptEditor).
-
Linux: Path to the editor, e.g.
/usr/bin/jedit
; leave the Editor command line options field empty. -
macOS: Path to the editor, e.g.
/Application/jedit
; Editor command line options field remains empty.
-
On the opsi Commands tab, adjust the following setting, which deviates from the default configuration:
-
Build command: We recommend the following command:
opsi-makepackage -v
-
Activate the checkbox Use depot functions.
Save the settings and restart the opsi PackageBuilder. After restarting, the program should switch to online mode.
Modifying, packing and installing packages
To edit a package, select the Open Package (F2) button and locate the directory created by the opsi-setup-detector
, for instance, w:\develop\newprod2
. This action will open the following dialog:
On the Package tab, the metadata of the opsi product is displayed in the left column (refer to section Product Configuration 1 for details). Script files are situated on the right. Next to each script file, you will find this button:
When you click on this button, the script editor specified in the settings will launch, allowing you to modify the script. On Windows, this typically defaults to the oPB-ScriptEditor. This editor comes equipped with features like colored syntax highlighting, optional source code folding (for a more compact view with comments), customizable lexer definition (accessible when launched from the start menu), auto-completion for syntax elements and variables, as well as customizable and reusable code blocks known as snippets.
The editor’s core component is the Scintilla module, which is also used by other renowned text editors like Notepad\++, CodeLite, etc. However, the lexical elements for opsi scripts, such as syntax highlighting and folding, are implemented using AutoIt. This is because Scintilla does not inherently provide specific highlighting for opsi scripts. Since AutoIt is an interpreter language, the ScriptEditor might not be as fast as other editors, particularly when editing very large scripts or with code folding activated.
The settings provide an option to enable or disable these functions when the editor is initiated via oPB. By default, syntax highlighting and folding are turned off when the editor is started from the start menu. However, you can activate them via the View menu if needed.
Launch the editor from the command line to access specific options directly. The --help option displays information about available parameters.
|
On the Dependencies tab, the dependencies established with other opsi products are displayed, as detailed in the section Priority and Dependencies.
The Properties tab shows the product properties, including type, value, etc:
At the bottom of the window, you can see the following buttons:
Button | Description |
---|---|
Starts an SSH connection to the opsi server and executes the command for packaging (see section opsi-makepackage: Packaging the Product). |
|
Starts an SSH connection to the opsi server and executes the install command (see section opsi-package-manager: Installing the Product). |
|
Similar to Install, but the package is also set to setup on all clients on which it is marked as installed. |
Be very cautious when using the Inst.+Setup button. Only use it when you’re certain of its function and implications! |
opsi-makepackage: Packaging the Product
To package the product, navigate to the product’s main directory and execute the command opsi-makepackage
.
It’s a good practice to generate an accompanying MD5 checksum file. Tools like opsi-package-updater use this file to verify the package’s integrity post-transfer.
|
By default, opsi-makepackage
automatically creates an MD5 checksum file. Should you wish to disable this feature, use the following parameter when executing the command:
opsi-makepackage --no-md5
When transferring packages to opsi depot servers, opsi-makepackage
uses the zsync
tool, which only transmits the differing parts of packages, thereby conserving bandwidth. This process needs a .zsync
file, which opsi-makepackage
automatically generates. To turn off this functionality, disable the feature using the following parameter:
opsi-makepackage --no-zsync
If you encounter storage issues in the /tmp
temporary directory while creating large packages, you can define an alternative temporary directory using --temp-directory
.
Additionally, before building a package, opsi-makepackage
examines if a package with an identical name or version number already resides in the directory. Should this occur, the tool will prompt you for your preferred course of action:
Package file '/var/lib/opsi/workbench/mytest/mytest_3.14-1.opsi' already exists.
Press <O> to overwrite, <C> to abort or <N> to specify a new version:
Press [O] to overwrite the existing package, press [C] to halt the process, or opt for [N] to provide a fresh version number for the product or package.
More details about the opsi-makepackage tool and its various options are available in the section opsi-makepackage.
|
opsi-package-manager: Installing the Product
To install opsi products, use the opsi-package-manager
command. First, navigate to the main directory of the product and execute the following command:
opsi-package-manager -i <myproductid_version.opsi>
For additional details about the opsi-package-manager tool and its parameters, refer to section opsi-package-manager.
|
Example: control File
Since opsi 4.3, you can create a control
file in TOML format. If such a control.toml
file exists, it is considered the definitive source and should be properly maintained.
[Package]
version: 1
depends:
[Product]
type: localboot
id: mytest
name: My Test
description: A test product
advice:
version: 3.14
priority: 0
licenseRequired: False
productClasses:
setupScript: setup.opsiscript
uninstallScript:
updateScript:
alwaysScript:
onceScript:
customScript:
userLoginScript:
[ProductDependency]
action: setup
requiredProduct: javavm
requiredStatus: installed
[ProductProperty]
type: unicode
name: mytextprop
multivalue: False
editable: True
description: hint
values: ["off", "on"]
default: ["off"]
[ProductProperty]
type: bool
name: myboolprop
description: yes or no
default: False
[Changelog]
mytest (3.14-1) testing; urgency=low
* Initial package
-- jane doe <j.doe@opsi.org> Mi, 14 Jul 2010 12:47:53 +0000
[Package]
version = "1"
depends = []
[Product]
type = "localboot"
id = "mytest"
name = "My Test"
description = """A test product"""
advice = """"""
version = "3.14"
priority = 0
licenseRequired = false
productClasses = []
setupScript = "setup.opsiscript"
uninstallScript = "uninstall.opsiscript"
updateScript = ""
alwaysScript = ""
onceScript = ""
customScript = ""
userLoginScript = ""
windowsSoftwareIds = []
[[ProductDependency]]
action = "setup"
requiredProduct = "javavm"
requiredStatus = "installed"
requirementType = ""
[[ProductProperty]]
type = "bool"
name = "myboolprop"
description = "hint"
default = [false]
mytest (3.14-1)
* Initial package
-- jane doe <j.doe@opsi.org> Di, 29 Aug 2023 10:36:09
opsi-newprod: Creating a Product
Apart from the graphical tools for creating opsi products introduced in this chapter, the opsi-newprod
command line tool is available to create a basic structure for opsi products. Upon launching, it initially inquires whether you want to create a localboot or a netboot product.
For products installed via the client agent or opsi-script , opting for localboot is appropriate. Choose netboot for products that are executed via the opsi Linux boot image, like operating system installations.
|
Use the [Tab] key to navigate to the OK option, or press [F12] to confirm your selection. In the next dialog, enter the information for your new opsi product:
Fill in the fields with the appropriate information:
-
Product id: This is a unique identifier for the product and is generally independent of the version. Only use lower case letters, no spaces or special characters; the hyphen
-
is permitted as a separator. -
Product name: This is the name of the product; we recommend avoiding special characters.
-
Description: Enter additional information about the product. Tools like
opsi-configed
will display this under Description. -
Advice: If you want to include further information, for example, on how to use the product, this is the place.
opsi-configed
displays these under Note. -
Product version: The version of the packaged software is shown here; a maximum of 32 characters are allowed.
-
Package version: This is the version of the package for the specified product version. It’s used to differentiate between packages that have the same product version but, for example, have updated or corrected
opsi-script
scripts. -
License required: This setting does not impact localboot products. For netboot products, however, it specifies whether a license key should be obtained from the license management system.
-
Priority: The value affects the order in which installations are executed, with possible values ranging from
100
(indicating installation at the very beginning) to-100
(indicating installation at the very end). Additionally, dependencies on other products may also influence the sequence of installation.
Next, specify the scripts that you provide for the various actions:
Enter the following information:
-
Setup script: Usually, this is
setup.ins
. -
Uninstall script: Usually, this is
uninstall.ins
. -
Update script: The script is designed to apply small modifications to an existing, large installation. When the product’s action request is set to
setup
, this update script is automatically run following the completion of the setup script’s execution. -
Always script: This script runs each time the client agent is activated, for instance, following every system startup.
-
Once script: The script has the resulting state
not_installed
. It’s a rarely used option that should be ignored unless you have a specific purpose for it. -
Custom script: Such a script neither alters subsequent actions nor affects the resulting state. It’s a seldom-used option, best left alone unless you’re certain of its application.
-
User login script: This is used to make modifications to the profile of the currently logged-in user after they’ve logged in. This only works if you’re using the User Profile Management extension.
Typ | Resulting State | Subsequent Action |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unchanged |
unchanged |
|
unchanged |
unchanged |
Now that the product details are specified, you can define dependencies with other products if needed. Otherwise, select No to proceed.
If you’ve chosen Yes, the following dialog appears:
Enter the following information:
-
Dependency for action: This contains the action of the product (that you are currently creating) for which the dependency applies (since opsi 4.3: not only setup`).
-
Required product id: Enter the ID of the produc for which there is a dependency.
-
Required action: You can either request the
setup
action or theinstalled
status (see below). -
Required installation status: This setting indicates the expected status of the dependent product, typically
installed
. If the actual status differs, the system will automatically set the product tosetup
. -
Requirement type: This option defines the installation sequence for the product dependencies. If the dependent product must be installed before the installation of the current product can commence, select
before
. Conversely, if it should be installed after the current product, chooseafter
. If the installation order is irrelevant, you can leave this field empty.
The actual installation order is determined by a mix of product dependencies and their set priorities. For more details on how these factors interact, refer to the section Priority and Dependencies. |
Next, opsi-newprod
focuses on properties, prompting you with the following questions:
Product properties are stored on a client-specific basis and consist of a name (key) that can have different values. These are then queried by the opsi-script
script. Initially, you determine whether it’s a text value (unicode) or a logical value (boolean):
For a unicode property, complete the following fields:
-
Property name (identifier): Input the name of the property.
-
Property description: This text appears as a tooltip in
opsi-configed
for assistance. -
Possible values: Type a comma-separated list of all possible values the key can assume. Leaving this field empty allows any value to be entered later in
opsi-configed
. -
Editable: Choose whether additional values can be entered beyond the specified list; you’ll see options True or False.
If a value includes a backslash \ , it must be entered twice. For example, a path specification should look like this: C:\\temp .
|
In the next dialog, you can set a default value for the property.
For boolean type properties, as opposed to unicode, the dialog differs. Here, you simply provide a name and a description for the property.
You can define multiple product properties. Once you choose not to define any more properties by responding negatively to Do you want to create a product property?, the final dialog will appear. In this dialog, you’re required to enter your name and email address, which are essential for the changelog.
The basic structure of the product is now ready. In the new directory you will find the files and directories described above. Change to the OPSI
folder and list the content (ls
). The control
file now contains the data you just defined, and you can load the file into an editor to view or change the entries.
Starting from opsi version 4.3 and onwards, the opsi-newprod tool will generate a control file in the TOML format (.toml ), along with a separate changelog.txt file.
|
Advanced Configuration with opsi-setup-detector
In the upcoming sections, we’ll explore additional configuration features of the opsi-setup-detector
. These include using a custom directory, installing from a local temporary directory, managing license keys, and personalizing user profiles and desktop icons.
Custom Directory
When you activate the Support custom directory checkbox on the Product Configuration 1 tab, the product gets supplemented with an extra directory named custom
. This directory is ideal for storing client-specific customizations. Importantly, when you upgrade to a new version of the package, the custom
directory remains untouched. The script includes templates for integrating files from this directory into the installation process.
Here’s what gets added to the setup.opsiscript
file:
; copy custom files to install dir
Files_copy_from_custom_dir
This calls a Files
section to copy files from a custom
directory to the client. The corresponding section looks like this:
[Files_copy_from_custom_dir]
copy -s "%scriptPath%\custom\*" "$installdir$"
In this example, the contents of the custom
directory are transferred to the installation directory, and the custom
directory itself is created. It contains the two files OPSI\preinst
and OPSI\postinst
. These files ensure that the contents of the custom
directory remain intact on the depot, even when updates occur.
Local, temporary Directory
When you activate the Install from local temp dir checkbox on the Product Configuration 1 tab in opsi-setup-detector
, it adjusts the installation process such that the installation files are initially copied to a local, temporary directory, and the installation is carried out from there. This method is particularly beneficial in scenarios where the installation might disrupt the network connection, a common situation with driver installations.
As a result, opsi-setup-detector
creates a new boolean property named install_from_local_tmpdir
, which defaults to false
and has this description: Determines whether the installation files are copied to a local directory.
To accommodate this feature, modifications are made to the setup.opsiscript
file as follows:
set $Install_from_local_tmpdir$ = GetProductProperty("Install_from_local_tmpdir","False")
; before the installation:
if $Install_from_local_tmpdir$ = "true"
; copy installer files to tempdirectory
Files_copy_installer_to_temp
; set $installerSourceDir$ to tmpdir
set $installerSourceDir$ = forcePathDelims("%opsiTmpDir%\"+$ProductId$)
endif
; do the installation
; after the installation
if $Install_from_local_tmpdir$ = "true"
; cleanup installer tempdirectory
Files_del_installer_from_temp
endif
Now the installation files are temporarily moved to a temporary directory and deleted after the installation if the condition Install_from_local_tmpdir
is set to true
.
The corresponding sections look like this:
; copy installer files to tempdirectory
[Files_copy_installer_to_temp]
copy -s "$installerSourceDir$\*.*" "%opsiTmpDir%\$ProductId$"
; cleanup installer tempdirectory
[Files_del_installer_from_temp]
del -sf "%opsiTmpDir%\$ProductId$\"
License Key
Activating the Handle License Key checkbox on the Product Configuration 1 tab within the opsi-setup-detector
adds the necessary property and code for managing license keys.
This action creates an additional property named secretlicense_or_pool
. By default, this property is left blank and carries the description license key or opsi licensepool. The inclusion of secret
in the property name signifies that the value of this property will be masked in opsi-configed
, meaning it won’t be displayed in plain text.
This code is inserted into the setup.opsiscript
file:
DefVar $LicenseHandledByScript$ = "true"
set $LicenseOrPool$ = GetConfidentialProductProperty("SecretLicense_or_Pool","")
; before the installation:
; ---------------------------------------------------------------
comment "handle license "
; ----------------------------------------------------------------
if $LicenseHandledByScript$ = "true"
comment "we should handle license"
;reserve license and get license key
set $LicenseKey$ = get_licensekey_byPoolOrKey($LicenseOrPool$)
; here the section or function calls should follow which
; make use of the license key resp the license reservation
endif
get_licensekey_byPoolOrKey
checks if the value entered in the secretlicense_or_pool
property corresponds to the name of a license pool as defined in the opsi extension License Management. If it matches, a license key is retrieved from this specified pool. Otherwise, the content of the property is treated and used directly as the license key.
This code is inserted into the uninstall.opsiscript
:
DefVar $LicenseHandledByScript$ = "true"
set $LicenseOrPool$ = GetConfidentialProductProperty("SecretLicense_or_Pool","")
; after the uninstallation
; ---------------------------------------------------------------
comment "handle license "
; ----------------------------------------------------------------
if $LicenseHandledByScript$ = "true"
comment "we should free license used"
Set $tmpstr$ = FreeLicense($LicenseOrPool$)
endif
Desktop Icon
Activate the checkbox DesktopIcon on the Product Configuration 1 tab to add a property and corresponding code for managing desktop icons.
A new boolean property named desktopicon
is then created, set to false
by default, and described as Should there be a desktop icon?
The corresponding code snippet is then integrated into the setup.opsiscript
file:
set $desktopicon$ = GetProductProperty("desktopicon", "False")
; after the installation
; handle desktop icon
if $DesktopIcon$ = "true"
comment "Create Desktop Icon"
Linkfolder_create_desktop_icon
else
comment "Remove Desktop Icon"
Linkfolder_remove_desktop_icon
endif
If desktopicon
is set to true
, a section Linkfolder
is called. The corresponding code (which is also inserted in the uninstall.opsiscript
file) looks like this:
[Linkfolder_remove_desktop_icon]
; check delete_element
set_basefolder common_desktopdirectory
set_subfolder ""
delete_element $productId$
[Linkfolder_create_desktop_icon]
; check name, target and working_dir
set_basefolder common_desktopdirectory
set_subfolder ""
set_link
name: $productId$
target: $Installdir$\$targetprogram$
parameters:
working_dir: $Installdir$
icon_file:
icon_index:
end_link
Additionally, these two lines are added to the delinc.opsiinc
file:
comment "Start Remove Desktop Icon Handling :"
Linkfolder_remove_desktop_icon
Customize local User Profiles
The Product Configuration 1 tab includes a checkbox named Customize Profile. When selected, a section Profileactions
is added to the code which facilitates modifications to local user profiles. This feature also extends to Roaming Profiles through a login script.
In the OPSI/control
file, the setup.opsiscript
is designated not only as a setupScript
but also as a userLoginScript
.
The following segment is added to the setup.opsiscript
file:
; Run the customization for user profiles
ProfileActions
The code triggers the execution of a section named ProfileActions
. Depending on the context in which it’s invoked, this section is executed for all local profiles or specifically for the profile of the currently logged-in user (see the chapter User Profile Management).
The sections relevant to this process, which serve as templates for modifying user profiles, are structured as follows:
[ProfileActions]
; all section that called from [ProfileActions]
; will be executed for all user profiles
;
; if this script runs as loginscript
; only the [ProfileActions] will be executed
; copy some files to every user profile
Files_copy_to_user_profiles
; make entries in every currentuser hive
Registry_current_user
; modify or create ini files in all user profiles
;Patches_in_user_profiles "%UserProfileDir%\Appdata\Roaming\<path_to_ini_file>"
Patches_in_user_profiles "%UserProfileDir%\Appdata\Roaming\osd_profile_example\osd_profile_example.ini"
[Files_copy_to_user_profiles]
; example structure:
;copy "%Scriptpath%\profile_files\*.*" "%UserProfileDir%\Appdata\Roaming\<path_to_application_dir>"
; example:
;copy "%Scriptpath%\profile_files\*.*" "%UserProfileDir%\Appdata\Roaming\osd_profile_example"
[Registry_current_user]
; example structure:
;openkey [HKCU\Software\<application key>]
;set "<var name>" = "<var value>"
; example:
;openkey [HKCU\Software\osd_profile_example]
;set "osd_profile_example_entry" = "example_value"
[Patches_in_user_profiles]
; example structure:
; set [<section name>] <key name>=<value>
; example:
;set [example_section] example_key=example_value
Uninstall_before_install
Activate the checkbox Uninstall_before_install on the Product Configuration 1 tab to add a property and corresponding code to control if we should uninstall before we try to install.
A new boolean property named Uninstall_before_install
is then created, set to true
by default, and described as Should we add code to check if we uninstall before the installation ?
The corresponding code snippet is then integrated into the setup.opsiscript
file:
set $uninstall_before_install$ = GetProductProperty("uninstall_before_install", "True")
(...)
if FileExists("%ScriptPath%\delinc.opsiinc") and ($uninstall_before_install$ = "true")
comment "Start uninstall part"
include_insert "%ScriptPath%\delinc.opsiinc"
endif
Installation with Logged-in User
There are times when software installations require a logged-in user. An indication of this is when a manual execution of an opsi-script
script with commands for unattended or silent installation works, but the same installation fails when executed automatically through opsi.
This could be because the installation program requires a logged-in user or needs access to a user profile.
In such scenarios, you can integrate your installation into an opsi package that establishes these necessary conditions. You can create such a package using the opsi-setup-detector
by selecting the Windows task Analyze File and Create Package 'with user'.
Customizing the Unattended/Silent Setup
Following a successful silent installation, there’s often a need for additional customizations. Using opsi-script
makes these adjustments manageable, but first, it’s essential to understand which changes in the graphical user interface correspond to specific alterations in files and the Windows registry.
For this task, consider using tools such as:
Setup with Automated Responses
An alternative and swift method for integration into automatic software distribution is the setup with automated responses. This approach uses a control program to automate user interactions with dialog windows that appear during setup.
For this, we recommend this tool:
AutoIt: Managing the Setup Process
AutoIt provides various functionalities for managing the setup process, including the capability to address potential error conditions with [ADLIB]
script sections.
One critical issue, however, remains unaddressed: unexpected windows, not previously incorporated into the script, can halt the script’s execution. Additionally, user interventions through mouse and keyboard (unless disabled) can unpredictably alter the scripted sequence of events.
For these reasons, an unattended or silent setup is typically the better solution! A hybrid method can also be effective: use a silent setup for the main installation, with an AutoIt script intercepting and managing known exceptions or special conditions. |
AutoIt: Known Issues
When installations are transferred to a different desktop in the client agent configuration, or if the desktop is locked, certain AutoIt functions have problems.
It is advisable to steer clear of these functions in opsi-script scripts, if possible:
|
-
winwait()
-
winactivate()
-
Send()
Unfortunately, these are the three most frequently used functions. We recommend replacing the commands with those included in the opsi-script
library C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-script\lib\opsi-autoit-lib.au3
. This library not only includes the extended functions outlined here but also encompasses a logging function. Simply copy the opsi-autoit-lib.au3
file into the product directory and then include it in the AutoIt code like this:
#include "%scriptpath%\opsi-autoit-lib.au3
After that, you can replace the following items:
-
You can replace
winwait()
with the functionopsiwinwait($title, $text, $maxseconds, $logname)
. -
Send()
can be replaced by the functionopsiControlClick($title, $text, $id, $maxseconds, $logname)
or byopsiControlSetText($title, $text, $id,$sendtext, $maxseconds, $logname)
.
It is recommended to determine the ControlID with Au3info.exe . Be sure to use the numeric ControlID, as other variants seem to cause problems.
|
Analyzing and Repackaging
When developers build an application package, they are aware of the essential components needed for its functionality. In cases where an installation package already exists, running the setup program can reveal which parts must be installed on a workstation to achieve the desired functionality.
There are a number of tools for analyzing setup programs, e.g. Regshot
Uninstalling Products
Removing software from a computer typically involves creating an uninstall script. However, the challenge lies in determining the specifics of the installation process and ensuring that only the necessary components are removed to avoid system damage. Ideally, the software manufacturer is best equipped to know the exact uninstallation process.
Products often come with automated uninstall routines. When these can operate without user intervention, they are the preferred choice. In scenarios where an automated routine isn’t available or needs augmentation, opsi-script
can be used. This section provides an overview of the available options.
Using the Uninstallation Routine
If the product’s manufacturer supplies a program (or an MSI package) for uninstallation, first check whether it operates silently, without user interaction. If this is not the case, an AutoIt script can be used in combination with the uninstallation routine.
The call to the executable file can be placed in a [WinBatch]
section within the opsi-script
script:
[WinBatch_start_ThunderbirdUninstall]
"%SystemRoot%\UninstallThunderbird.exe" /ma
Even when a manufacturer provides a dedicated program for uninstalling their product, don’t assume it completely removes all components. Always verify on a test system to ensure the computer remains stable post-uninstallation and to check if any files or registry entries persist. |
Uninstalling MSI Products
When a product is distributed as an MSI package and installed via msiexec
, it can typically be uninstalled using the same tool. Use msiexec.exe
with the /x
parameter, followed by the name of the MSI package or its GUID.
Each MSI package has a unique, product-specific GUID that remains consistent across all installations. This ID can be found in the registry at HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall .
|
For silent uninstallation without user interaction, include the /qb-!
parameter in your command:
msiexec.exe /x some.msi /qb-! REBOOT=ReallySuppress
This is what the uninstallation looks like with a GUID:
msiexec.exe /x {003C5074-EB37-4A75-AC4B-F5394E08B4DD} /qb-!
Each version of a product might have a unique GUID. To remove older versions, it’s important to pinpoint their respective GUIDs.
To do this, there are different methods. The preferred method since opsi-setup-detector
Version 4.3.3 is using the MsiUpgradeCode.
MsiUpgradeCode
Here we use the MsiUpgradeCode
, extracted by opsi-setup-detector
from the MSI file.
The MsiUpgradeCode
is product specific and version independent. The osd-lib.opsiscript
library contains the function getGuidListByMsiUpgradecode
which list all the MsiProduct codes that identfy installed software that matches the given MsiUpgradeCode
. This list ($UninstallList$
) can be used to control the uninstall of installed versions.
; Variant 3:
;-----------------------------------------------------
; Finding the MsiId by the Upgrade Code from the MSI file:
; The MsiUpgradecode should be product specific and version independent.
; It should be - it is not always.
Set $MsiUpgradecode$ = '{C73ED533-953E-47E5-9A42-A48292BB7C6C}'
; get Installed MsiIds by the UpgradeCode
Set $UninstallList$ = getGuidListByMsiUpgradecode($MsiUpgradecode$)
;-----------------------------------------------------
MsiDisplayName
This method involves using the `MsiName`, extracted by `opsi-setup-detector` from the MSI file.
This MsiName
is listed as DisplayName
in the registry’s Uninstall
section. Use the MsiName
to search for the right GUID. Start by removing any details about the architecture and version at the end of MsiName
. Then, encapsulate it with regular expressions:
; Variant 2:
;-----------------------------------------------------
; Finding the MsiId by the Displayname from Registry:
; Be sure that the Displayname is set correctly:
Set $DisplayName$ = 'grepWin x64'
; escape all regex relevant chars with '\' : '\^$.|?*+()[{'
set $DisplayNameRegex$ = escapeRegexMetaChars($DisplayName$)
; '(?i)' = case insesitive ; '.*' = 0 or more of any thing
set $DisplayNameRegex$ = '(?i)'+$DisplayNameRegex$+'.*'
Set $UninstallList$ = getGuidListByDisplaynameRegex($DisplayNameRegex$)
;-----------------------------------------------------
In this script segment, the following actions are performed:
-
Set $DisplayName$ = 'short msi name'
: The variable$DisplayName$
is assigned the truncatedMsiName
, omitting any additional details like version or architecture. -
set $DisplayNameRegex$ = escapeRegexMetaChars($DisplayName$)
: This line prepares$DisplayName$
for a regex search, effectively escaping any special characters in the string. -
set $DisplayNameRegex$ = '(?i)'$DisplayNameRegex$'.*'
: This regex pattern is set to be case-insensitive (?i
) and designed to match the beginning of a string, followed by any sequence of characters, essentially accommodating any additional details following the base name. -
Set $UninstallList$ = getGuidListByDisplaynameRegex($DisplayNameRegex$)
: The script then uses thegetGuidListByDisplaynameRegex
function, part of theosd-lib.opsiscript
library, to scour the registry. It compiles a list matching the criteria, formatted as<MsiVersion> = <msi GUID>
.
Processing the $UninstallList$
The further uninstall process is controlled by the entries of the $UninstallList$
:
comment "run the uninstallation "
; ----------------------------------------------------------------
if count($UninstallList$) int> "0"
Comment "Uninstalling all found versions"
for %uninstallEntry% in $UninstallList$ do Sub_Uninstallation_msi
endif
[Sub_Uninstallation_msi]
set $MsiVersion$ = TakeString(0, splitstring('%uninstallEntry%', "="))
set $MsiId$ = TakeString(1, splitstring('%uninstallEntry%', "="))
if stringtobool(checkForMsiProduct($MsiId$))
Message "Uninstalling :" + $ProductId$ + " " + $MsiVersion$+ "..."
Winbatch_Uninstall_1
Set $ExitCode$ = getlastexitcode
if stringtobool(isMsiExitcodeFatal($ExitCode$, "true", $ErrorString$ ))
LogError $ErrorString$
isfatalerror $ErrorString$
else
Comment $ErrorString$
endif
else
Comment "No previously installed " + $ProductId$ + " version found"
endif
In this script segment, the following actions are performed:
-
If the
$UninstallList$
contains one or more entries -
Call for every entry of the
$UninstallList$
the sub section[Sub_Uninstallation_msi]
-
[Sub_Uninstallation_msi]
: Finally, this section utilizes the retrieved GUID for the uninstallation process.
If these techniques fall short or are partially successful, the next section discusses an alternative approach using an opsi-script
script.
opsi-script Useful Commands for Uninstalling
When uninstalling a product that was installed using opsi-script
functions or if a manufacturer’s uninstall routine isn’t available, creating a custom uninstall script is a viable solution.
opsi-script
provides a variety of functions to aid in creating an effective uninstallation process. A comprehensive explanation of these functions and their parameters can be found in the opsi-script Reference.
For basic scenarios, you can use a Files
section to remove specific files with the following command:
delete -f <file>
To delete a directory with subdirectories, use this command:
delete -sf <directory>\
The parameter f
indicates a forced deletion of the file, even if it is write-protected. The s
parameter includes subdirectories and operates recursively.
Use the /AllNTUserProfiles
parameter if you need to delete a file or directory from all user profiles.
When you need to remove a directory tree containing files marked as "hidden" or as "system files", consider using the rmdir
command. This can be executed via a ShellScript
section:
[ShellScript_deleteDir]
rmdir /S /Q "<directory>"
Sometimes a running process must be terminated before deletion. In this case, find out the name (e.g. via the task manager) and pass it to the opsi-script
command KillTask
:
KillTask "thunderbird.exe"
If a product (or parts of it) operates as a service, you need to stop this service before uninstallation. You can deactivate the service in the registry and restart the computer, or use the system command net
with the stop
parameter. This stops the service instantly, deleting the associated files without a restart:
net stop <service>
Extra caution is necessary when removing .dll files that may still be in use by other programs. These files need to be dealt with on a case-by-case basis, and unfortunately, we can’t offer universal guidance for this situation.
|
To remove specific entries from the registry using opsi-script
, use the DeleteVar
command. This command is placed within a Registry
section of an opsi-script
and it removes entries from the currently open key:
DeleteVar <VarName>
To delete a registry key with all subkeys and registry variables, you can use the command DeleteKey
:
DeleteKey [HKLM\Software\Macromedia]
64 Bit Support
opsi-script
is a 32 bit application. Scripts designed for installing 32 bit software typically function properly on 64 bit systems as well. However, when it comes to installing 64 bit software using opsi-script
or working with 64 bit systems in general, please consult the chapter 64 Bit Support.