Eigene Software einbinden

Für die Installation von Software ist bei opsi der Client-Agent bzw. das Setup-Programm opsi-script zuständig. Wenn Sie also eigene Software paketieren, müssen Sie zu jedem Produkt auch ein opsi-script-Skript erstellen. Dieses packen Sie anschließend zusammen mit den Installationsdateien und den Metadaten zu einem opsi-Produkt, das Sie auf dem opsi-Server installieren (siehe Kapitel Produkte auf opsi-Server bereitstellen).

Tutorial: opsi-script-Skript erstellen

Dieses Tutorial kann eine Schulung oder das Studium der Handbücher nicht vollständig ersetzen. Es soll lediglich eine Einführung bieten. Daher verweisen wir zuerst auf weiterführende Quellen:

Nicht-interaktive Software-Installation (Windows)

Grundsätzlich stehen Ihnen drei Methoden zur Verfügung, um ein Softwarepaket in die automatische Softwareverteilung für Windows-Betriebssysteme zu integrieren. Zusätzlich gibt es eine Variante, die den Dienst Windows Installer verwendet:

  • Unattended/Silent Setup:
    Bei dieser Methode verwenden Sie das Original-Setup-Programm und versetzen es mit Kommandozeilen-Parametern in einen nicht-interaktiven Modus. Der wichtigste Spezialfall ist der „stille“ Aufruf eines MSI-Paketes, das Sie mit der /quiet-Option des Tools msiexec installieren.

  • Interaktives Setup mit automatisierten Antworten:
    Zur Vorbereitung führen Sie das ursprüngliche Setup-Programm einmal aus und notieren dabei, welche Fenstertitel es anzeigt und welche Fragen und Antworten während des Setups auftreten. Diese Informationen halten Sie in einem Skript fest. Im Softwareverteilungs-Prozess steuert ein Automatisierungs-Programm wie z. B. AutoIt oder AutoHotkey das Setup-Programm nach den Vorgaben des Skriptes.

  • Setup-Routine mit opsi-script nachbilden:
    Während das Original-Setup-Programm läuft, protokolliert ein Tool wie Prozessmonitor/Procmon sämtliche Systemänderungen. Basierend auf diesen Daten und den erfassten Änderungen erstellen Sie das opsi-script-Skript.

opsi unterstützt alle drei Varianten. In der Praxis kommt häufig eine Kombination aus mehreren Methoden zum Einsatz.

Struktur eines opsi-script-Skriptes

Die nächsten Abschnitte erläutern die wesentlichen Elemente eines opsi-script-Skriptes für Windows-Rechner. So sieht beispielsweise ein einfaches Skript aus:

[Actions]
WinBatch_tightvnc_silent_install

[WinBatch_tightvnc_silent_install]
"%ScriptPath%\tightvnc-1.3.9-setup.exe" /silent

Ein opsi-script-Skript besteht aus primären und sekundären Sektionen. Genau wie bei INI-Dateien leitet der Name in eckigen Klammern eine Sektion ein.

Die eigentlichen Arbeiten zur Software-Installation finden in den sekundären Sektionen statt, die von den primären Sektionen aufgerufen werden. Die sekundären Sektionen sind themenspezifisch und folgen einer speziellen Syntax: Der Name beginnt mit mit dem Typ, gefolgt von einem frei definierbaren Namen.

Im letzten Beispiel ruft die primäre Sektion [Actions] eine sekundäre Sektion [WinBatch_tightvnc_silent_install] auf; diese ist vom vom Typ WinBatch. Der Inhalt einer WinBatch-Sektion wird über die Windows-API ausgeführt. In diesem Fall wird das angegebene Setupprogramm tightvnc-1.3.9-setup.exe mit dem Parameter /silent gestartet.

Primäre Sektionen

  • Actions/Aktionen: Die [Actions]-Sektion ist das eigentliche Hauptprogramm. Hier beginnt die Skript-Verarbeitung.

  • Sub-Sektionen: Programmabschnitte, die wiederholt benötigt werden, können in Sub-Sektionen (Unterprogramme) ausgelagert werden. Sie können Sub-Sektionen auch in externe Dateien auslagern.

Vermeiden Sie doppelten Code über ausgegliederte Sub-Sektionen.
Abbildung 1. Vermeiden Sie doppelten Code über ausgegliederte Sub-Sektionen.

Die primären Sektionen (also die Hauptprogramme) steuern den Ablauf des Skriptes. Hier können Sie Variablen, bedingte Anweisungen, Funktionen usw. verwenden. Lesen Sie dazu auch den Abschnitt Elementare Befehle für primäre Sektionen.

Sekundäre Sektionen

  • Files: Für Datei-Operationen, wie beispielsweise

    • Kopieren (mit Versionskontrolle, rekursiv, usw.)

    • Löschen

    • Verzeichnisse anlegen

    • usw.

  • WinBatch: Dient zum Aufrufen von Programmen über die Windows-API. So werden in diesen Sektionen beispielsweise Setup-Programme im nicht-interaktiven Modus ausgeführt.

  • ShellScript: Der Inhalt dieser Sektion wird der Standard-Shell des jeweiligen Betriebssystems zur Ausführung übergeben. Bei Windows ist das die cmd.exe, bei Linux und bei macOS die bash. Hier können also normale Batch-Skripte abgelegt werden.

  • ExecWith: Der Inhalt dieser Sektionen wird einem externen Programm (wie einem Interpreter) zur Ausführung übergeben. Beispielsweise können über ExecWith AutoIt-Skripte direkt ins opsi-script-Skript integriert werden.

  • Registry: In diesen Sektionen stehen Anweisungen zum Bearbeiten der Windows-Registry.

  • LinkFolder: In diesen Sektionen erstellen bzw. entfernen Sie Verknüpfungen, z. B. zum Desktop oder ins Startmenü.

Globale Konstanten

opsi-script unterstützt ebenfalls globale Konstanten. Es handelt sich um Platzhalter, die Sie in primären und sekundären Sektionen einsetzen können. Mit solchen Konstanten stellen Sie sicher, dass Pfade in unterschiedlichen Umgebungen (z. B. auf Systemen mit unterschiedlichen Sprachen oder Betriebssystem-Versionen) richtig gesetzt sind.

Hier ein paar Beispiele:

  • %ProgramFiles64Dir%: c:\program files (auf einem 64 Bit System)

  • %ProgramFiles32Dir%: c:\program files (x86) (auf einem 64 Bit System)

  • %SystemRoot%: c:\windows

  • %System%: c:\windows\system32

  • %opsiTmpDir%: c:\opsi.org\tmp

  • %ScriptPath%: <Pfad zu laufendem Skript>

Beispiel: TightVNC installieren

Zur Erläuterung drucken wir hier ein weiteres Beispiel-Skript ab. Zur Installation des Programms wäre hier der Silent-Aufruf der setup.exe in der sekundären Sektion WinBatch_tightvnc_silent_install ausreichend; bei einer wiederholten Installation erscheint jetzt aber (wegen eines laufenden Services) ein interaktiver Dialog. Wenn das Dialogfenster auftaucht, wird es mit Hilfe von AutoIt geschlossen:

[Actions]
Message "Installiere 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")

Weitere Details zur Verwendung von AutoIt finden Sie hier:
Setup mit automatisierten Antworten.

Elementare Befehle für primäre Sektionen

Die nächsten Abschnitte erklären kurz die elementaren Befehle für primäre Sektionen in opsi-script-Skripten, darunter Variablen, Anweisungen, bedingte Anweisungen, Funktionen usw. Eine vollständige Referenz finden Sie im opsi-script-Kapitel.

String-Variablen
Variablen-Deklaration

DefVar <variable name> [= <initial value>]

Variablen-Zuweisung

Set <variable name> = <value>

Im folgenden Beispiel wird eine Variable $ProductId$ deklariert und ihr der Wert "firefox" zugewiesen:

DefVar $ProductId$
Set $ProductId$ = "firefox"

Alternativ geht es auch kürzer:

DefVar $ProductId$ = "firefox"
String-Variablen werden in primären und sekundären Sektionen unterschiedlich behandelt. In primären Sektionen sind es eigenständige Objekte, in sekundären Sektionen werden sie vor der Ausführung der Sektion durch den Inhalt der Variable ersetzt. Achten Sie besonders darauf, wenn Sie entsprechende String-Ausdrücke im Skript mit Copy & Paste kopieren/einfügen.

Demzufolge können Sie String-Variablen nur in primären Sektionen deklarieren und ihnen Werte zuweisen. Die Verbindung von Variablen und Strings zu einem String-Ausdruck benötigt den Operator "+":

"Installing "+ $ProductId$ +" ..."

In sekundären Sektionen werden String-Variablen vor der Ausführung der Sektion durch den Inhalt der Variable ersetzt:

"Installing $ProductId$ ..."

Das hat den Vorteil, dass Sie in Sektionen, die außerhalb des Skriptes ausgeführt werden (ExecWith, ShellScript), problemlos mit opsi-script-Variablen arbeiten können.

Anweisungen: Message und ShowBitmap

Zur Textausgabe während der Installation verwenden Sie Message <string>; <string> ersetzen Sie durch den tatsächlichen Text, den Sie anzeigen möchten:

Message "Installing "+ $ProductId$ +" ..."

Anstelle von Textnachrichten können Sie auch Grafiken (ShowBitmap) in den Formaten während der Installation anzeigen. Die Bilder müssen als BMP-, JPG- oder PNG-Datei im Format 160 x 160 Pixel vorliegen. Optional ist über subtitle eine Beschriftung möglich:

ShowBitmap "%ScriptPath%\python.png" "Python"
Bedingte Anweisungen: if, elseif/else und endif

Sie können auch Code abhängig von einer bestimmten Bedingung ausführen:

  • if: Das ist die erste Bedingung. Ist sie wahr (true), werden die im folgenden Block eingeschlossenen Anweisungen ausgeführt. Ist sie falsch (false), wird dieser Block übersprungen.

  • ;statement(s): Das ist der Codeblock, der ausgeführt wird, wenn die Bedingung im if-Teil wahr ist. Hier können eine oder mehrere Anweisungen stehen, die ausgeführt werden, wenn die Bedingung erfüllt ist.

  • elseif <condition>: Dieser Teil ist optional. Wenn die Bedingung im if-Teil nicht erfüllt ist, wird die Bedingung hier überprüft. Wenn diese Bedingung wahr ist, werden die im folgenden Block eingeschlossenen Anweisungen ausgeführt. Dies ermöglicht das Hinzufügen zusätzlicher Bedingungen, die überprüft werden, wenn die vorherigen Bedingungen nicht erfüllt sind.

  • else: Dieser Teil ist ebenfalls optional. Wenn keine der vorherigen Bedingungen wahr ist, werden die Anweisungen im else-Block ausgeführt. Der Block ist also eine Art Fallback und wird dann ausgeführt, wenn keine der vorherigen Bedingungen zutrifft.

  • endif: Dass markiert das Ende des bedingten Konstrukts. Es zeigt an, dass die bedingte Überprüfung hier endet.

if <condition>
	;statement(s)
[elseif <condition>
;statement(s)]
[
else
	;statement(s)
]
endif
Funktionen
  • HasMinimumSpace: Prüft auf freien Platz auf der Festplatte.

  • FileExists: Prüft auf Existenz einer Datei oder eines Verzeichnisses.

Kommentare, Fehler und Logging
  • Kommentarzeichen: Zeilen, die mit einem Semikolon (;) beginnen, werden nicht interpretiert.

  • Comment: Schreibt einen Kommentar in die Logdatei.

  • LogError: Schreibt eine Fehlermeldung in die Logdatei.

  • IsFatalError: Bricht die Ausführung des laufenden Skriptes ab und meldet die Installation als gescheitert zurück.

Bedingung zur Ausführung
  • requiredOpsiscriptVersion: Gibt die (mindestens) benötigte opsi-script-Version an:

requiredOpsiscriptVersion >= "4.12.3.6"
Weitere wichtige opsi-script-Funktionen
  • String-Listen: String-Listen sind sehr mächtig, insbesondere zur Auswertung von Ausgaben externer Programme (siehe Abschnitt Verarbeitung von String-Listen).

  • Funktion ExitWindows: Neustart/Herunterfahren des Systems und opsi-script beenden

    • ExitWindows /Reboot: Neustart des Rechners nach Abschluss des laufenden Skriptes

    • ExitWindows /ImmediateReboot: sofortiger Neustart

    • ExitWindows /ImmediateLogout: Skript-Bearbeitung und opsi-script sofort beenden

  • Produkteigenschaften: Für manche Produkte ist es erforderlich, Optionen zur Verfügung zu stellen. Diese werden zur Laufzeit Client-spezifisch ausgewertet (siehe Abschnitt opsi-Produkte erstellen).

Der Zugriff auf die Werte der Propertys geschieht über die Funktion GetProductProperty:

if GetProductProperty("example-property", "no") = "yes"
	Files_copy_extra_files
endif
  • Encoding: Schreiben Sie Ihre Skripte in UTF-8-Kodierung und setzen Sie dazu an den Anfang der Datei die Anweisung:

encoding=utf8
Spezielle Windows-Kommandos
  • GetOS: Gibt das Betriebssystem aus, z. B. Linux, Windows_NT (Windows NT bis Windows 11) oder macOS.

  • GetMsVersionInfo: Gibt auf Windows-Systemen Informationen über die interne Version aus; z. B. produziert ein Windows 7 das Ergebnis "6.1", Windows 11 liefert "10.0" usw.

  • GetMsVersionName: Gibt die Marketing-Version für ein Windows-System aus, z. B. produziert ein Windows 7 das Ergebnis "7.0", Windows 11 liefert "11.0" usw.

  • getMSVersionMap: Fragt die Betriebssystem-Informationen lokal ab und schreibt die Informationen in eine String-Liste.

Weiterführende Informationen zu diesen String-Funktionen lesen Sie im Abschnitt String-Funktionen (Betriebssystem ermitteln).

Beispiel: Windows-Template opsi-template

Dieses Template können Sie mit dem opsi-setup-detector erstellen (siehe Abschnitt opsi-setup-detector: Skript erstellen).

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$


; ----------------------------------------------------------------
; ----------------------------------------------------------------

opsi-Produkte erstellen

Die nächsten Abschnitte erklären, wie Sie Software paketieren, also opsi-Produkte erstellen. Der grundlegende Ablauf sieht so aus:

  1. Den "Rohbau" eines Paketes erstellen Sie mit dem opsi-setup-detector (siehe Abschnitt opsi-setup-detector: Skript erstellen).

  2. Danach testen Sie das opsi-script-Skript (siehe Abschnitt Skript testen und verbessern).

  3. Mit dem opsi PackageBuilder (oPB) erstellen Sie aus der Rohform ein opsi-Paket und hinterlegen es auf dem opsi-Server.

Vorbereitungen

Zum Erstellen von opsi-Paketen benötigen Sie die folgenden Werkzeuge:

opsi-setup-detector installieren

Den opsi-setup-detector gibt es derzeit für Windows, Linux und macOS. Sie können das Programm direkt über opsi installieren. Es gehört zu den Standard-Localboot-Produkten und sollte bereits auf dem opsi-Server vorhanden sein. Ist das nicht der Fall, stellen Sie das Produkt über den folgenden Befehl bereit:

opsi-package-updater install opsi-setup-detector
Das Localboot-Produkt opsi-setup-detector erfordert ebenfalls die Installation des Produktes opsipackagebuilder_wlm, denn der Setup-Detector verwendet den PackageBuilder (sofern dieser vorhanden ist).

Installieren Sie daher ebenfalls das Produkt opsipackagebuilder_wlm:

opsi-package-updater install opsipackagebuilder_wlm

Anschließend rollen Sie die beiden Produkte auf den gewünschten Clients aus, beispielsweise über die Management-Oberfläche opsi-configed.

Für Windows-Rechner bieten wir den Setup-Detector auch als eigenständiges Paket an, das Sie unabhängig von opsi installieren können: https://tools.43.opsi.org/stable/
Unterschiede unter Windows, Linux, Mac

Grundsätzlich funktioniert der opsi-setup-detector auf allen drei Betriebssystemen ähnlich. Zur Analyse einer Installationsdatei ruft das Programm aber unterschiedliche Hilfsprogramme auf:

  • Genaue Analysen von Inno Setups unter Windows verwenden das integrierte Tool innounpack.exe. Diese Detailanalyse ist daher nur unter Windows möglich.

  • Zur Arbeit mit dem Windows Installer XML (kurz WiX Toolset) wird unter Windows das integrierte Werkzeug Dark.exe verwendet. Diese Detailanalyse ist daher nur unter Windows möglich.

  • .deb- bzw. .rpm-Pakete analysieren die entsprechenden Standard Paketverwaltungstools unter Linux. Diese Detailanalyse ist daher nur auf Linux-Rechnern möglich.

opsi PackageBuilder installieren

Der opsi PackageBuilder (oPB) steht für Windows, Linux und macOS zur Verfügung.

Das Produkt opsipackagebuilder_wlm gehört zu den opsi-Standardprodukten. Falls es noch nicht auf Ihrem Server installiert ist, spielen Sie es über diesen Befehl ein:

opsi-package-updater install opsipackagebuilder_wlm

Anschließend können Sie das Localboot-Produkt auf den Clients ausrollen, beispielsweise über die Management-Oberfläche opsi-configed.

Den opsi PackageBuilder (oPB) können Sie als Localboot-Produkt auf den Clients ausrollen.
Abbildung 2. Den opsi PackageBuilder (oPB) können Sie als Localboot-Produkt auf den Clients ausrollen.

Alternativer Weg zum Produkt:

Sie können opsi PackageBuilder (oPB) entweder als opsi-Produkt auf dem opsi-Server installieren und dann über opsi-configed ausrollen oder eines der im forum.opsi.org - opsi PackageBuilder verlinkten Installationspakete verwenden.

Der opsi PackageBuilder (oPB) ist ein Community-Produkt und wird von Holger Pandel entwickelt — vielen Dank!

Die Quellen und Lizenz finden sie hier: GitHub: opsi PackageBuilder (oPB)

opsi-logviewer installieren

Den opsi-logviewer gibt es derzeit für Windows, Linux und macOS. Er gehört zur Management-Oberfläche opsi-configed und wird mit dieser zusammen ausgeliefert.

Das Paket opsi-configed gehört zu den opsi-Standardprodukten und sollte auf Ihrem opsi-Server installiert sein. Falls nicht, spielen Sie es mit diesem Kommando ein:

opsi-package-updater install opsi-configed
Eine ausführbare Version der Management-Oberfläche opsi-configed für Windows, Linux und macOS finden Sie auf unserer Website opsi-Tools.

opsi-setup-detector: Skript erstellen

Die folgenden Abschnitte erklären detailliert, wie Sie mit dem opsi-setup-detector ein opsi-Produkt eine Setup-Datei analysieren und ein opsi-Produkt erstellen.

Start und Konfiguration

Unter Windows starten Sie den opsi-setup-detector aus dem Startmenü heraus; Sie finden das Werkzeug unter opsi.org / opsi-setup-detector. Unter macOS finden Sie den opsi-setup-detector über Programme und unter Linux in den Startmenüs unter Systemwerkzeuge. Auf den meisten Linux-Desktopumgebungen können Sie außerdem den vollen Pfad zur ausführbaren Datei (/opt/opsi-setup-detector/opsisetupdetector) in ein Schnellstartfenster ([Alt]+[F2]) oder Terminal eingeben.

Unter Windows können Sie den opsi-setup-detector direkt aus dem Explorer heraus starten. Wenn Sie mit der rechten Maustaste auf ein Setup-Programm einer Applikation klicken, finden Sie im Kontextmenü einen Eintrag, über den Sie das Tool zur Analyse starten.
Den *opsi-setup-detector* starten Sie auch aus dem Explorer heraus.
Abbildung 3. Den opsi-setup-detector starten Sie auch aus dem Explorer heraus.

Nach dem ersten Start erscheint ein Dialog, der Sie zur Konfiguration führt. Die folgenden drei Angaben sind unbedingt erforderlich:

  • fullName: Tragen Sie Ihren Namen ein, wie er später in der Datei changelog.txt auftauchen soll.

  • email_address: Tragen Sie Ihre Mailadresse ein, wie sie später in der Datei changelog.txt auftauchen soll.

  • workbench_Path: Hier geben Sie den Pfad zum Verzeichnis an, in dem Sie die opsi-Pakete erstellen.
    Idealerweise ist das der Pfad zur Freigabe, an der die Workbench Ihres opsi-Servers gemountet ist (siehe Kapitel Samba).

Nach dem ersten Start konfigurieren Sie den *opsi-setup-detector*.
Abbildung 4. Nach dem ersten Start konfigurieren Sie den opsi-setup-detector.

Darüber hinaus können Sie optional weitere Einstellungen vornehmen. Für den opsi-Webservice opsiconfd (https://<opsi-server>:4447, siehe Kapitel Der Dienst opsiconfd) füllen Sie die folgenden Felder aus:

  • Service_URL: URL des opsi-Webservices (im Format https://<opsi-server>:4447)

  • Service_user: Benutzername für die Verbindung zum opsi-Webservice

  • Service_pass: Passwort des unter Service_user eingetragenen Benutzers für die Verbindung zum opsi-Webservice: lassen Sie das Feld leer, dann fragt der opsi-setup-detector bei Bedarf nach.

Mögliches Sicherheitsrisiko: Auch wenn das Passwort verschlüsselt abgespeichert wird, so lässt es sich doch nach einer Analyse des (offenen) Quellcodes entschlüsseln.

Weitere optionale Einstellungen sind:

  • control_in_toml_format: Checkbox aktivieren, um eine control-Datei im TOML-Format zu erzeugen (siehe Abschnitt Beispiel: control-Datei);
    Achtung: Dazu ist mindestens opsi 4.3 erforderlich!

  • dependencies_for_all_actionrequests: Sollen Abhängigkeiten auch für andere Action Requests (ausser setup) erlaubt sein?
    Achtung: Dazu ist mindestens opsi 4.3 erforderlich, bitte mit äußerster Vorsicht verwenden!

  • preferMsiUninstall: Soll wenn in einem Setupprogramm ein MSI gefunden wird, die Uninstallroutine des MSI statt der des Setupprogramms verwendet werden ?

Eine ausführliche Beschreibung aller Einstellungen finden Sie im Kapitel opsi-setup-detector Konfiguration.

Nach dem Speichern der Konfiguration erscheint die Startseite.

Onlinehilfe

Klicken Sie auf das Fragezeichen, um die Onlinehilfe zum opsi-setup-detector einzublenden.

Über dieses Icon zeigen Sie die Onlinehilfe an.
Abbildung 5. Über dieses Icon zeigen Sie die Onlinehilfe an.
Die *opsi-setup-detector*-Startseite
Abbildung 6. Die opsi-setup-detector-Startseite

Wählen Sie die gewünschte Aufgabe aus. Sie finden hier Tasks für Windows, Linux und macOS sowie vom Betriebssystem unabhängige Aufgaben und eine eigene Abteilung für Multiplattform-Pakete.

Unter Windows stehen folgende Funktionen zur Verfügung:

  • Analysiere Datei und erzeuge ein opsi Paket: Ausgehend von einer Setup-Datei wird hier der gesamte Prozess durchlaufen bis zum Erzeugen eines opsi-Paketes (siehe Abschnitt Datei analysieren und Paket erzeugen).

  • Analysiere 2 Dateien (32 / 64 Bit) und erzeuge ein O. Paket: Verläuft ähnlich, allerdings werden hier zwei Setup-Programme für die beiden Architekturen (32 Bit und 64 Bit) abgefragt und analysiert. Das Produkt bekommt ein zusätzliches Property: install_architecture (mögliche Werte: 32bitonly, 64bitonly, both und systemspecific).

  • Eine opsi Paketvorlage (Template) erzeugen: Fragt nicht nach einer Setup-Datei, sondern erstellt ein opsi-Template-Produkt für Windows und übernimmt dazu die Angaben aus der Produkt-Konfiguration.

  • Analysiere Datei und erzeuge ein Paket 'with user': Ähnlich wie Analysiere Datei und erzeuge ein opsi Paket, erstellt das Paket für eine Installation bei angemeldetem Benutzer (siehe Abschnitt opsi_template_with_userlogin). Das Produkt bekommt zusätzliche Propertys:

    • execution_method, mögliche Werte: loginOpsiSetupUser, runAsOpsiSetupUser und runOpsiScriptAsOpsiSetupUser

    • boolesche Propertys: uninstall_before_install, copy_files_locally und debug

  • Erzeuge ein opsi Paket Template 'with user'_: Fragt nicht nach einer Setup-Datei, sondern erstellt ein opsi-Template-Produkt für eine Installation bei angemeldetem Benutzer und übernimmt dazu die Angaben aus der Produkt-Konfiguration.

Datei analysieren und Paket erzeugen

Die folgenden Abschnitte beschreiben, wie Sie eine Setup-Datei analysieren und daraus ein opsi-Produkt erstellen. Klicken Sie dazu auf der Startseite (Abbildung 6, “Die opsi-setup-detector-Startseite”) auf die Schaltfläche Analysiere eine Datei und erzeuge ein opsi Paket. Danach navigieren Sie im Dateiauswahldialog zur gewünschten Installerdatei. Der opsi-setup-detector beginnt direkt mit der Analyse.

Analyse

Der opsi-setup-detector analysiert dabei die Datei mit seiner eigenen Methode und unter Verwendung des Werkzeugs Detect it Easy (DIE). Dateien welche an Ihrer Dateinamenerweiterung erkannt werden, werden nicht weiter analysiert.
Nach der Analyse einer Setup-Datei sehen Sie diesen Dialog:

Der *opsi-setup-detector* hat eine Datei analysiert.
Abbildung 7. Der opsi-setup-detector hat eine Datei analysiert.

War die Analyse nicht erfolgreich, sehen Sie stattdessen entweder diesen Dialog:

Der Dialog *Sorry Unknown Installer*
Abbildung 8. Der Dialog Sorry Unknown Installer

Der Typ der Installerdatei konnte nicht ermittelt werden.
Sie können jetzt den Vorgang per Klick auf Cancel abbrechen oder aus dem Drop-down-Menü einen Installertyp auswählen und die Paketerstellung fortsetzen.

oder Sie sehen diesen Dialog:

Der Dialog *Detektierter Installer ist nicht bekannt*
Abbildung 9. Der Dialog Detektierter Installer ist nicht bekannt

Der Typ der Installerdatei konnte zwar ermittelt werden aber der opsi-setup-detector hat keine weiteren Informationen zu diesem Typ.
Sie können jetzt den Vorgang per Klick auf Cancel abbrechen oder aus dem Drop-down-Menü einen Installertyp auswählen und die Paketerstellung fortsetzen.

Ist die Analyse erfolgreich verlaufen, öffnet sich in einzelnen Fällen ein Fenster mit ergänzenden Informationen zum erkannten Installertyp. Das ist beispielsweise bei Anwendungen wie InstallShield, dem Qt-Installer oder InstallAnywhere der Fall.

Additional Info: InstallShield
Additional Info: Qt-Installer
Additional Info: InstallAnywhere

Ist die Analyse erfolgreich verlaufen, zeigt der opsi-setup-detector auf jeden Fall das Ergebnis an:

Auf diesem Reiter sehen Sie das Ergebnis einer erfolgreichen Analyse.
Abbildung 10. Auf diesem Reiter sehen Sie das Ergebnis einer erfolgreichen Analyse.

Im Detail finden Sie auf dem Reiter 1. Setup die folgenden Informationen und Funktionen:

  • Erkannter Setup Typ: Typ des erkannten Installers

  • Bevorzuge Silent Installation: Aktivieren Sie diese Checkbox, um (wenn möglich) eine Silent-Installation einer Unattended-Installation vorzuziehen.

  • MST erlaubt: Sollen zusätzliche mst-Dateien zum Anpassen der Einstellungen für Microsoft-Windows-Installer-Anwendungen (MSI) verwendet werden?

  • Info: Link, der weiterführende Informationen zum Installer anzeigt

  • Setup Datei: Pfad und Name der analysierten Setup-Datei

  • MST Datei: Zur Angabe der MST-Datei, die in den Installer-Aufruf integriert werden soll

  • MsiId: Produktcode bei MSI-Installern oder Installern, die MSI enthalten

  • MsiName: Produktname bei MSI-Installern oder Installern, die MSI enthalten; in der Registry als DisplayName hinterlegt

  • MsiUpgrade: Upgradecode bei MSI-Installern oder Installern, die MSI enthalten

  • Software Version: Version der zu installierenden Software (falls diese ermittelt werden kann)

  • Setup Datei Größe MB: Größe der Setup-Datei in MByte

  • Benötigter Platz MB: geschätzter Wert (Größe der Setup-Datei mal 6), kann gegebenenfalls angepasst werden

  • InstallDir: Verzeichnis, in das die Software installiert werden wird (sofern dieses erkannt wird); falls nicht korrekt erkannt, können Sie über das Ordner-Icon neben dem Feld einen Dateiauswahl-Dialog öffnen und das Verzeichnis festlegen. Pfade wie C:\program Files bzw. C:\program Files (x86) werden automatisch durch die entsprechenden opsi-script-Konstanten (z. B. %ProgramFiles32Dir%) ersetzt.

  • Kommando zur Installation: ermitteltes Kommando zur nicht-interaktiven Installation; kann abhängig von der Checkbox Bevorzuge Silent Installation unterschiedlich ausfallen

  • Kommando zur Deinstallation: ermitteltes Kommando zur nicht-interaktiven Deinstallation; kann abhängig von der Checkbox Bevorzuge Silent Installation unterschiedlich ausfallen
    Siehe auch: Konfiguration: preferMsiUninstall

  • Deinstallations Programm: ermitteltes Programm zur Deinstallation; falls nicht korrekt erkannt, können Sie über das Ordner-Icon neben dem Feld einen Dateiauswahl-Dialog öffnen und zur gewünschten Anwendung navigieren. MSI-Dateien haben (üblicherweise) kein Deinstallations-Programm.

  • Hauptrogramm: Hauptrogramm der zu installierenden Software; wird verwendet, um z. B. Desktopsymbole oder Einträge fürs Starmenü zu erzeugen. Wird nicht automatisch erkannt. Wenn das Produkt bereits auf dem Rechner installiert ist, können Sie über das Ordner-Icon einen Auswahldialog öffnen.

Alle nach der Analyse ermittelten Werte können Sie bei Bedarf korrigieren und/oder ergänzen. Klicken Sie danach auf die Schaltfläche Nächster Schritt, um den ersten Reiter der Produkt-Konfiguration zu öffnen.

Es ist sehr wahrscheinlich, dass die ermittelten Werte unvollständig oder sogar teilweise falsch sind. Überprüfen Sie nach einer ersten Installation unbedingt die Werte von InstallDir, Deinstallations Programm, Hauptrogramm und Software Version und passen Sie diese gegebenenfalls in Ihrem Skript an!

Produkt-Konfiguration 1

Auf diesem Reiter nehmen Sie die folgenden Einstellungen vor:

Konfigurieren Sie das opsi-Produkt.
Abbildung 11. Konfigurieren Sie das opsi-Produkt.
  • opsi Product ID: Das ist der Name des neuen opsi-Paketes. Er wird aus dem Produktnamen (Feld opsi Product Name) erzeugt, wobei Leer- und Sonderzeichen durch Bindestriche ersetzt werden. Die vorgeschlagene Produkt-ID können Sie verändern.

  • Import control File: Öffnet einen Dateiauswahl-Dialog, um Daten aus einer bestehenden control-Datei (control, control.toml) ins aktuelle Projekt zu importieren. Nicht importiert werden Angaben zu Versionsnummern, Skriptnamen oder dem benötigten Platz.

  • opsi Product Name: Den Namen der zu installierenden Software können Sie hier korrigieren.

  • Produkt Version: Die aus dem Namen der Setup-Datei ermittelte Versionsnummer können Sie hier korrigieren; sie darf nur Ziffern und Punkte enthalten, da sie zur Versionierung des opsi-Paketes verwendet wird.

  • Paket-Version: Die Versionsnummer des opsi-Paketes dient zur Unterscheidung von opsi-Produkten, die dieselbe Software in derselben Version enthalten, aber unterschiedliche Skripte oder Propertys haben. Sie darf nur Ziffern und Punkte enthalten, da sie zur Versionierung des opsi-Paketes verwendet wird.

  • Beschreibung: Tragen Sie in dieses Feld eine kurze Beschreibung der Anwendung ein. Seit opsi 4.3 können Sie Markdown für diesen Text verwenden. Links ist der Editierbereich und auf der rechten Seite die Vorschau.

  • Hinweis: Hier ist Platz für ergänzende Hinweise zur Software, wie z. B. Herkunft, Downloadlink, Lizenz usw. Seit opsi 4.3 können Sie Markdown für diesen Text verwenden. Links ist der Editierbereich und auf der rechten Seite die Vorschau.

  • Template Channel: Wählen Sie aus dem Drop-down-Menü eines der folgenden Templates zur Erstellung der Skripte aus:

    • default: Standard und Fallback; wählen Sie ein anderes Template aus, das die notwendigen Dateien für Ihren Task nicht bereitstellt, so wird automatisch default verwendet. Wesentliche Skripte des Produktes sind: setup.opsiscript, uninstall.opsiscript, declarations.opsiinc, sections.opsiinc und delinc.opsiinc.

    • training: einfacher Aufbau mit ausführlichen Kommentaren; wesentliche Skripte des Produktes sind: setup.opsiscript, uninstall.opsiscript und delinc.opsiinc

    • structured: Fallback zu default; in Version 4.2.2 und darüber nicht verwendet

    • custom: Ist in der Voreinstellung leer und bietet Platz für eigene Template-Dateien. Dazu kopieren Sie Ihre Templates ins Verzeichnis opsi-setup-detector/custom/template-files/ auf dem Depotserver und installieren danach den opsi-setup-detector neu auf den entsprechenden Clients.

Im unteren Fensterbereich finden Sie außerdem einige Checkboxen, über die Sie zusätzlichen Code und Einstellungen für bestimmte Aufgaben ergänzen:

  • Unterstütze custom directory: Das Produkt bekommt ein zusätzliches Verzeichnis namens custom, das (kundenspezifische) Anpassungen enthalten kann. Bei der Installation einer neuen Version des Paketes auf dem Server wird ein solches custom-Verzeichnis nicht überschrieben. Der Code enthält Vorlagen, um Dateien aus diesem Verzeichnis hinzuzufügen (siehe Abschnitt Custom-Verzeichnis).)

  • Installiere von lokalem, temporären Verzeichnis: Die Installations-Dateien werden zunächst in ein lokales, temporäres Verzeichnis kopiert und dann von dort aus installiert. Das ist vor allem sinnvoll für alle Komponenten, die während der Installation die Netzwerkverbindung beeinträchtigen könnten, z. B. Treiber (siehe Abschnitt Lokales, temporäres Verzeichnis).

  • Behandle Lizenzkeys: Erzeugt ein zusätzliches Property zur Behandlung von Lizenzschlüsseln hinzu (siehe Abschnitt Lizenzschlüssel).

  • Desktopicon: Erzeugt ein zusätzliches, boolesches Property (Voreinstellung false) zur Behandlung von Desktopsymbolen hinzu (siehe Abschnitt Desktop-Icon).

  • Customize Profile: Ergänzt den Code um einen Abschnitt ProfileActions für Anpassungen in den lokalen Benutzerprofilen (siehe Abschnitt Lokale Benutzerprofile anpassen).

  • Uninstall_before_install: Erzeugt ein zusätzliches, boolesches Property (Voreinstellung true) zur Steuerung ob vor einer Installation eine Deinstallation durchgeführt werden soll. (siehe Abschnitt Uninstall_before_install).

Priorität und Abhängigkeiten

Auf dem Reiter Produkt Konfiguration 2 können Sie Prioritäten und Abhängigkeiten genauer definieren:

Konfigurieren Sie Prioritäten und Abhängigkeiten.
Abbildung 12. Konfigurieren Sie Prioritäten und Abhängigkeiten.
Bei "normaler" Anwendungssoftware müssen Sie hier in der Regel nichts konfigurieren und können auf Nächster Schritt klicken.

Auf diesem Reiter können Sie folgende Einstellungen vornehmen:

  • Priorität: Beeinflusst die Reihenfolge der Installation; mögliche Werte liegen zwischen 100 (ganz am Anfang) und -100 (ganz am Ende). Für Anwendungssoftware empfohlen: 0. Wenn außerdem Abhängigkeiten existieren, dann beeinflussen diese ebenfalls die Reihenfolge bei der Installation.

  • Abhängigkeiten: Hier können Sie Abhängigkeiten zwischen Produkten definieren. Wenn in der Konfiguration die Zugangsdaten zu Ihrem opsi-Server hinterlegt sind, wird versucht, eine Verbindung zum Server aufzubauen. Haben Sie das Kennwort aus Sicherheitsgründen nicht hinterlegt, dann erfolgt an dieser Stelle die Passwortabfrage (siehe Abschnitt Abhängigkeiten definieren).

Dialog zur Passworteingabe
  • Properties: Hier definieren Sie (veränderbare) Eigenschaften des Produktes (siehe Abschnitt Propertys definieren).

Abhängigkeiten definieren

Klicken Sie auf die Schaltfläche Dependency hinzufügen, um den Dialog Depency Editor zu öffnen:

In diesem Dialog konfigurieren Sie Abhängigkeiten.
Abbildung 13. In diesem Dialog konfigurieren Sie Abhängigkeiten.

Hier können Sie die folgenden Einstellungen vornehmen:

  • Actionrequest zu dem die Abhängigkeit erzeugt werden soll: In der Voreinstellung ist hier setup ausgewählt. Ab opsi 4.3 sind auch andere ActionRequests erlaubt (uninstall, update, always, custom und once). Verwenden Sie diese Einstellung mit Vorsicht, um nicht Bedingungen zu erzeugen, die ohne Widersprüche nicht auflösbar sind!

Das Drop-down-Menü ist nur dann aktiv, wenn Sie in der opsi-setup-detector-Konfiguration die Option dependencies_for_all_actionrequests aktiviert haben (siehe Abschnitt Start und Konfiguration).
  • productId des abhängigen Produkts: Aus dem Drop-down-Menü können Sie das Produkt auswählen, zu dem eine Abhängigkeit besteht. Wenn es eine Verbindung zum opsi-Server gibt, dann zeigt der Dialog dies in grüner Schrift an und listet die installierten Produkte im Menü auf. Besteht die Verbindung nicht, dann sehen Sie einen Hinweis in roter Schrift und müssen die Produkt-ID von Hand eingeben.

  • Abhängigkeits Modus: Wenn Sie ein Meta-Produkt erzeugen, ist dieser Bereich deaktiviert, um unsinnige Einstellungen zu vermeiden. Hier gibt es zwei Optionen zur Auswahl:

    • Aktion: Anforderung für einen ActionRequest, der beim Produkt gesetzt werden soll, zu dem eine Abhängigkeit besteht (setup).

    • Status: Status, den das Produkt haben soll, zu dem eine Abhängigkeit besteht (installed). Liegt ein anderer Status vor, so wird das Produkt auf setup gesetzt.

Die tatsächliche Installations-Reihenfolge ergibt sich aus einer Kombination von Abhängigkeiten und Priorität der Produkte (siehe Abschnitt Abhängigkeiten und Reihenfolge).
Propertys definieren

Auf dem Reiter Produkt Konfiguration 2 können Sie im unteren Bereich veränderbare Eigenschaften (Variablen) für das Produkt definieren. Klicken Sie dazu auf Property hinzufügen:

In diesem Dialog konfigurieren Sie Produkt-Propertys.
Abbildung 14. In diesem Dialog konfigurieren Sie Produkt-Propertys.
Feld/Funktion Beschreibung Hinweise

Property Name

Name der Produkt-Variable

Der opsi-configed zeigt diesen Bezeichner in der Produktkonfiguration an; in Skripten ist der Name mit der Funktion GetProductProperty auslesbar.

Property Type

Typ der Variable

Mögliche Werte sind Text und Boolean.

Multivalue

Anzahl der Werte

Bestimmt, ob die Variable nur genau einen oder mehrere Werte annehmen kann; nur bei Typ Text verfügbar.

Editierbar

Werte überschreibbar

Bestimmt, ob die Vorgabewerte mit neuen oder zusätzlichen Werten überschrieben werden können oder nicht, nur bei Typ Text verfügbar.

Mögliche Werte

Eingabewerte

Durch Kommata getrennte Liste der möglichen Eingabewerte. Falls hier True gesetzt ist, können Sie die Liste später im opsi-configed ergänzen; nur bei Typ Text verfügbar.

Default Wert

Vorgabewert

Auswahlliste; nur bei Typ Text verfügbar: Freitextfeld. Nur bei Typ Multivalue verfügbar: Mehrfachauswahl.

Produkt-Icon auswählen

Auf diesem Reiter können Sie ein Symbol für das Produkt auswählen, das während der Installation angezeigt wird:

In diesem Dialog wählen Sie ein Symbol für Ihr Produkt aus.
Abbildung 15. In diesem Dialog wählen Sie ein Symbol für Ihr Produkt aus.
Wenn Sie diesen optionalen Schritt überspringen, wählt der opsi-setup-detector automatisch ein Zahnrad als Icon aus (Default) und wechselt zum nächsten Reiter.

Klicken Sie in der rechten Fensterhälfte auf die Schaltfläche Öffne Icon Verzeichnis und navigieren Sie im Auswahldialog zum Ordner mit den gewünschten Icons. Als Vorauswahl sehen Sie ein mit dem opsi-setup-detector mitgeliefertes Verzeichnis 128x128 mit Symbolen, die unter einer freien Lizenz stehen. Nach dem Öffnen des Ordners erscheinen in der linken Hälfte alle Symbole, und Sie können eines für Ihr Produkt auswählen.

Produkt erzeugen

Nachdem die Konfiguration des Produktes abgeschlossen ist, können Sie es auf dem letzten Reiter erzeugen:

Auf dem letzten Reiter erzeugen Sie das opsi-Produkt.
Abbildung 16. Auf dem letzten Reiter erzeugen Sie das opsi-Produkt.

Hier stehen die folgenden Optionen zur Verfügung:

  • Pfad zur opsi-work-bench: Hier sehen Sie das bei der Einrichtung konfigurierte Verzeichnis zur Workbench-Freigabe auf Ihrem opsi-Server (Laufwerksbuchstabe oder UNC-Pfad).

  • Über die Schaltfläche Workbench Pfad prüfen können Sie überprüfen, ob die Freigabe erreichbar ist.

  • Im Bereich Erstellungs Modus wählen Sie aus, wie das Paket erstellt wird:

    • Erstelle opsi Produkt Dateien erzeugt (falls noch nicht vorhanden) den Verzeichnisbaum für das neue opsi-Produkt auf der Workbench. Die für das Paket benötigten Dateien werden erzeugt bzw. kopiert.

    • Erstelle opsi Produkt Dateien und baue opsi Paket erzeugt den Verzeichnisbaum und versucht außerdem, das Paket auf dem opsi-Server zu bauen. Ist auf der rechten Seite (Bau Modus) die Checkbox bauen und installieren aktiviert, wird das Produkt nach dem Bauen auch auf dem Server installiert. Wenn Sie in der Konfiguration die Verbindung zum opsi-Webservice eingerichtet haben, wird der Dienst kontaktiert und ggf. nach dem Passwort gefragt.

Das Bauen und Installieren über den Webservice gelingt nur, wenn der opsiconfd in Version 4.2.0.287 oder neuer vorliegt. Ist der Service nicht erreichbar oder zu alt, dann übernimmt der opsi PackageBuilder (ohne GUI) und erstellt das Paket.
  • Erstelle opsi Produkt Dateien und starte interaktiven Packagebuilder erzeugt (falls noch nicht vorhanden) den Verzeichnisbaum für das neue opsi-Produkt auf der Workbench und startet den opsi PackageBuilder im interaktiven Modus. Diesen müssen Sie explizit beenden, um zum opsi-setup-detector zurückzukehren.

    • Bau Modus: Die beiden Optionen bestimmen, was bei einem Klick auf opsi Paket erstellen tatsächlich passiert:

  • nur bauen erzeugt das opsi-Paket (entspricht dem Befehl opsi-makepackage).

  • bauen und installieren erzeugt das opsi-Paket (opsi-makepackage) und installiert dieses (entspricht dem Befehl opsi-package-manager --install <paket>).

    • opsi Paket erstellen: Per Klick auf diesen Button starten Sie die Paketerstellung. Gibt es bereits ein opsi-Produkt mit demselben Namen, dann erscheint eine Sicherheitsabfrage:

Backup-Dialog
  • Nur Paket neu bauen: Dieser Button startet das Bauen des opsi-Paketes, ohne vorher die opsi-Dateien neu zu erzeugen. Die Option eignet sich also dazu, ein Paket neu zu bauen, nachdem Sie in einem Editor Änderungen am Skript vorgenommen haben.

Beim Erstellen des opsi-Produktes schreibt der opsi-setup-detector alle Informationen, die Sie dort hinterlegt haben, in die Datei opsi-project.osd im Hauptverzeichnis des Produktes.

Eine solche opsi-project.osd-Datei können Sie zu einem späteren Zeitpunkt wieder mit dem opsi-setup-detector öffnen, um ein vorhandenes Paket zu modifizieren.

Vorhandenes Projekt öffnen

Es gibt zwei Möglichkeiten, eine bestehende Projektstruktur mit dem opsi-setup-detector als Projekt zu öffnen:

  • Wenn das Produkt mit dem opsi-setup-detector erstellt wurde, dann können Sie aus dem Menü Datei / Öffnen und die Datei opsi-project.osd aus dem Hauptverzeichnis des Projektes öffnen.

  • Bei Produkten, die nicht mit dem opsi-setup-detector erstellt wurden, können Sie stattdessen die control-Datei (control, control.toml) öffnen. Wählen Sie dazu aus dem Menü Datei / Controldatei öffnen und navigieren zur control-Datei im Verzeichnis OPSI des Produktes.

Letzteres bietet weniger Informationen, insbesondere in Bezug auf die verwendete Setup-Datei des Installers.

Skript testen und verbessern

Zum Testen und Verbessern eines Produktes gibt es zwei verschiedene Varianten:

  • Sie testen das erstellte Skript, ohne es auf dem opsi-Server zu installieren und auf dem Client auszurollen (Standalone-Tests).

  • Sie testen das komplette Produkt, indem Sie es auf dem Server installieren und auf einem Client ausrollen (Integrierte Tests).

Wir gehen im Folgenden davon aus, dass Sie das zu testende Produkt mit dem opsi-setup-detector erstellt haben.

Standalone-Tests

Starten Sie die Anwendung opsi-script-gui:

  • Windows: Öffnen Sie opsi-script.exe per Doppelklick. Wenn der Client-Agent auf dem Rechner installiert ist, finden Sie das Programm unter C:\Program files (x86)\opsi.org\opsi-client-agent\opsi-script\opsi-script.exe. Andernfalls kopieren Sie den Inhalt des Verzeichnisses opsi-script\windows\x86\ von der Freigabe \\<opsiserver>\opsi_depot auf den Windows-Rechner.

Unter Windows 10 klicken Sie die Datei opsi-script.exe mit der rechten Maustaste im Explorer an und wählen aus dem Kontextmenü den Eintrag Ausführen als Administrator.
  • Linux: Starten Sie /opt/opsi-script/opsi-script-gui.

  • macOS: Starten Sie die Anwendung über das Menü /Applications/opsi-script.

Nach dem Start sehen Sie das folgende Fenster:

Öffnen Sie *opsi-script-gui* im interaktiven Modus.
Abbildung 17. Öffnen Sie opsi-script-gui im interaktiven Modus.

Wählen Sie über Select Script das Skript, das Sie testen möchten. Klicken Sie anschließend auf Start. Das Skript wird nun auf diesem Rechner ausgeführt. Alternativ klicken Sie auf Test_Syntax, um das Skript auf Syntaxfehler zu prüfen. Es wird dabei nicht auf dem Rechner ausgeführt (siehe Abschnitt Skript-Syntax prüfen).

Mit dem opsi-logviewer können Sie nun nachvollziehen, wie opsi-script das Skript interpretiert.

Über den Schieberegler rechts unten im opsi-logviewer können Sie den Loglevel verändern und damit mehr oder weniger Details einblenden.

Falls Sie das Skript verändern möchten, können Sie es in einem Texteditor bearbeiten:

  • Öffnen Sie das Projekt im opsi PackageBuilder und rufen den Editor auf.

  • Verwenden Sie einen Texteditor wie beispielsweise jEdit mit opsi-script-Syntax-Highlighting, wie Sie ihn in der Grundausstattung der opsi-Produkte finden.

Der Texteditor jEdit unterstützt Syntax-Highlighting für *opsi-script*-Skripte.
Abbildung 18. Der Texteditor jEdit unterstützt Syntax-Highlighting für opsi-script-Skripte.

Sie können die Änderungen nun speichern (und den Editor geöffnet lassen). Wechseln Sie zum opsi-script-Fenster zurück und drücken Sie erneut den Start_Button; Sie müssen das Skript nicht erneut auswählen. Schauen Sie sich die Änderungen im opsi-logviewer an; dazu wählen Sie _Neu laden aus dem Kontextmenü der rechten Maustaste oder über den Button in der Symbolleiste.

Um Ihre Skripte weiter anzupassen, können Sie die Punkte wiederholen:

  1. Skript im Editor bearbeiten und Änderungen speichern

  2. Skript (erneut) in opsi-script ausführen

  3. Logdatei kontrollieren

Integrierte Tests

Bei den integrierten Tests rollen Sie das Produkt auf einem Testclient aus:

  • Öffnen Sie das Skript setup.opsiscript in einem Editor und nehmen Sie ggf. Änderungen vor; speichern Sie die Änderungen:

    • Öffnen Sie das Projekt im opsi PackageBuilder und rufen den Editor auf.

    • Verwenden Sie einen Texteditor wie beispielsweise jEdit mit opsi-script-Syntax-Highlighting, wie Sie ihn in der Grundausstattung der opsi-Produkte finden.

  • Packen Sie das Produkt:

    • Variante 1: Öffnen Sie das Projekt im opsi PackageBuilder und klicken auf den Button Packen.

    • Variante 2: Öffnen Sie ein Terminal auf dem opsi-Server oder melden sich per SSH an, z. B. mit PuTTY. Wechseln Sie zur Workbench (/var/lib/opsi/workbench) und dann ins Verzeichnis des Projektes. Rufen Sie den folgenden Befehl zum Packen auf:
      opsi-makepackage

  • Installieren Sie das Produkt auf dem opsi-Server:

    • Variante 1: Klicken Sie auf den Button Installieren im opsi PackageBuilder.

    • Variante 2: Rufen Sie im Projektverzeichnis im Terminal den folgenden Befehl auf:
      opsi-package-manager -i <myproctid_version.opsi>
      Ersetzen Sie <myproctid_version.opsi> durch den Namen des opsi-Paketes (wie er beim Packen ausgegeben wurde).

  • Rollen Sie das Produkt über die Management-Oberfläche opsi-configed aus:

    1. Wählen Sie auf dem Reiter Clients den Testclient aus.

    2. Wählen Sie auf dem Reiter Localboot-Produkte das Produkt aus. Sollte Ihr opsi-Paket dort nicht auftauchen (was nach dem ersten Installieren normal ist), drücken Sie den Button ganz links in der Symbolleiste oder wählen Sie aus dem Menü Datei / Alle Daten neu laden.

    3. Setzen Sie das Produkt auf setup und speichern Sie die Änderungen.

    4. Starten Sie den Client oder rufen Sie für laufende Clients aus dem Kontextmenü on_demand auf.

    5. Warten Sie, bis die Installation des Produktes auf dem Client durchgelaufen ist.

    6. Wechseln Sie zum Reiter Logfiles und dort zu instlog und betrachten Sie die Logdatei.

Über den Schieberegler rechts unten können Sie den Loglevel verändern und damit mehr oder weniger Details einblenden.

Um Ihre Skripte weiter anzupassen, können Sie die Punkte wiederholen:

  1. Skript im Editor bearbeiten und Änderungen speichern

  2. Produkt packen

  3. Produkt auf dem Server installieren

  4. Produkt auf dem Client ausrollen

  5. Logdatei kontrollieren

opsi PackageBuilder: Skript modifizieren

Starten Sie den opsi PackageBuilder (oPB) aus dem Startmenü. Sollte das nicht funktionieren (beobachtet unter Linux mit KDE-Desktopumgebung), starten Sie das Programm aus einem Terminal heraus. Geben Sie einen beliebigen Pfad an und bestätigen die Fehlermeldung, dass der Pfad nicht gefunden wurde:

opsipackagebuilder --path /home

Beim ersten Start befindet sich der opsi PackageBuilder im Offlinemodus, da die Verbindung zum opsi-Server noch fehlt:

opsi PackageBuilder: Erster Start im Offlinemodus
Abbildung 19. opsi PackageBuilder: Erster Start im Offlinemodus

Initiale Konfiguration

Klicken Sie auf die Schaltfläche Einstellungen, um das Programm opsi PackageBuilder zu konfigurieren.

Auf dem Reiter Allgemein nehmen Sie die folgenden Einstellungen vor:

  • Konfigserver: Tragen Sie den vollständigen Namen (FQDN) Ihres opsi-Configservers ein (z. B. opsi.mycompany.org).

  • opsiadmin Benutzer: Hier steht der Name eines Benutzers, der administrativ auf den opsi-Service zugreifen darf; der Account muss Mitglied der Gruppe opsiadmin sein (siehe Abschnitt Benutzer und Gruppen).

  • opsiadmin Passwort: Tragen Sie hier das dazugehörige Passwort ein. Dieses wird nicht angezeigt und verschlüsselt gespeichert. Das Kennwort ist zwingend erforderlich, damit der opsi PackageBuilder mit dem opsi-Server kommunizieren kann.

  • 4.0.4 oder neuer: Aktivieren Sie diese Checkbox.

  • SUDO ohne Passwort: Das ist die Voreinstellung; übernehmen Sie diese.

  • Betreuer: Tragen Sie hier Ihren vollständigen Namen ein; er wird in den Changelogs verwendet.

  • EMail: Hier gehört Ihre Mailadresse hin, sie wird in den Changelogs verwendet.

oPB-Einstellungen: Reiter *Allgemein*
Abbildung 20. oPB-Einstellungen: Reiter Allgemein

Auf dem Reiter Programm nehmen Sie die folgenden Einstellungen vor:

  • Aktivieren Sie die Checkbox Erweiterten Changelog Editor verwenden.

  • Wählen Sie einen Entwicklungsordner aus; tragen Sie den vollständigen Pfad zum Verzeichnis ein, in dem die opsi-Pakete erstellt werden sollen. Idealerweise ist das der Pfad zur gemounteten Freigabe mit der opsi-Workbench. Optional können Sie dazu ein Bestehendes Netzlaufwerk verwenden.

  • Skripteditor: Wählen Sie den Texteditor zur Bearbeitung der Skripte aus:

    • Windows: übernehmen Sie die Voreinstellung (Pfad zum oPB-ScriptEditor)

    • Linux: Pfad zum Editor, z. B. /usr/bin/jedit; Feld Kommandozeilenoption bleibt leer

    • macOS: Pfad zum Editor, z. B. /Application/jedit; Feld Kommandozeilenoption bleibt leer

oPB-Einstellungen: Reiter *Programm*
Abbildung 21. oPB-Einstellungen: Reiter Programm

Auf dem Reiter opsi Verwaltungsbefehle nehmen Sie die folgende Einstellungenq (abweichend von den Voreinstellungen) vor:

  • Paketieren: Tragen Sie in dieses Feld den Befehl zum Bauen des Paketes ein:
    opsi-makepackage -v

  • Aktivieren Sie die Checkbox Depotfunktionen aktivieren.

oPB-Einstellungen: Reiter *opsi Verwaltungsbefehle*
Abbildung 22. oPB-Einstellungen: Reiter opsi Verwaltungsbefehle

Speichern Sie die Einstellungen und starten Sie den opsi PackageBuilder neu. Das Programm sollte sich nun im Onlinemodus befinden.

opsi PackageBuilder: Start im Onlinemodus
Abbildung 23. opsi PackageBuilder: Start im Onlinemodus

Pakete modifizieren, packen und Installieren

Zum Modifizieren eines Paketes klicken Sie auf den Button Paket öffnen (F2) und navigieren zum Verzeichnis, das der opsi-setup-detector erstellt hat (z. B. w:\develop\newprod2). Es öffnet sich der folgende Dialog:

Öffnen Sie ein vorhandenes opsi-Paket.
Abbildung 24. Öffnen Sie ein vorhandenes opsi-Paket.

Auf dem Reiter Paket sehen Sie die Metadaten des opsi-Produktes in der linken Spalte (siehe Abschnitt Produkt-Konfiguration 1). Auf der rechten Seite stehen die Skriptdateien. Daneben befindet sich jeweils dieser Button:

oPB: *Edit*-Button
Abbildung 25. oPB: Edit-Button

Wenn Sie diesen Button anklicken, öffnet sich der in der Konfiguration definierte Editor zum Modifizieren des Skriptes. Unter Windows ist das der oPB-ScriptEditor, der unter anderem farbige Syntax-Hervorhebung, Falten des Quellcodes (optional: kompakt, mit Kommentaren), anpassbare Lexerdefinition (dazu muss der Editor über das Startmenü aufgerufen werden), automatische Vervollständigung für Syntax-Elemente und Variablen und frei definierbare und wiederverwendbare Codeblöcke (Snippets) unterstützt.

Die Kernkomponente des Editors ist das Modul Scintilla, das auch andere bekannte Texteditoren (Notepad\++, CodeLite usw.) verwenden. Die lexikalischen Elemente (Syntax-Hervorhebung und Faltung) für opsi-Skripte sind allerdings in AutoIt geschrieben, da Scintilla für diese kein eigenes Highlighting mitbringt. Da AutoIt eine Interpreter-Sprache ist, ist der ScriptEditor langsamer als andere Editoren und eignet sich daher nur bedingt zur Bearbeitung sehr großer Skripte (vor allem bei aktivierter Faltung des Codes).

In den Einstellungen können Sie vorgeben, ob der Editor mit diesen Funktionen aufgerufen wird oder nicht (sofern er aus dem oPB heraus gestartet wird). Bei einem Aufruf über das Startmenü sind Syntax-Hervorhebung und Faltung deaktiviert. Sie können diese bei Bedarf über das Menü Ansicht einschalten.

Den Editor können Sie über die Kommandozeile aufrufen und dabei bestimmte Optionen direkt vorgeben. Weitere Informationen zu den möglichen Parametern blenden Sie über die Option --help ein.

Auf dem Reiter Abhängigkeiten sehen Sie die definierten Abhängigkeiten zu anderen opsi-Produkten (siehe Abschnitt Priorität und Abhängigkeiten):

oPB: Reiter *Abhängigkeiten*
Abbildung 26. oPB: Reiter Abhängigkeiten

Auf dem Reiter Produktvariablen stehen links jeweils die Produkt-Propertys, inklusive Typ, Wert usw:

oPB: Reiter *Produktvariable*
Abbildung 27. oPB: Reiter Produktvariablen

Am unteren Fensterrand sehen Sie die folgenden Schaltflächen:

Button Bedeutung

image::common:opb_btnPacken.png[]

Startet eine eine SSH-Verbindung zum opsi-Server und ruft dort das Kommando zum Paketieren auf (siehe Abschnitt opsi-makepackage: Produkt packen).

image::common:opb_btnInstallieren.png[]

Startet eine eine SSH-Verbindung zum opsi-Server und ruft dort das Kommando zum Installieren auf (siehe Abschnitt opsi-package-manager: Produkt installieren).

image::common:opb_InstSetup.jpg[]

Ähnlich wie Installieren, allerdings wird das Paket zusätzlich auf allen Clients, auf denen es als installed gekennzeichnet ist, auf setup gesetzt.

Verwenden Sie die Schaltfläche Inst.+Setup ist nur mit äußerster Vorsicht und wenn Sie genau wissen, was Sie tun!

opsi-makepackage: Produkt packen

Um das Produkt zu packen, wechseln Sie ins Hauptverzeichnis des Produktes und rufen das Kommando opsi-makepackage.

Es ist empfehlenswert, gleichzeitig eine dazugehörige MD5-Prüfsummendatei zu erzeugen. Diese Datei nutzen unter anderem Tools wie opsi-package-updater, um die Integrität des Paketes nach einer Übertragung sicherzustellen.

In der Voreinstellung erzeugt opsi-makepackage eine solche MD5-Prüfsummendatei. Falls Sie die Funktion deaktivieren möchten, verwenden Sie diesen Parameter beim Aufruf:

opsi-makepackage --no-md5

Beim Übertragen von Paketen auf opsi-Depotserver nutzt opsi-makepackage das Tool zsync. Es überträgt lediglich die Unterschiede der Pakete und spart damit Bandbreite. Dazu ist eine .zsync-Datei erforderlich, die opsi-makepackage automatisch erstellt. Falls das nicht gewünscht ist, deaktivieren sie das Feature so:

opsi-makepackage --no-zsync

Wenn es beim Erstellen großer Pakete zu Platzproblemen im temporären Verzeichnis /tmp kommt, können Sie hinter --temp-directory ein abweichendes temporäres Verzeichnis angeben.

opsi-makepackage schaut außerdem vor dem Bauen nach, ob es im Verzeichnis schon ein Paket mit gleichem Namen bzw. mit derselben Versionsnummer gibt. Das Tool fragt in dem Fall nach, wie Sie weiter vorgehen möchten:

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:

Drücken Sie [O], um das Paket zu überschreiben; mit [C] brechen Sie den Vorgang ab, und wenn Sie [N] drücken, können Sie anschließend eine neue Versionsnummer angeben.

Weitere Informationen zum Tool opsi-makepackage und seinen Parametern finden Sie in Abschnitt opsi-makepackage.

opsi-package-manager: Produkt installieren

Mit dem Befehl opsi-package-manager installieren Sie opsi-Produkte. Wechseln Sie dazu ins Hauptverzeichnis des Produktes und rufen Sie dieses Kommando auf:

opsi-package-manager -i <myproductid_version.opsi>
Weitere Informationen zum Tool opsi-package-manager und seinen Parametern finden Sie in Abschnitt opsi-package-manager.

Beispiel: control-Datei

Seit opsi 4.3 ist es möglich, eine control-Datei im TOML-Format zu erzeugen. Gibt es eine solche Datei control.toml, dann ist diese maßgeblich und muss gepflegt werden.

control file in opsi ⇐ 4.2 style:
[Package]
version: 1
depends:

[Product]
type: localboot
id: mytest
name: My Test
description: A test product
advice:
version: 3.14
priority: 10
licenseRequired: False
productClasses:
setupScript: setup.ins
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
control file in opsi >= 4.3 .toml style:
[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]
Stand-alone changelog entry: changelog.txt file
mytest (3.14-1)

  * Initial package

-- jane doe <j.doe@opsi.org> Di, 29 Aug 2023 10:36:09

opsi-newprod: Produkt erstellen

Außer den in diesem Kapitel vorgestellten grafischen Programmen zum Erstellen von opsi-Produkten gibt es das Kommandozeilentool opsi-newprod, das ein Gerüst für opsi-Produkte erzeugt. Nach dem Start fragt es zuerst nach, ob Sie ein Localboot- oder Netboot-Produkt erstellen möchten.

Für Produkte, die Sie über den Client-Agent bzw. opsi-script installieren, ist localboot die richtige Wahl. Der Typ netboot eignet sich für Produkte, die Sie über das opsi-Linux-Bootimage ausführen, z. B. Betriebssystem-Installationen.
Wählen Sie zuerst den Typ des opsi-Produktes aus.
Abbildung 28. Wählen Sie zuerst den Typ des opsi-Produktes aus.

Navigieren Sie mit der Taste [Tab] zu OK oder bestätigen Sie Ihre Wahl über [F12]. Im nächsten Dialog geben Sie die Daten zum neuen opsi-Produkt ein:

Geben Sie Informationen zum Produkt ein.
Abbildung 29. Geben Sie Informationen zum Produkt ein.

In die Felder tragen Sie die folgenden Werte ein:

  • Produkt-ID: Das ist ein eindeutiger Bezeichner für das Produkt und in der Regel unabhängig von der Version. Verwenden Sie nur Kleinbuchstaben, keine Umlaute, keine Leer- und Sonderzeichen; der Bindestrich - ist als Trennzeichen erlaubt.

  • Produkt-Name: Hier steht der Name des Produktes; wir empfehlen die Vermeidung von Umlauten.

  • Beschreibung: Hier ist Platz für ergänzende Informationen zum Produkt, die dann beispielsweise der opsi-configed unter Beschreibung anzeigt.

  • Hinweis: Falls Sie weitere Hinweise, etwa zum Umgang mit dem Produkt, unterbringen möchten, ist hier der Ort. Der opsi-configed zeigt diese unter Notiz an.

  • Produkt-Version: Die Version der gepackten Software steht hier; es sind maximal 32 Zeichen erlaubt.

  • Paket-Version: Das ist die Version des Paketes für die Produktversion. Sie dient dazu, Pakete mit gleicher Produktversion, aber z. B. korrigiertem opsi-script-Skript zu unterscheiden.

  • Lizenz benötigt: Das hat bei Localboot-Produkten keinen Einfluss. Bei Netboot-Produkten entscheidet diese Option, ob ein Lizenzschlüssel aus dem Lizenzmanagement geholt wird.

  • Priorität: Der Wert beeinflusst die Installations-Reihenfolge; mögliche Werte liegen zwischen 100 (ganz am Anfang) und -100 (ganz am Ende). Wenn es zusätzlich Abhängigkeiten zu anderen Produkten gibt, beeinflussen diese ebenfalls die Reihenfolge.

Als Nächstes geben Sie die Skripte an, die Sie für die unterschiedlichen Aktionen bereitstellen:

Geben Sie die Namen der Skripte ein.
Abbildung 30. Geben Sie die Namen der Skripte ein.

In die Felder tragen Sie Folgendes ein:

  • Setup-Skript: Normalerweise ist das setup.ins.

  • Uninstall-Skript: Normalerweise ist das uninstall.ins.

  • Update-Skript: Das Skript dient zur geringfügigen Veränderung einer existierenden großen Installation. Wird das Produkt auf setup gestellt, so wird nach dem Abarbeiten des Setup-Skriptes automatisch das Update-Skript ausgeführt.

  • Always-Skript: Dieses Skript läuft bei jeder Aktivierung des Client-Agent, z. B. nach jedem Bootvorgang.

  • Once-Skript: Das Skript hat den Folgestatus not_installed. Das ist ein sehr selten verwendeter Schalter, den Sie ignorieren sollten, wenn Sie nicht genau wissen, was Sie damit tun wollen.

  • Custom-Skript: Ein solches Skript verändert weder die Folgeaktion noch den Folgestatus. Es handelt sich hierbei um einen sehr selten verwendeten Schalter, den Sie ignorieren sollten, wenn Sie nicht genau wissen, was Sie damit tun wollen.

  • Benutzer-Anmeldung-Skript: Es dient dazu, nach der Anmeldung des Benutzers Modifikationen am Profil des eingeloggten Accounts vorzunehmen. Das funktioniert nur, wenn Sie die Erweiterung User Profile Management verwenden.

Typ Folgestatus Folgeaktion

setup

installed

none

uninstall

not_installed

none

update

installed

none

always

installed

always

once

not_installed

none

custom

unverändert

unverändert

User login

unverändert

unverändert

Nachdem nun das Produkt beschrieben ist, können Sie eine oder mehrere Abhängigkeiten zu anderen Produkten definieren. Andernfalls springen Sie zu Nein.

Wollen Sie eine Abhängigkeit definieren?
Abbildung 31. Wollen Sie eine Abhängigkeit definieren?

Wenn Sie Ja gewählt haben, dann erscheint dieser Dialog:

Definieren Sie die Produktabhängigkeit genau.
Abbildung 32. Definieren Sie die Produktabhängigkeit genau.

In die Felder tragen Sie Folgendes ein:

  • Abhängigkeit für die Aktion: Hier steht die Aktion des Produktes (das Sie gerade erstellen), für die die Abhängigkeit gilt (Seit opsi 4.3: nicht nur setup).

  • Benötigte Produkt-ID: Tragen Sie die ID (Bezeichner) des Produktes ein, zu dem eine Abhängigkeit besteht.

  • Benötigte Aktion: Sie können entweder die Aktion setup oder (siehe unten) den Status installed anfordern.

  • Benötigter Installations-Zustand: Hier steht der Status, den das Produkt, zu dem eine Abhängigkeit besteht, haben soll (installed). Liegt ein anderer Status vor, so wird das Produkt auf setup gesetzt.

  • Typ der Abhängigkeit: Hier geht es um die Installations-Reihenfolge: Wenn das Produkt, zu dem eine Abhängigkeit besteht, installiert sein muss, bevor mit der Installation des aktuellen Produktes begonnen werden kann, dann steht hier before. Muss es nach dem aktuellen Produkt installiert werden, steht hier after. Lassen Sie das Feld leer, wenn die Reihenfolge egal ist.

Die tatsächliche Installations-Reihenfolge ergibt sich aus einer Kombination von Produktabhängigkeiten und den Prioritäten (siehe Abschnitt opsi-setup-detector: Priorität und Abhängigkeiten).

Als Nächstes geht es um die Propertys. opsi-newprod fragt nach:

Wollen Sie Produkt-Propertys definieren?
Abbildung 33. Wollen Sie Produkt-Propertys definieren?

Die Produkteigenschaft wird clientspezifisch gespeichert und besteht aus einem Namen (Key), der verschiedene Werte (Values) haben kann. Das opsi-script-Skript fragt diese dann ab. Als Erstes entscheiden Sie, ob es sich um einen Textwert (unicode) oder um einen logischen Wert (boolean) handelt:

Wählen Sie den Datentyp der Produkteigenschaft.
Abbildung 34. Wählen Sie den Datentyp der Produkteigenschaft.

Wenn Sie unicode gewählt haben, füllen Sie danach die folgenden Felder aus:

  • Eigenschafts-Name (identifier): Tragen Sie den Property-Namen ein.

  • Eigenschafts-Beschreibung: Diesen Text zeigt unter anderem der opsi-configed als Hilfe an.

  • Mögliche Werte: Geben Sie eine durch Kommata getrennte Liste alle Werte an, die der Key annehmen darf. Wenn Sie das Feld leer lassen, dann können Sie später im opsi-configed einen beliebigen Wert eingeben.

  • Editierbar: Entscheiden Sie, ob neben der von Ihnen vorgegebenen Liste auch andere Werte eingegeben werden dürfen; hier steht True oder False.

Enthält ein Wert einen Backslash \, so muss dieser doppelt angegeben werden. Eine Pfadangabe sieht dann beispielsweise so aus: C:\\temp
In diesem Dialog beschreiben Sie die Produkteigenschaften.
Abbildung 35. In diesem Dialog beschreiben Sie die Produkteigenschaften.

Im nächsten Fenster legen Sie den Standardwert des Propertys fest.

Wenn Sie anstelle von unicode den Typ boolean ausgewählt haben, sieht der Dialog anders aus. Sie können jetzt lediglich einen Namen und eine Beschreibung eingeben:

Tragen Sie den Namen und eine Beschreibung ein.
Abbildung 36. Tragen Sie den Namen und eine Beschreibung ein.

Produkt-Propertys können Sie beliebig oft definieren. Erst wenn Sie die Frage Wollen Sie eine Produkt-Eigenschaft definieren? verneinen, dann erscheint der nächste und letzte Dialog. Geben Sie hier Ihren Namen und die Mailadresse ein; diese werden im Changelog verwendet und sind obligatorisch.

Als Letztes geben Sie die Daten des Betreuers ein.
Abbildung 37. Als Letztes geben Sie die Daten des Betreuers ein.

Danach ist das Grundgerüst des Produktes fertig. Im neuen Verzeichnis finden Sie im Kapitel bereits beschriebenen Dateien und Verzeichnisse. Wechseln Sie in den Ordner OPSI und listen Sie den Inhalt auf (ls). Die Datei control enthält nun die Daten, die Sie gerade definiert haben, und Sie können die Datei in einem Editor öffnen, um die Einträge anzusehen oder zu ändern.

Bei opsi >= 4.3 erzeugt opsi-newprod eine Kontrolldatei im TOML-Format (.toml) und eine eigenständige Datei changelog.txt.

Erweiterte Konfiguration mit opsi-setup-detector

Die folgenden Abschnitte zeigen weitere Konfigurationsmöglichkeiten des opsi-setup-detector. Sie behandeln die Verwendung eines benutzerdefinierten Verzeichnisses, die Installation aus einem lokalen temporären Verzeichnis, die Verwaltung von Lizenzschlüsseln und die Anpassung von Benutzerprofilen und Desktopsymbolen.

Custom-Verzeichnis

Auf dem Reiter Produkt Konfiguration 1 sehen Sie im unteren Bereich die Checkbox Unterstütze custom directory. Aktivieren Sie diese, und das Produkt erhält ein zusätzliches Verzeichnis namens custom. Hier können kundenspezifische Anpassungen landen — bei einem Upgrade auf eine neue Paketversion bleibt das vorhandene Verzeichnis custom unverändert. Der Code enthält Vorlagen, um Dateien aus diesem Verzeichnis in die Installation einzufügen.

In die Datei setup.opsiscript wird Folgendes eingefügt:

; copy custom files to install dir
Files_copy_from_custom_dir

Das ruft eine Files-Sektion auf, um Dateien aus einem custom-Verzeichnis auf den Client zu kopieren. Die dazugehörige Sektion sieht so aus:

[Files_copy_from_custom_dir]
copy -s "%scriptPath%\custom\*" "$installdir$"

In diesem Beispiel wird der Inhalt das custom-Verzeichnisses in das Installations-Verzeichnis kopiert. Außerdem wird das custom-Verzeichnis selbst erzeugt. Es erhält die beiden Dateien OPSI\preinst und OPSI\postinst. Sie sorgen dafür, dass der Inhalt des Verzeichnisses auf dem Depot auch bei Aktualisierungen erhalten bleibt.

Lokales, temporäres Verzeichnis

Der opsi-setup-detector hat auf dem Reiter Produkt Konfiguration 1 die Checkbox Installiere von lokalem, temporären Verzeichnis. Aktivieren Sie diese, und die Installations-Dateien werden zunächst in ein lokales, temporäres Verzeichnis kopiert und dann aus diesem heraus installiert. Das Feature bietet sich beispielsweise an, wenn eine Installation die Netzwerkverbindung beeinträchtigen könnte, z. B. bei Treibern.

Der opsi-setup-detector erzeugt dann ein zusätzliches boolesches Property install_from_local_tmpdir, das in der Voreinstellung auf false steht und diese Beschreibung erhält: Bestimmt, ob die Installationsdateien nach lokal kopiert werden.

In die Datei setup.opsiscript wird Folgendes eingefügt:

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

Jetzt werden die Installations-Dateien vorübergehend in ein temporäres Verzeichnis verschoben und nach der Installation gelöscht, wenn die Bedingung Install_from_local_tmpdir auf true gesetzt ist.

Die dazugehörigen Sektionen sehen so aus:

; 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$\"

Lizenzschlüssel

Der opsi-setup-detector enthält auf dem Reiter Produkt Konfiguration 1 die Checkbox Behandle Lizenzkeys. Wenn Sie diese aktivieren, werden Property und Code zur Behandlung von Lizenzschlüsseln hinzugefügt.

Es wird ein zusätzliches Property namens secretlicense_or_pool erzeugt; es ist in der Voreinstellung leer und trägt diese Beschreibung: Lizenzkey oder opsi Lizenzpool. Das Schlüsselwort secret im Property-Namen führt dazu, dass im opsi-configed der Wert des Propertys nur maskiert angezeigt wird.

In die Datei setup.opsiscript wird Folgendes eingefügt:

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

Der Aufruf von get_licensekey_byPoolOrKey prüft, ob der Wert des Propertys der Name eines Lizenzpools aus der opsi-Erweiterung Lizenzmanagement ist. Falls ja, so wird ein Lizenzschlüssel aus diesem Pool bezogen. Falls nein, so wird der Property-Inhalt als Lizenzschlüssel geliefert.

In die Datei uninstall.opsiscript wird Folgendes eingefügt:

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

Der opsi-setup-detector enthält auf dem Reiter Produkt Konfiguration 1 die Checkbox DesktopIcon. Aktivieren Sie diese, um Property und Code zur Behandlung von Desktopsymbolen hinzuzufügen.

Es wird dann ein zusätzliches boolesches Property namens desktopicon erzeugt, in der Voreinstellung steht es auf false und hat diese Beschreibung: Soll es ein Desktopicon geben?.

In die Datei setup.opsiscript wird folgender Code eingefügt:

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

Falls desktopicon auf true steht, wird eine Sektion Linkfolder aufgerufen. Der dazugehörige Code (der auch in die Datei uninstall.opsiscript eingefügt wird) sieht so aus:

[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

In die Datei delinc.opsiinc werden außerdem diese beiden Zeilen eingefügt:

comment "Start Remove Desktop Icon Handling :"
Linkfolder_remove_desktop_icon

Lokale Benutzerprofile anpassen

Der opsi-setup-detector enthält auf dem Reiter Produkt Konfiguration 1 die Checkbox Customize Profile. Aktivieren Sie diese, und der Code wird ergänzt um eine Sektion Profileactions. Sie nimmt Anpassungen an den lokalen Benutzerprofilen vor. Diese Funktionalität wird auch über ein Loginskript für Roaming Profiles bereitgestellt.

Über die Datei OPSI/control wird das setup.opsiscript nicht nur als setupScript, sondern auch als userLoginScript bereitgestellt.

In die Datei setup.opsiscript wird Folgendes eingefügt:

; Run the customization for user profiles
ProfileActions

Der Code ruft eine ProfileActions-Sektion auf. Diese wird je nach Aufruftyp für alle lokalen Profile oder für den gerade eingeloggten Benutzer ausgeführt (siehe auch Kapitel User Profile Management).

Die dazugehörigen Sektionen, die als Templates für Aufrufe zur Manipulation der User Profiles dienen, sehen so aus:

[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

Der opsi-setup-detector enthält auf dem Reiter Produkt Konfiguration 1 die Checkbox Uninstall_before_install. Aktivieren Sie diese zur Steuerung ob vor einer Installation eine Deinstallation durchgeführt werden soll.

Es wird dann ein zusätzliches boolesches Property namens uninstall_before_install erzeugt, in der Voreinstellung steht es auf true und hat diese Beschreibung: Soll ein Property "uninstall_before_install" und der entsprechende Code hinzugefügt werden ?.

In die Datei setup.opsiscript wird folgender Code eingefügt:

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 mit angemeldetem Benutzer

Vereinzelt taucht das Problem auf, dass sich Installationen nur bei angemeldetem Benutzer durchführen lassen. Ein möglicher Hinweis auf dieses Problem ist, dass der manuelle Aufruf eines opsi-script-Skriptes mit Anweisungen zu einem Unattended- oder Silent-Setup funktioniert, im Rahmen der automatischen Installation über opsi jedoch scheitert.

Eine mögliche Ursache kann sein, dass dieses Setup-Programm einen angemeldeten Benutzer bzw. den Zugriff auf ein Benutzer-Profil benötigt. In einem solchen Fall können Sie Ihre Installation in ein opsi-Paket einbinden, das diese benötigten Voraussetzungen schafft. Sie erstellen ein solches Paket beispielsweise im opsi-setup-detector über die Windows-Aufgabe Analysiere Datei und erzeuge ein Paket 'with user'.

Unattended-/Silent-Setup anpassen

Häufig will man nach einer erfolgreichen Silent-Installation Anpassungen an der Installation vornehmen, was mit opsi-script kein Problem ist. Vorher müssen Sie allerdings ermitteln, welche der in der grafischen Oberfläche gemachten Änderungen zu welchen Veränderungen in Dateien und in der Windows Registry führen.

Dazu benötigen Sie Werkzeuge wie beispielsweise diese hier:

Setup mit automatisierten Antworten

Eine weitere schnelle Möglichkeit zur Einbindung in die automatische Softwareverteilung ist das Setup mit automatisierten Antworten. Dazu automatisiert eine Steuerungs-Software über ein Skript die Interaktion eines Anwenders mit den erscheinenden Dialog-Fenstern.

Wir empfehlen dazu dieses Werkzeug:

AutoIt: Setup-Prozess steuern

AutoIt bietet viele Möglichkeiten, um den Setup-Prozess zu steuern. Außerdem kann das Programm eventuelle Fehlerzustände (sofern vorher bekannt) mit [ADLIB]-Sektionen im Skript abfangen.

Ein grundsätzliches Problem bleibt aber bestehen: Nicht vorhergesehene (und im Skript berücksichtigte) Fenster können das Skript zum Stoppen bringen. Außerdem kann der Anwender mittels Maus und Tastatur (wenn diese nicht gesperrt sind) in den automatisierten Prozess eingreifen und den Ablauf damit verändern.

Ein Unattended- oder Silent-Setup ist daher immer die bessere Lösung! Eine Kombination aus beiden Ansätzen funktioniert ebenfalls gut. Das Silent-Setup übernimmt die eigentliche Installation, und ein AutoIt-Skript fängt bekannte Sonderbedingungen ab.

AutoIt: Bekannte Probleme

Wenn Sie in der Client-Agent-Konfiguration das Ausführen von Installationen auf einen anderen Desktop verlegen oder der Desktop gesperrt wird, haben verschiedene AutoIt-Funktionen Probleme.

Meiden Sie nach Möglichkeit in opsi-script-Skripten die folgenden Funktionen:
  • winwait()

  • winactivate()

  • Send()

Leider sind das die drei am häufigsten verwendeten Funktionen. Wir empfehlen daher, die Befehle durch die mit opsi-script ausgelieferten Bibliothek C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-script\lib\opsi-autoit-lib.au3 zu ersetzen. Sie bietet neben den hier vorgestellten erweiterten Funktionen auch noch eine Logfunktion. Sie können die Datei opsi-autoit-lib.au3 ins Produktverzeichnis kopieren und dann über die folgende Anweisung in den AutoIt-Code einbinden:

#include "%scriptpath%\opsi-autoit-lib.au3

Anschließend können Sie folgende Ersetzungen vornehmen:

  • winwait() können Sie durch die Funktion opsiwinwait($title, $text, $maxseconds, $logname) ersetzen.

  • Send() können Sie durch die Funktion opsiControlClick($title, $text, $id, $maxseconds, $logname) bzw. durch opsiControlSetText($title, $text, $id,$sendtext, $maxseconds, $logname).

Es empfiehlt sich, die ControlID mit Au3info.exe zu ermitteln. Verwenden Sie unbedingt die numerische ControlID, da andere Varianten anscheinend Probleme machen.
  • Beispiele finden Sie im Verzeichnis C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-script\lib\ in den Dateien:

    • autoit_example_1.txt

    • autoit_example_2.txt

    • autoit_example_3.txt

Analyse und Neu-Paketieren

Ein Entwickler, der ein Anwendungspaket erstellt, weiß, welche Teile benötigt werden. Wenn bereits ein Installationspaket vorhanden ist, kann man durch das Ausführen des Setup-Programms herausfinden, welche Teile für die gewünschte Funktionalität auf einem Arbeitsplatzrechner installiert werden müssen.

Es gibt eine Reihe von Werkzeugen zur Analyse von Setup-Programmen, z. B. Regshot

Produkte deinstallieren

Um Software von einem Computer zu entfernen, erstellt man oft ein Deinstallations-Skript. Das Problem dabei ist, dass nicht immer klar ist, wie die Software installiert wurde und was entfernt werden muss. Man darf auch nicht zu viel entfernen, um das System nicht zu beschädigen. Normalerweise weiß nur der Hersteller genau, wie mit seinem Produkt bei der Deinstallation umzugehen ist.

Oft gibt es Deinstallations-Routinen, die dem Produkt beiliegen und automatisch arbeiten. Gibt es die Möglichkeit, diese ohne Benutzer-Interaktion auszuführen, ist das der bevorzugte Weg. Ist eine solche Routine nicht vorhanden, oder muss diese erweitert werden, können Sie opsi-script dazu nutzen. Hier geben wir einen Überblick über die Möglichkeiten.

Deinstallations-Routine verwenden

Liefert der Hersteller des Produktes ein Programm (oder ein MSI-Paket) zur Deinstallation, dann prüfen Sie zunächst, ob dieses ohne Benutzer-Interaktion läuft (Silent-Modus). Ist das nicht der Fall, können Sie ein AutoIt-Skript zu Hilfe nehmen und mit der Deinstallations-Routine verbinden.

Der Aufruf der ausführbaren Datei kann im opsi-script-Skript in einer [WinBatch]-Sektion stehen:

[WinBatch_start_ThunderbirdUninstall]
"%SystemRoot%\UninstallThunderbird.exe" /ma
Auch wenn der Hersteller ein eigenes Programm zur Deinstallation ausliefert, sollten Sie sich nicht darauf verlassen, dass das Produkt danach korrekt beseitigt ist. Prüfen Sie zusätzlich auf einem Testsystem, ob es der Rechner nach der Deinstallation weiter stabil läuft und ob Dateien oder Registry-Einträge zurückgeblieben sind.

Deinstallation von MSI Produkten

Falls das Produkt als MSI-Paket bereitgestellt und mittels msiexec installiert wurde, ist in der Regel auch eine Deinstallation mittels msiexec möglich. Dazu rufen Sie msiexec.exe mit dem Parameter /x auf und übergeben dahinter den Namen des MSI-Paketes oder dessen GUID.

Diese ID ist eindeutig, produktspezifisch und auf allen Systemen gleich, auf denen das MSI-Paket installiert ist. Sie finden Sie in der Registry unter HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall.

Um die Benutzer-Interaktion zu deaktivieren, verwenden Sie zusätzlich den Parameter /qb-!:

msiexec.exe /x some.msi /qb-! REBOOT=ReallySuppress

So sieht die Deinstallation unter Angabe einer GUID aus:

msiexec.exe /x {003C5074-EB37-4A75-AC4B-F5394E08B4DD} /qb-!

Die GUID kann sich bei demselben Produkt von Version zu Version ändern. Um vorhandene und eventuell ältere Installationen zu löschen, müssen Sie also ermitteln, welche GUID diese Installationen haben.

Hierzu gibt es verschiedene Möglichkeiten.
Die seit opsi-setup-detector Version 4.3.3 päferierte Version ist der Weg über den MsiUpgradeCode:

MsiUpgradeCode

Der MsiUpgradeCode Code wird vom opsi-setup-detector aus der MSI-Datei ermittelt.
Dieser ist spezifisch für das Produkt, ändert sich aber nicht mit der Version. Die Bibliothek osd-lib.opsiscript enthält die Funktion getGuidListByMsiUpgradecode welche anhand des MsiUpgradeCodes eine Liste aller MsiProductCodes erstellt welche installierter Software identifiziert welche zu diesem MsiUpgradeCodes passt. Diese Liste ($UninstallList$) kann dan zur Deinstallation der installierten Versionen verwendet werden.

; 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

Eine alternative Möglichkeit ist die Verwendung des MsiName des Paketes, den der opsi-setup-detector aus der MSI-Datei ermittelt.

Der MsiName taucht im Uninstall-Eintrag der Registry als DisplayName auf. So können Sie also den MsiName verwenden, um die passenden GUID zu finden. Schneiden Sie dazu Informationen zur Architektur und Version vom Ende des MsiName ab und verpacken das Ganze in reguläre Ausdrücke. Die Bibliothek osd-lib.opsiscript enthält die Funktion getGuidListByDisplaynameRegex welche anhand der reguläre Ausdrücke eine Liste aller MsiProductCodes erstellt welche installierte Software identifiziert welche zu diesem Displayname passt. Diese Liste ($UninstallList$) kann dan zur Deinstallation der installierten Versionen verwendet werden.

; 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 diesem Skript-Teil passiert Folgendes:

  • Set $DisplayName$ = 'short msi name': Setzt die Variable $DisplayName$ auf den MsiName, kürzt nicht benötigte anhängende Informationen.

  • set $DisplayNameRegex$ = escapeRegexMetaChars($DisplayName$): Präpariert den $DisplayName$ als Suche mit regulären Ausdrücken, versteckt (maskiert) alle Sonderzeichen.

  • set $DisplayNameRegex$ = '(?i)'$DisplayNameRegex$'.*': Dieses Regex-Muster unterscheidet nicht zwischen Groß- und Kleinschreibung (?i) und ist so konzipiert, dass es mit dem Anfang einer Zeichenkette übereinstimmt, gefolgt von einer beliebigen Folge von Zeichen, die im Wesentlichen alle zusätzlichen Details nach dem Basisnamen berücksichtigt.

  • Set $UninstallList$ = getGuidListByDisplaynameRegex($DisplayNameRegex$): Sucht in der Registry; die Funktion getGuidListByDisplaynameRegex ist Bestandteil der Bibliothek osd-lib.opsiscript und erzeugt eine Liste von als passend gefundenen Einträgen in der Form <MsiVersion> = <msi GUID>.

Abarbeitung der $UninstallList$

Die weiter Deinstallation wird dann von den Einträgen in der $UninstallList$ gesteuert:

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 diesem Skript-Teil passiert Folgendes:

  • Wenn die $UninstallList$ mehr wie 0 Element hat

  • Für jedes Element von $UninstallList$ wird die Sektion [Sub_Uninstallation_msi] aufgerufen.

  • [Sub_Uninstallation_msi]: Die Sektion verwendet die gefundenen GUID zur Deinstallation.

Sollten diese Methoden nicht oder nicht vollständig funktionieren, helfen Sie mit einem opsi-script-Skript nach, wie es der nächste Abschnitt beschreibt.

opsi-script Nützliche Befehle zur Deinstallation

Haben Sie ein Produkt mit den opsi-script-Funktionen installiert oder fehlt die Deinstallations-Routine des Herstellers, schreiben Sie ein eigenes Skript zur Deinstallation.

opsi-script bietet einige Funktionen, um Programmierer bei der Deinstallation zu unterstützen. Hier erhalten Sie einen kurzen Überblick, während eine ausführliche Beschreibung der Befehle und ihrer Parameter im opsi-script-Handbuch verfügbar ist.

Der einfachste Fall ist das Löschen einer oder mehrerer Dateien in einer Files-Sektion mit diesem Befehl:

delete -f <datei>

Um ein Verzeichnis mit Unterverzeichnissen zu löschen, verwenden Sie dieses Kommando:

delete -sf <verzeichnis>\

Der Parameter f steht dabei für „force“, um die Datei wirklich zu löschen, auch wenn diese schreibgeschützt ist. Der Parameter s schließt Unterverzeichnisse mit ein und arbeitet rekursiv.

Um eine Datei oder ein Verzeichnis aus allen Benutzer-Profilen zu löschen, verwenden Sie den Parameter /AllNTUserProfiles.

Wenn Sie einen Verzeichnisbaum löschen möchten, in dem sich Dateien mit dem Attribut „versteckt“ oder „Systemdatei“ befinden, gehen Sie einen Umweg über den Befehl rmdir. Diesen können Sie über eine ShellScript-Sektion aufrufen:

[ShellScript_deleteDir]
rmdir /S /Q "<verzeichnis>"

Manchmal muss vor dem Löschen ein laufender Prozess beendet werden. In dem Fall finden Sie den Namen heraus (etwa über den Task-Manager) und übergeben diesen an den opsi-script-Befehl KillTask:

KillTask "thunderbird.exe"

Sollte das Produkt (oder Teile davon) als Service laufen, dann müssen Sie diesen Dienst vor der Deinstallation beenden. Dazu schalten Sie den Service in der Registry auf “inaktiv“ und starten den Rechner neu, oder Sie rufen den System-Befehl net mit dem Parameter stop auf. Er stoppt den Dienst sofort und löscht anschließend (ohne Neustart) die dazugehörigen Dateien:

net stop <service>
Besondere Vorsicht ist beim Löschen von .dll-Dateien geboten, die noch von anderen Produkten verwendet werden könnten. Sie müssen diese individuell behandeln, daher können wir hier keinen allgemeingültigen Rat geben.

Um mit opsi-script einzelne Einträge aus der Registry zu löschen, verwenden Sie den Befehl DeleteVar. Er stehe innerhalb einer Registry-Sektion eines opsi-script-Skriptes und löscht Einträge aus dem momentan geöffneten Key:

DeleteVar <VarName>

Einen Registry-Key mitsamt seiner Unterschlüssel und Registry-Variablen löschen Sie mit DeleteKey:

DeleteKey [HKLM\Software\Macromedia]

64-Bit-Unterstützung

opsi-script ist ein 32-Bit-Programm. Skripte zur Installation von 32-Bit-Programmen funktionieren in der Regel auch auf 64-Bit-Systemen korrekt. Für die Installation von 64-Bit-Software mit opsi-script und generell für das Arbeiten auf 64-Bit-Systemen beachten Sie das Kapitel 64-Bit-Unterstützung.