Einbindung eigener Software in die Softwareverteilung von opsi

Die Installation von Software erfolgt bei opsi durch den opsi-client-agent und insbesondere durch das Script gesteuerte Setup Programm opsi-script. Daher muss zu jedem opsi-Produkt ein opsi-script-Script erstellt werden. Danach werden dieses Script, die Installationsdateien und die Metadaten zu einem opsi-Produkt gepackt, welches sich schließlich auf dem opsi-Server installieren lässt.

Ein kleines Tutorial zur Erstellung eines opsi-script Scriptes

Einführung

Dieses Tutorial kann keine Schulung oder das Studium der Handbücher ersetzen. Es dient nur dazu eine Einführung zu bekommen. Daher als erstes der Verweis auf weiterführende Quellen:

Schulungen:

Die uib GmbH bietet opsi-Schulungen in Mainz und Inhouse Schulungen an:
https://uib.de/de/support-schulung/schulung/

Auch zu finden über:
https://uib.de/de/opsi-dokumentation/dokumentationen/
Besonders wichtig:
opsi-script-reference-card und opsi-script-Handbuch

Wiki (Scripte, Tipps, Links):

https://forum.opsi.org/wiki

Support Forum:

siehe https://forum.opsi.org

Methoden der nicht interaktiven Softwareinstallation bei Windows

Prinzipiell gibt es drei Verfahren der Einbindung eines Softwarepakets in die automatische Softwareverteilung für Windows-Betriebssysteme, zuzüglich einer Variante, die sich auf die Pakete für den Microsoft Installer Service bezieht.

  1. Unattended / Silent Setup:
    Das Original-Setupprogramm wird verwendet und über Kommandozeilenargumente in einen nicht-interaktiven Modus versetzt. Der wichtigste Spezialfall davon ist der
    „stille“ Aufruf eines MSI-Pakets:
    Ein Paket für den Microsoft Installer Service ist vorhanden und wird mit einer „quiet“-Option aufgerufen.

  2. Interaktives Setup mit automatisierten Antworten:
    Zur Vorbereitung wird bei einem Lauf des Original-Setupprogramms festgestellt, welche Fenstertitel das Programm zeigt und welche Fragen und Antworten beim Setup anfallen. Dies wird in einem Skript niedergeschrieben. Im Prozess der Softwareverteilung läuft das Setupprogramm dann unter Kontrolle eines Automatisierungs-Programms wie z.B. AutoIt oder Autohotkey, welches das Setupprogramm gemäß dem Skript steuert.

  3. Nachbilden der Setup-Routine mit dem opsi-script:
    Bei einem Lauf des originalen Setupprogramms werden etwaige System-Änderungen mitprotokolliert, z.B. mit procmon und mithilfe des opsi-script nachgefahren.

Opsi unterstützt alle drei Varianten. In der Praxis werden sie häufig ergänzend verwendet.

Struktur eines opsi-script Skripts

Im folgenden werden die wesentlichen Elemente eines opsi-script Skriptes an Beispielen für Windows erläutert.

Zunächst ein Beispiel für ein einfaches opsi-script-Skript:

[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. Sektionen werden, wie von ini-Dateien bekannt, mit einem Sektions-Namen in eckigen Klammern eingeleitet.
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 „Themen-spezifisch“ und verfügen jeweils über eine spezielle Syntax.
Der Sektionsname einer sekundären Sektion beginnt mit deren Typ, gefolgt von einem frei definierbaren Namen.

Im Beispiel ruft die primären Sektion [Actions] eine sekundäre Sektion [WinBatch_tightvnc_silent_install] auf.
Die sekundäre Sektion ist vom Typ WinBatch. Der Inhalt einer WinBatch-Sektion wird über die Windows-API ausgeführt.
In diesem Fall wird also das Setup-Programm 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. Es besteht die Möglichkeit Sub-Sektionen in externe Dateien auszulagern.

Die primären Sektionen sind das Hauptprogramm in dem der Ablauf des Skripts gesteuert wird. Hierzu gibt es:

Abbildung: Vermeidung doppelten Codes über ausgegliederte Sub
Abbildung 1. Vermeidung doppelten Codes über ausgegliederte Sub
  • Variablen: Strings und Stringlisten

  • if elseif else endif Anweisungen

  • for Schleifen über Stringlisten

  • Funktionen

Wichtige sekundäre Sektionen

Files

Datei-Operationen, wie:

  • kopieren (mit Versionskontrolle, rekursiv …​)

  • löschen

  • Verzeichnisse anlegen

  • …​

WinBatch

Dient zum Aufrufen von Programmen über die Windows-API. Beispielsweise werden Aufrufe von Setup-Programmen im silent mode in diesen Sektionen durchgeführt.

ShellScript

Der Inhalt dieser Sektion wird der Betriebssystemtypischen shell zur Ausführung übergeben. Diese shell ist bei Windows 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 (Interpreter) zur Ausführung übergeben. Beispielsweise können über ExecWith AutoIt-Skripte http://www.autoitscript.com direkt in das opsi-script-Skript integriert werden.

Registry

Die Registry-Sektionen dienen dem Bearbeiten der Registry.

LinkFolder

LinkFolder-Sektionen dienen dem Erstellen und Entfernen von Verknüpfungen. Es können beispielsweise Verknüpfungen auf dem Desktop oder im Startmenü erstellt werden.

Globale Konstanten

Globale Konstanten sind Text-Platzhalter, die in primären und sekundären Sektionen eingesetzt werden können und zur Laufzeit textuell durch ihre Werte ersetzt werden.
Über die Verwendung von Platzhaltern kann sichergestellt werden, dass Pfade in unterschiedlichen Umgebungen (z.B. auf System mit unterschiedlichen Sprachen oder Betriebssystem-Versionen) richtig gesetzt sind.

Beispiele:

%ProgramFiles32Dir%

c:\programme

%Systemroot%

c:\windows

%System%

c:\windows\system32

%opsiTmpDir%

c:\

%Scriptpath%

<Pfad zu laufenden Script>

Zweites Beispiel: tightvnc

Zur Erläuterung nun ein einfaches Script zur Installation von tightvnc. Eigentlich würde dieses Script mit dem Aufruf der Silent-Installation in der Winbatch-Sektion auskommen. Bei einer wiederholten Installation erscheint hier (wegen des Neustarts eines laufenden Services) jedoch ein interaktiver Dialog. Dieses Dialog-Fenster wird (so es auftaucht) mithilfe 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")

Elementare Befehle für primäre Sektionen

String-Variable

Variablen-Deklaration

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

Variablen-Zuweisung

Set <variable name> = <value>

Beispiel:

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

oder

DefVar $ProductId$ = "firefox"
Stringvariablen werden in primären und sekundären Sektionen unterschiedlich behandelt. In primären Sektionen sind Stringvariablen eigenständige Objekte. Nur hier können sie deklariert und ihnen Werte zugewiesen werden. Entsprechend ist die Verbindung von Variablen und Strings zu einem Stringausdruck mit einem Operator "+" durchzuführen.
Beispiel: "Installing "+ $ProductId$ +" …​"
In sekundären Sektionen werden Stringvariablen vor der Ausführung der Sektion durch den Inhalt der Variable ersetzt.
Beispiel: "Installing $ProductId$ …​"
Dies ist zu beachten, wenn entsprechende Stringausdrücke per Cut&Paste im Skript kopiert werden.
Der Vorteil dieser Konstruktion ist, dass in Sektionen die außerhalb des opsi-script ausgeführt werden (ShellScript / Execwith) problemlos mit opsi-script-Variablen gearbeitet werden kann.

Message / ShowBitmap

Zur Textausgabe während der Installation:
Message <string>

Beispiel:

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

Zur Ausgabe einer Grafik während der Installation:
ShowBitmap <filename> <subtitle>

Beispiel:

ShowBitmap "%ScriptPath%\python.png" "Python"

if [elseif] [else] endif

Syntax:

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.

Fehler, Logging und Kommentare

Kommentarzeichen ';'

Zeilen, die mit einem Semikolon (';') beginnen, werden nicht interpretiert.

Comment

Schreibt eine Kommentar-Meldung in die Log-Datei.

LogError

Schreibt eine Fehlermeldung in die Log-Datei.

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.

Weitere wichtige opsi-script Funktionen

Einen Überblick über die opsi-script Funktionen gibt die Referencecard:
https://docs.opsi.org/opsi-docs-de/4.2/opsi-script-manual/reference-card.html

Eine detaillierte Dokumentation ist im opsi-script Handbuch zu finden:
https://docs.opsi.org/opsi-docs-de/4.2/opsi-script-manual/opsi-script-manual.html

Hier noch einige Hinweise auf besonders wichtige Elemente:

Stringlisten:

Stringlisten sind sehr mächtig, insbesondere zur Auswertung von Ausgaben externer Programme. Lesen Sie dazu die opsi-script-Dokus.

ExitWindows:

Neustart/Herunterfahren des Systems und Beendung des opsi-script.

  • ExitWindows /Reboot
    Rechner-Neustart nach Abschluss des laufenden Skriptes.

  • ExitWindows /ImmediateReboot
    Sofortiger Neustart.

  • ExitWindows /ImmediateLogout
    Sofortige Beendigung der Skript-Bearbeitung und Beendung des opsi-script.

Produkteigenschaften:

Für manche Produkte ist es erforderlich, Optionen zur Verfügung zu stellen. Diese werden zur Laufzeit Client-spezifisch ausgewertet. Wie solche Properties erstellt werden, ist im Kapitel Erstellen eines opsi-Produkt-Pakets beschrieben.

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

if GetProductProperty("example-property", "no") = "yes"
	Files_copy_extra_files
endif
Encoding:

Schreiben Sie Ihre Scripte in UTF-8 Encoding und setzen sie die Zeile
encoding=utf8 an den Anfang der Datei-

Spezielle Kommandos für Windows

  • getOS : string // liefert: Linux or Windows_NT or macOS [W/L/M]
    GetOS

  • getMsVersionInfo : string // Windows Version Information [W]
    GetMsVersionInfo

  • GetMsVersionName //Windows marketing Version //since 4.12.4.35 [W]
    GetMsVersionName

  • getMSVersionMap : stringlist [W]
    GetMSVersionMap

Beispiel: Windows-Template 'opsi-template'

Dieses Template können Sie sich mit dem opsi-setup-detector 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$


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

Erstellen eines opsi-Produkt-Pakets

Installation des opsi PackageBuilder

Den opsi PackageBuilder gibt es derzeit für Windows, Linux und MacOS.

Die Installations-Dateien / Pakete des opsi PackageBuilder finden Sie hier:
https://forum.opsi.org/viewtopic.php?p=32473#p32473
Dort findet sich im oberen Teil die Links auf die Installationspakete für Windows, Linux und MacOS.
Der opsi PackageBuilder kommt nicht von 'uib' sondern aus der opsi-community von Holger Pandel (Danke!).

Der opsi PackageBuilder unterliegt einer OpenSource Lizenz:
https://github.com/pandel/opsiPackageBuilder/blob/master/LICENSE_DE

Der opsi PackageBuilder hat eine eigene Dokumentation welche mit installiert wird.

Sie können den opsi PackageBuilder auch per opsi installieren:

Das Paket opsipackagebuilder_wlm gehört zu den opsi Standardprodukten und sollte auf Ihrem opsi-server installiert sein. Falls nicht, mit:

opsi-package-updater install opsipackagebuilder_wlm

können Sie es auf dem opsi-server installieren.

Installation des opsi-setup-detector

Den opsi-setup-detector gibt es derzeit für Windows, Linux und MacOS.

Sie können den opsi-setup-detector per opsi installieren:

Das Paket opsi-setup-detector gehört zu den opsi Standardprodukten und sollte auf Ihrem opsi-server installiert sein. Falls nicht, mit:

opsi-package-updater install opsi-setup-detector

können Sie es auf dem opsi-server installieren.

Ein Setup-Programm um den opsi-setup-detector auf Windows auch ohne opsi zu installieren, finden sie unter :
https://download.uib.de/opsi4.2/misc/helper/

Die Basis Funktionalität des opsi-setup-detector auf den unterschiedlichen Betriebssystemen ist gleich. Bei der Analyse einer Installationsdatei werden aber eventuell Hilfprogramme aufgerufen, welche nicht überall verfügbar bzw. lauffähig sind.

  • Genauere Analyse von Inno-Setups verwendet innounpack.exe unter Windows.

  • Genauere Analyse von wix-setups verwendet dark.exe unter Windows.

  • .deb bzw. .rpm Dateien werden mit den entsprechenden Linux Werkzeugen analysiert.

Das opsi-Produkt opsi-setup-detector hat eine Abhängigkeit zu dem opsi-Produkt opsipackagebuilder_wlm. Der opsi-setup-detector verwendet den opsi PackageBuilder wenn vorhanden, funktioniert in weiten Teilen aber auch ohne. Die Installation des opsi PackageBuilder ist aber empfohlen.

Installation des opsi-logviewer

Den opsi-logviewer gibt es derzeit für Windows, Linux und MacOS.
Der opsi-logviewer ist ein Teil des opsi-configed Pakets, daher muss dieses installiert werden.

Sie können den opsi-configed per opsi installieren:

Das Paket opsi-configed gehört zu den opsi Standardprodukten und sollte auf Ihrem opsi-server installiert sein. Falls nicht, mit:

opsi-package-updater install opsi-configed

können Sie es auf dem opsi-server installieren.

Eine ausführbare Version des opsi-configed für Windows / Linux / MacOS finden sie unter :
https://download.uib.de/opsi4.2/stable/misc/

Opsi-setup-detector: Start und notwendige Konfigurationen

Der opsi-setup-detector kann gestartet werden aus der Programm Menü und findet sich dort unter opsi.org. Der opsi-setup-detector wird unter Windows auch in das Kontextmenü des Explorers eingebunden, um so per Rechte Maustaste Setup-Programm direkt zur Analyse aufrufen zu können.

Opsi-setup-detector: Notwendige Konfigurationen

Konfigurationsdialog
Abbildung 2. opsi-setup-detector Notwendige Konfiguration beim ersten Start

Nach dem erstmaligen Start des opsi-setup-detector erscheint ein Konfigurationsmaske. Hier sind die folgenden Angaben erforderlich:

  • fullname : (Wird verwendet für Einträge in die changelog.txt)

  • email_address (Wird verwendet für Einträge in die changelog.txt)

  • workbench_path : Pfad zum Verzeichnis in dem die opsi-Pakete erstellt werden sollen. Dies ist idealerweise der Pfad zu der Stelle an der die opsi_workbench Ihres opsi-servers gemountet ist.

Optional: Verbindungsdaten zu dem opsi-webservice:

  • Service_URL :Die URL des opsi webservice (wie: https://<opsi-server>:4447)

  • Service_user : Der user name für die Verbindung zum opsi Webservice

  • Service_pass : Das Passwort des angegebenen users für die Verbindung zum opsi webservice.
    ACHTUNG SICHERHEITSRISIKO: Auch wenn das Passwort verschlüsselt abgespeichert wird, so läßt es sich doch nach einer Analyse des (offenen) Quellcodes entschlüsseln. Es wird nach dem Passwort gefragt, wenn hier nichts steht.

Optional:

  • control_in_toml_format : Control Datei im TOML Format erzeugen ?
    Hierfür wird mind. opsi 4.3 benötigt.
    Gibt es eine control.toml, so ist diese maßgeblich und muss gepflegt werden.

  • dependencies_for_all_actionrequests : Sollen Abhängigkeiten auch für andere Actionrequests (ausser 'setup') erlaubt sein ?
    Für 'true' ist opsi 4.3 Voraussetzung.
    Nur sehr vorsichtig verwenden.

Opsi-setup-detector Online Hilfe

Hilfe anzeigen
Abbildung 3. Hilfe anzeigen

Über diese Fragezeichen Icon können Sie die allgemeine bzw. Kontext bezogene Online Hilfe aufrufen.

Opsi-setup-detector start page

Startpage
Abbildung 4. opsi-setup-detector Start

Auf der Startseite wählen Sie die gewünschte Aufgabe und folgen den Dialogen bzw. wählen den Button 'Nächster Schritt'.

Die angebotenen Aufgaben sind gruppiert nach:

  • OS unabhängig

  • Windows

  • Linux

  • MacOS

  • Multiplattform

Die angebotenen Aufgaben für Windows:

  1. Analysiere Datei und erzeuge ein opsi Paket
    Hier wird von einer Setup-Datei ausgegangen und der gesamte Ablauf bis zur Erzeugung eines opsi-Paketes durchlaufen. Dieser Prozess ist im nächsten Kapitel beschrieben.

  2. Analysiere 2 Dateien (32 / 64 Bit) und erzeuge ein opsi Paket
    Verläuft analog zu dem obigen Punkt 1 mit folgenden Unterschieden:
    Es werden zwei Setupprogramme für die Architekturen 32 und 64 Bit abgefragt und analysiert. Das Produkt bekommt ein zusätzliches Property: install_architecture mit den möglichen Werten: 32bitonly, 64bitonly, both, systemspecific.

  3. Analysiere Datei und erzeuge ein Paket 'with user'
    Verläuft analog zu dem obigen Punkt 1. Das Paket wird erstellt für eine Installation bei eingeloggtem User.
    Das Produkt bekommt zusätzliche Properties: Das Property execution_method mit den möglichen Werten: (loginOpsiSetupUser, runAsOpsiSetupUser, runOpsiScriptAsOpsiSetupUser) und die boolschen Properties uninstall_before_install, copy_files_locally, debug.
    Für weitere Details siehe : opsi_template_with_userlogin

  4. Eine opsi Paketvorlage (Template) erzeugen
    Dieser Punkt fragt nicht nach einer Setup-Datei, sondern erstellt ein opsi template Produkt für Windows bei dem die Angaben aus der Produktkonfiguration bereits übernommen werden.

  5. Eine Datei nur analysieren
    Verläuft analog zu dem obigen Punkt 1 nur das nach der Analyse des Setup-Programms abgebrochen wird.

opsi-setup-detector: Analysiere eine Datei und erzeuge ein opsi Paket

Im folgenden wird der Ablauf anhand des Punktes Analysiere eine Datei und erzeuge ein opsi Paket erläutert.

Startpage
Abbildung 5. opsi-setup-detector Start

Nach der Auswahl der Aufgabe erscheint ein Dateiauswahl-Dialog zur Auswahl der zu analysierenden Setup Datei. Nach der Auswahl beginnt direkt die Analyse.

opsi-setup-detector: Analyse

Analyse
Abbildung 6. opsi-setup-detector Analyse

War die Analyse nicht erfolgreich, endet sie hier mit Sorry unknown Installer.

Sorry unknown Installer

In diesem Dialog kann gewählt werden, ob die Erzeugung abgebrochen wird, oder ob die Erzeugung nach dem Muster eines wählbaren bekannten Installerstyps fortgesetzt werden soll.

Bei einer erfolgreichen Analyse wird direkt zum Ergebnis gewechselt.

opsi-setup-detector: Ergebnis der Analyse

Ergebnis der Analyse
Abbildung 7. opsi-setup-detector Ergebnis der Analyse
  • Erkannter Setup Typ: Typ des erkannten Installer

  • Bevorzuge Silent Installation:
    Wird (wenn möglich) eine 'silent' Installation einer 'unattended' vorgezogen.

  • MST erlaubt: Sollen auch zusätzliche 'mst' Dateien verwendet werden ? (Nur bei msi)

  • Hilfe anzeigen: image::osd_help-circle20.png["Hilfe anzeigen", pdfwidth=10%]

  • Info Link mit Infos zum Installer

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

  • MST Datei: Bei MSI-Installern oder Installern welche MSI enthalten, kann hier eine MST-Datei angegeben werden welche in den MSI Aufruf integriert wird.

  • MsiId: Bei MSI-Installern oder Installern welche MSI enthalten, der MSI-Produktcode

  • MsiName: Bei MSI-Installern oder Installern welche MSI enthalten, der MSI-Produktname welcher in der Registry als 'Displayname' hinterlegt wird.

  • Software Version: Die Version der zu installierenden Software soweit ermittelbar

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

  • Benötigter Platz MB: Dieser Wert ist eine Schätzung aus sechsmal die Größe der Setup-Datei und kann gegebenenfalls angepasst werden

  • InstallDir: Soweit erkannt das Verzeichnis in das die Software installiert werden wird.
    Wenn nicht korrekt erkannt, so kann über den Auswahlbutton rechts neben dem Feld das Verzeichnis gewählt werden. (Wenn das Produkt bereits auf dem Rechner installiert ist.)
    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: Das ermittelte Kommando zu einer nicht interaktiven Installation. Die genaue Form des Kommandos kann abhängig von der Checkbox Bevorzuge Silent Installation unterschiedlich ausfallen.

  • Kommando zur Deinstallation: Das ermittelte Kommando zu einer nicht interaktiven Deinstallation. Die genaue Form des Kommandos kann abhängig von der Checkbox Bevorzuge Silent Installation unterschiedlich ausfallen.

  • Deinstallations Programm: Das ermittelte Deinstallations Programm.
    Wenn nicht korrekt erkannt, so kann über den Auswahlbutton rechts neben dem Feld die Datei gewählt werden. (Wenn das Produkt bereits auf dem Rechner installiert ist.).
    MSI-Dateien haben (üblicherweise) kein Deinstalltions Programm.

  • Hauptrogramm: Das Hauptrogramm der zu installierenden Software.
    Wir verwendet um z.B. DesktopIcons oder Starmenüeinträge zu erzeugen. Wird nicht automatisch erkannt und kann über den Auswahlbutton rechts neben dem Feld die Datei gewählt werden. (Wenn das Produkt bereits auf dem Rechner installiert ist.)

Die hier ermittelten Werte können nun bei Bedarf korrigiert oder ergänzt werden. Der Button Nächster Schritt führt zur ersten Seite der Produktkonfiguration. Hier werden die Metadaten des zu erstellenden opsi Produktes eingegeben.

Die hier ermittelten Werte können falsch sein und sind wahrscheinlich unvollständig !
Nach einer ersten Installation sollten Sie unbedingt die Werte von InstallDir, Deinstallations Programm, Hauptrogramm und Software Version überprüfen und gegebenenfalls in Ihrem Script anpassen.

opsi-setup-detector: Produktkonfiguration 1

Produktkonfiguration 1
Abbildung 8. opsi-setup-detector Produktkonfiguration 1
  • opsi Product ID: dies ist der Name des zu erzeugenden opsi Paketes und wird aus dem weiter unten stehenden Produkt Namen erzeugt, wobei Leerzeichen und andere ungültigen Zeichen durch ein '-' ersetzt werden. Die vorgeschlagene opsi Product ID kann natürlich geändert werden.

  • Importiere control Datei: Mit diesem Button können ausgewählte Daten aus einer bestehenden opsi control Datei (control, control.toml) in das laufende Projekt importiert werden. Nicht importiert werden dabei Versionsnummern, Scriptnamen, Benötigter Platz.

  • Produkt Name: der Name der zu installierenden Software. Dieser muss evtl. händig korrigiert werden

  • Produkt Version: die aus dem Name der Setup-Datei ermittelte Versionsnummer muss wahrscheinlich händig korrigiert werden. Sie darf nur Ziffern und Punkte enthalten, da sie für die Versionierung des opsi Paketes verwendet wird.

  • Paket-Version: Die Versionsnummer des opsi Paketes. Diese dient datz Pakete zu unterscheiden, welche dieselbe Software in der selben Version enthalten aber z.B. unterschiedliche Scripte oder Properties. Sie darf nur Ziffern, da sie für die Versionierung des opsi Paketes verwendet wird.

  • Beschreibung: Üblicherweise ein Kurzbeschreibung was die Software macht.

  • Hinweis: Ergänzende Hinweise zur Software, wie z.B. Herkunft, Link zum Download, Hinweise zur Lizenz

  • Template Channel: Hier kann zwischen verschiedenen Quellen der Templates gewählt werden, welche für die Erstellung der Skripte verwendet werden. Die folgenden 'Template Channel' sind verfügbar:

    • Default: Dies ist der default und auch der Fallback. Wenn Sie einen anderen 'Template Channel' wählen und dieser die notwendigen Dateien für Ihren Task nicht bereitstellt, so werden die Dateien aus default verwendet.
      Die wesentlichen Skriptdateien eines Produktes sind: setup.opsiscript, uninstall.opsiscript, declarations.opsiinc, sections.opsiinc, delinc.opsiinc

    • Training: Das Ziel ist hier ein einfacherer Aufbau mit ausführlicher Kommentierung.
      Die wesentlichen Skriptdateien eines Produktes sind: setup.opsiscript, uninstall.opsiscript, delinc.opsiinc

    • Structured: In der Version 4.2.2 nicht verwendet (fallback zu default)

    • Custom: Ist per default leer. Sie können hier eigene Templatedateien bereitstellen. Um dies zu tun, müssen Sie Ihre Templates in das Verzeichnis 'opsi-setup-detector/custom/template-files/' auf Ihrem opsi-depot kopieren und dann den opsi-setup-detector neu auf dem Client installieren.

Checkboxen zur Codeergänzung
Die folgenden Checkboxen fügen zusätzlichen Code und zusätzliche Einstellungen für bestimmte Aufgaben hinzu:

  • Unterstütze custom directory : Das Produkt erhält ein zusätzliches Verzeichnis 'custom' welches Kunden spezifische Dateien enthalten kann. Bei der Installation einer neuen Version des Paketes auf dem Server wird das vorhandene custom Verzeichnis erhalten. Der Code enthält Vorlagen um Dateien aus diesem Verzeichnis in die Installation einzufügen.
    Mehr Details: Opsi-setup-detector: Support custom directory

  • Installiere von lokalem, temporären Verzeichnis : Die installationsdateien werden zunächst in ein lokales, temporäres Verzeichnis kopiert und dann aus diesem Verzeichnis heraus installiert. Insbesondere sinnvoll für alles was bei der Installation die Netzwerkverbindung beeinträchtigen könnte (z.B. Treiber).
    Mehr Details: Opsi-setup-detector: Installiere von lokalem, temporären Verzeichnis

  • Behandle Lizenzkeys : Fügt Property und Code zur Behandlung von Lizenzkeys hinzu.
    Mehr Details: Opsi-setup-detector: Behandle Lizenzkeys

  • DesktopIcon : Fügt Property und Code zur Behandlung von Desktop Icons hinzu.
    Mehr Details: Opsi-setup-detector: DesktopIcon

  • Customize Profile : Ergänzt den Code um eine 'Profileactions' Sektion um Anpassungen in den lokalen Userprofilen durchzuführen. Diese Funktionalität wird auch über ein loginscript für 'Roaming Profiles' bereitgestellt.
    xref:osd-checkboxes-subtasks.adoc#opsi-setup-detector-customize_profile
    Mehr Details: Opsi-setup-detector: Customize Profile

opsi-setup-detector: Priorität und Abhängigkeiten

Produktkonfiguration 2
Abbildung 9. opsi-setup-detector Produktkonfiguration 2

Für normale Anwendungssoftware müssen Sie hier nichts tun, da die Voreinstellungen 'passen'. Sie können auf den Button Nächster Schritt drücken.

Ansonsten sei hier erläutert, welche Einstellungen hier möglich sind:

Priorität

beeinflusst die Installationsreihenfolge. Empfohlen für Anwendungssoftware: 0
Mögliche Werte liegen zwischen 100 (ganz am Anfang) und -100 (ganz am Ende). Existieren auch Produktabhängigkeiten, so beeinflussen diese zusätzlich die Installationsreihenfolge.

Abhängigkeiten

Hier können Abhängigkeiten zwischen Produkten definiert werden.
Wenn in der Konfiguration die Zugangsdaten zu Ihrem opsi-server hinterlegt sind, so wird versucht eine Verbindung zum opsi-server aufzubauen. Wenn das Passwort aus Sicherheitsgründen nicht hinterlegt ist, wird hier nach dem Passwort gefragt:

Password Dialog
Dependency Editor
Abbildung 10. opsi-setup-detector Dependency Editor
Actionrequest

Actionrequest zu dem eine Abhängigkeit erzeugt werden soll. Dies ist üblicherweise setup. Ab opsi 4.3 sind auch andere Actionrequests erlaubt. Diese Möglichkeit ist mit Bedacht zu verwenden um nicht Bedingungen zu erzeugen welche nicht ohne Widersprüche auflösbar sind.
Dieser Bereich ist nur enabled, wenn In der Konfiguration dependencies_for_all_actionrequests = true gesetzt ist.

Productid

Productid (Bezeichner) des Produkts zu dem eine Abhängigkeit besteht.
Wenn es eine Verbindung zum opsi-server gibt, so wird dies hier in grüner Schrift angezeigt und die bekannten productIds können über das Auswahlfeld gewählt werden. Gibt es keine Verbindung zum opsi-server, so wird dies in roter Schrift angezeigt und die productId muss eingegeben werden.

Abhängigkeits Modus

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

Aktion oder Status

Für Status: Status den das Produkt, zu dem eine Abhängigkeit besteht, haben soll (installed). Liegt ein anderer Status vor, so wird das Produkt auf setup gestellt.
Für Aktion: Aktionsanforderung welche bei dem Produkt, zu dem eine Abhängigkeit besteht, gesetzt werden soll (setup)
Bei der Erzeugung eines Meta Produkts ist dieser Bereich disabled um unsinnige Einstellungen zu vermeiden.

Abhängigkeits Typ

Installationsreihenfolge. Wenn das Produkt, zu dem eine Abhängigkeit besteht, installiert sein muss bevor mit der Installation des aktuellen Produkts begonnen werden kann, dann ist dies before. Muss es nach dem aktuellen Produkt installiert werden so ist dies after. Ist die Reihenfolge egal so muss hier nichts eingetragen werden.
Bei der Erzeugung eines Meta Produkts ist dieser Bereich disabled um unsinnige Einstellungen zu vermeiden.

Hinweis:

Die tatsächliche Installationsreihenfolge ermittelt sich aus einer Kombination von Produktabhängigkeiten und Produktpriorisierung. Details hierzu finden Sie im opsi-Handbuch im Kapitel Beeinflussung der Installationsreihenfolge durch Prioritäten und Produktabhängigkeiten

opsi-setup-detector: Properties

Hier können veränderbare Eigenschaften (Produktvariablen) für das Produkt definiert werden.

Property Editor
Abbildung 11. opsi-setup-detector Property Editor

Feld / Funktion

Beschreibung

Hinweise

Property Name

Name der Produktvariable

Dieser Bezeichner wird in der Produktkonfiguration im opsi-configed angezeigt und ist innerhalb der Skripte mit der Funktion GetProductProperty auslesbar.

Beschreibung

Beschreibung der Variablenfunktion

Wird im opsi-configed als Tooltip angezeigt

Property Type

Variablentyp

Mögliche Werte: Text / bool

Multivalue

Bestimmt, ob die Produktvariable nur genau einen oder mehrere Werte annehmen kann

Nur bei Typ Text verfügbar

Editierbar

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

Komma-separiert Liste der möglichen Eingabewerte

Falls Editierbar auf “True” gesetzt wurde, kann die Liste später innerhalb von opsi-configed ergänzt werden.
Nur bei Typ Text verfügbar

Default Wert

Vorgabewert

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

opsi-setup-detector: Produkt Icon

Produktkonfiguration 3 (Icon)
Abbildung 12. opsi-setup-detector Produktkonfiguration 3 (Icon)

Hier kann ein Icon für die Anzeige während der Installation ausgewählt werden oder Sie übernehmen mit Nächster Schritt das DefaultIcon (Zahnrad) und wechseln zum nächsten Reiter..

Um ein anderes Icon auszuwählen wählen Sie über den Button Öffne Icon Verzeichnis in Verzeichnis aus in dem Sie Icons erwarten. Als Vorauswahl bekommen Sie ein beim opsi-setup-detector mitgeliefertes Verzeichnis von 'open source' Icons: 128x128. Wählen Sie ein Unterverzeichnis und die Icons werden angezeigt.
Nun können Sie aus der Anzeige ein Icon auswählen.

Nachdem die Produktkonfiguration vollständig ist, kann nun das Produkt erzeugt werden.

opsi-setup-detector: Produkt erzeugen

Produkt erzeugen
Abbildung 13. opsi-setup-detector Produkt erzeugen
  • Pfad zur opsi-workbench ist ein Laufwerksbuchstabe oder UNC Pfad auf dem der share opsi_workbench Ihres opsi-servers gemounted ist.

  • Links neben dem Button opsi Paket erstellen befinden sich drei mögliche Auswahl Optionen, die sich auf die Funktion des Buttons beziehen:

  • Erstellungs Modus ist ein Auswahlbereich bei dem die Vorgänge bei der Paketerstellung bestimmt werden können:

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

  • Erstelle opsi Produkt Dateien und baue opsi Paket führt die im ersten Punkt angeführten Vorgänge durch.
    Zusätzlich wird versucht das Paket auf dem opsi-server zubauen und gegebenenfalls zu installieren (siehe unten: Auswahlfeld Bau Modus).
    Wenn in der Konfiguration Verbindungsdaten zum opsi-webservice hinterlegt sind (siehe auch: Opsi-setup-detector Start und notwendige Konfigurationen) wird dieser kontaktiert. Ist kein Service Passwort gespeichert, wird nach dem Passwort gefragt. Ist die opsi-service Version größer gleich 4.2.0.287 dann wird das bauen und installieren über den opsi-service ausgeführt.
    Ist der Service nicht erreichbar oder zu alt, wird der opsi PackageBuilder ohne interaktive GUI aufgerufen um aus dem erstellten Verzeichnisbaum das opsi-Paket zu erstellen und danach wieder beendet. Die genauen Abläufe werden dabei durch das Auswahlfeld Bau Modus bestimmt:

    • nur bauen erzeugt das opsi Paket so wie der Server Befehl opsi-makepackage.

    • bauen und installieren erzeugt das opsi Paket so wie der Server Befehl opsi-makepackage. Danach wird das erzeugte Paket installiert wie mit dem Server Befehl opsi-package-manager --install <package name>.

  • Erstelle opsi Produkt Dateien und starte interaktiven Packagebuilder führt die im ersten Punkt angeführten Vorgänge durch.
    Zusätzlich wird der opsi PackageBuilder interaktiv aufgerufen.
    Sie müssen diesen selbst beenden um zu dem opsi-setup-detector zurückzukehren.
    Zu Installation, Konfiguration und Bedienung des Community Projektes opsi PackageBuilder siehe https://forum.opsi.org/viewforum.php?f=22

  • opsi Paket erstellen ist der Button welcher die Paketerstellung veranlasst.
    Ist bereits ein Paket mit diesem Namen vorhanden, so erscheint eine Rückfrage ob die Dateien im vorhandene Verzeichnis gesichert oder gelöscht werden sollen:

Backup Dialog

Wenn bei der Erstellung der Produktdateien auf der Workbench ein vorhandenes Verzeichnis mit dem Namen <productId> gefunden wird, gibt es eine Rückfrage was mit den alten Dateien geschehen soll.

  • Nur Paket neu bauen ist ein Button mit dem das bauen des opsi Paketes veranlasst wird ohne vorher die opsi Dateien neu zu erzeugen.
    Damit kann das Paket neu gebaut werden nach dem per Editor Änderungen an den Scripten durchgeführt wurden ohne diese Änderungen zu verlieren.

Bei der Erstellung der Produktdateien werden auch alle Informationen welche in den Masken eingegeben wurden, in die Datei opsi-project.osd im Basisverzeichnis des Produktes geschrieben. Diese Datei kann zu einem späteren Zeitpunkt wieder mit dem opsi-setup-detector geöffnet werden um das Produkt zu modifizieren.

opsi-setup-detector: Vorhandenes Projekt öffnen

Eine existierende Projektstruktur kann auf zwei Arten durch den opsi-setup-detector als Projekt geöffnet werden:

  • Wenn das Produkt durch den opsi-setup-detector erzeugt wurde, können Sie dazu den Menüpunkt: Datei / Projektdatei öffnen verwenden um die Datei opsi-project.osd im Basisverzeichnis des Produktes zu öffnen.

  • Wenn das Produkt nicht durch den opsi-setup-detector erzeugt wurde, können Sie dazu den Menüpunkt: Datei / Controldatei öffnen verwenden um die Datei control bzw. control.toml im OPSI Verzeichnis des Produktes zu öffnen.
    In diesem Fall haben Sie weniger Informationen insbesondere über die verwendete Installerdatei.

Mehr Details zum opsi-setup-detector finden Sie im opsi-manual:
https://docs.opsi.org/opsi-docs-de/4.2/manual/modules/setup-detector.html

Das Programm opsi PackageBuilder zum modifizieren eines Scriptes

Beim ersten Start nach der Installation startet der opsi PackageBuilder im Offline Modus, da noch wichtige Konfigurationsdaten für die Verbindung mit dem opsi-server fehlen.

Erster Start
Abbildung 14. opsi PackageBuilder Erster Start: Offline Modus

Sollte der der Start auf diese Weise nicht funktionieren und das Startmenü nicht reagieren (beobachtet unter Linux / KDE), so probieren sie es von der Kommandozeile unter Angabe irgend eines Pfades und bestätigen die Fehlermeldung das der Pfad nicht gefunden wurde:

opsipackagebuilder --path /home

Initiale Konfiguration des opsi PackageBuilder

Um die fehlenden Konfigurationsdaten einzugeben öffnen Sie die Einstellungen.

Einstellungen: Allgemein
Abbildung 15. opsi PackageBuilder Einstellungen: Allgemein

Im Reiter Allgemein machen Sie bitte folgende Einstellungen:

  • Konfigserver : Vollständiger Name (FQDN) Ihres opsi-configservers (z.B. opsi.mycompany.org)

  • opsiadmin Benutzer: username eines Mitglieds der Gruppe opsiadmin (Am besten Ihr username)

  • opsiadmin Passwort: das Passwort des oben angegeben Benutzers. Dieses wird nicht angezeigt und verschlüsselt gespeichert. Es ist notwendig damit der opsi PackageBuilder mit dem opsi-server kommunizieren kann.

  • opsi Server Version: opsi 4.1 oder höher

  • opsi Workbench : /var/lib/opsi/workbench

  • Kompatibilität der Befehlsausführung : opsi 4.0.4 oder neuer / Sudo ohne Passwort

  • Benutzer : Ihr voller Name (wird in changelogs verwendet)

  • EMail : Ihre eMail Adresse (wird in changelogs verwendet)

Einstellungen: Programm
Abbildung 16. opsi PackageBuilder Einstellungen: Programm

Im Reiter Programm machen Sie bitte folgende Einstellungen:

  • Bestehendes Netzlaufwerk verwenden : Häkchen setzen

  • Entwicklungsordner : Pfad zum Verzeichnis in dem die opsi-Pakete erstellt werden sollen. Dies ist idealerweise der Pfad zu der Stelle an der die opsi_workbench Ihres opsi-servers gemountet ist.

  • Skripteditor :
    Den Skripteditor des opsi PackageBuilder gibt es leider nur für Windows.

    • Unter Windows belassen Sie es bei den Voreinstellungen

    • Unter Linux: Externer Editor: /usr/local/bin/jedit
      Kommandozeilenoptionen: (leer)

    • Unter MacOS: Externer Editor: /Application/jedit
      Kommandozeilenoptionen: (leer)

Einstellungen: Verwaltung
Abbildung 17. opsi PackageBuilder Einstellungen: Verwaltung

Im Reiter Verwaltung empfehlen wir folgende Einstellung abweichend vom Default

  • Paketieren : opsi-makepackage -v

Speichern Sie die Einstellungen und starten Sie den opsi PackageBuilder neu. Der opsi PackageBuilder sollte nun nicht mehr Offline Modus melden.

Mit dem opsi PackageBuilder Pakete modifizieren, packen und Installieren

Start
Abbildung 18. opsi PackageBuilder Start

Verwenden Sie Paket öffnen (F2) und wählen Sie das Verzeichnis in dem das Sie mit dem opsi-setup-detector erstellt haben. (z.B.: w:\newprod2 )
Dann öffnet sich das Produktfenster mit verschiedenen Reitern. Der default Reiter ist Paket.

Reiter Packet
Abbildung 19. opsi PackageBuilder Reiter Packet

In desem Reiter sehen auf der Linken Seite die allgemeinen Metadaten des opsi-Produktes wie Sie auch schon in opsi-setup-detector: Produktkonfiguration 1 erläutert wurden.

Auf der rechten Seite sehen Sie die Scriptdateien und daneben den Button:

Button Edit
Abbildung 20. opsi PackageBuilder Button Edit

Mit dem Button können Sie die Datei in dem in der Konfiguration angegebenen Scripteditor aufrufen und das Script modifizieren. Unter Windows ist das der Scripteditor des opsi PackageBuilder.

Scripteditor
Abbildung 21. opsi PackageBuilder Scripteditor unter Windows

Wesentliche Merkmale:

  • Farbige Syntaxhervorhebung

  • “Falten” des Quellcodes (optional: kompakt, mit Kommentaren)

  • Lexerdefinition anpassbar (dazu muss der Editor per Startmenü Eintrag aufgerufen werden)

  • Autocomplete für Syntaxelemente und Variablen

  • Frei definierbare und wiederverwendbare Codeblöcke (“Snippets”)

Die Kernkomponente des Editors bildet das Modul Scintilla, welches auch in andere bekannten Editoren, wie bspw. Notepad++, verwendet wird. Die lexikalischen Elemente (Syntaxhervorhebung und Faltung) zur Darstellung der für opsi gültigen Scriptsprache sind allerdings komplett in AutoIt geschrieben, da Scintilla für opsi Skripte kein eigenes Darstellungsmodul mitliefert. Dadurch, dass AutoIt eine Interpretersprache ist, ist er damit langsamer als andere Editoren und eignet sich daher nur bedingt zur Bearbeitung sehr großer Skripte, vor allem bei eingeschalteter Quellcode Faltung. In den Einstellungen lässt sich jedoch vorgeben, ob der Editor mit diesen Funktionen überhaupt aufgerufen wird oder nicht, sofern der Aufruf direkt über den Skriptbaum erfolgt. Bei einem Aufruf über den Link im Startmenü sind Syntaxhervorhebung und Faltung generell beim Start ausgeschaltet und können über das Editormenü “Ansicht” aktiviert werden.

(Der Editor kann auch über die Kommandozeile aufgerufen werden. Weitere Informationen zu den möglichen Kommandozeilenparametern können mit der Option “–help” aufgerufen werden.)

Reiter Produktvariablen (Properties)
Abbildung 22. opsi PackageBuilder Reiter Produktvariablen (Properties)

In desem Reiter sehen auf der Linken Seite die Produkt Properties des opsi-Produktes wie Sie auch schon in opsi-setup-detector: Properties erläutert wurden.

Reiter Abhängigkeiten
Abbildung 23. opsi PackageBuilder Reiter Abhängigkeiten

In desem Reiter sehen auf der Linken Seite die Produkt Abhängigkeiten des opsi-Produktes wie Sie auch schon in opsi-setup-detector: Priorität und Abhängigkeiten erläutert wurden.

Button: Packen
Abbildung 24. opsi PackageBuilder Button: Packen

Dieser Button startet eine SSH-Verbindung vom Server und ruft dort den Paketierungsbefehl auf.
Sie können das selbe auch in einem Terminal selber machen wie in Packen mit opsi-makepackage beschrieben.

Button: Installieren
Abbildung 25. opsi PackageBuilder Button: Installieren

Dieser Button startet eine SSH-Verbindung vom Server und ruft dort den Installationsbefehl auf um das Produkt auf dem Server zu installieren.
Sie können das selbe auch in einem Terminal selber machen wie in Installieren mit opsi-package-manager beschrieben.

Button: Installieren + Setup
Abbildung 26. opsi PackageBuilder Button: Installieren + Setup

Finger weg!

Testen und verbessern eines opsi-script Skriptes

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

  • Testen des erstellten Scriptes 'Standalone' also ohne es auf dem opsi-server zu installieren und es von dort auf den Client auszurollen

  • 'Integrierte' Tests des kompletten Produktes mit Installation auf dem Server und Ausrollen auf einem Client

In beiden Fällen gehen wir hier davon aus, das Sie ein Projekt mit dem opsi-setup-detector erstellt haben.

'Standalone' Tests

Starten Sie die Anwendung opsi-script-gui: per Doppelklick.

  • Windows: Die Datei opsi-script.exe per Doppelklick.
    (Beim Starten des Programms auf einem Windows 7 / 10 Client muss "ausführen als Administrator" über die rechte Maustaste verwendet werden.) Wenn der opsi-client-agent bereits auf Ihrem Rechner installiert ist, finden Sie diese unter C:\Program files (x86)\opsi.org\opsi-client-agent\opsi-script\opsi-script.exe Wenn nicht, kopieren Sie sich vom share \\<opsiserver\opsi_depot, aus dem Verzeichnis opsi-script\windows\x86\ den Inhalt des Verzeichnisses.

  • Linux: Starten sie Datei /usr/bin/opsi-script

  • MacOS: Starten sie die Anwendung /Applications/opsi-script

Sie sehen dann folgendes Fenster:

Screenshot: opsi-script-gui im interaktiven Modus
Abbildung 27. opsi-script-gui im interaktiven Modus
  • Über Select Script können Sie das Skript auswählen, dass Sie ausführen möchten.

  • Mit Start können Sie das Script starten. Dabei wird das Script auf diesem Rechner ausgeführt.

  • Mit Test_Syntax können Sie das Script auf Syntaxfehler prüfen. Dabei wird das Script auf diesem Rechner nicht ausgeführt.
    siehe auch: https://docs.opsi.org/opsi-docs-de/4.2/opsi-script-manual/cli-params.html#opsi-script-testsyntax

  • Öffnen Sie nun mit dem opsi-logviewer die Log-Datei an, um nachzuvollziehen, wie der opsi-script das Skript interpretiert.
    Achten Sie dabei darauf, das Sie hier mit dem Schieberegler rechts unten den angezeigten Loglevel einstellen können.

  • Öffnen Sie das Script setup.opsiscript in einem Editor und führen Sie gewünschte Änderungen durch (Speichern nicht vergessen). Dazu gibt es mehrere Möglichkeiten:

    • Öffnen Sie das Projekt im opsi PackageBuilder und öffnen von dort den Editor.

    • Im Prinzip können Sie auch jeden anderen beliebigen Editor verwenden.
      Wir empfehlen den Editor 'jEdit' mit opsi-script Syntax-Highlighting, wie Sie ihn in der Grundausstattung der opsi-Produkte finden.

jEdit with a opsi script
Abbildung 28. jEdit mit einem opsi script
  • Sie können nun das Skript im Editor anpassen und speichern (Sie können den Editor geöffnet lassen).
    Wechseln Sie zum opsi-script-Fenster und starten Sie das Skript erneut über den Knopf 'Start' (das Skript muss nicht neu ausgewählt werden).
    Schauen Sie sich das auf Basis Ihrer Änderungen im Skript veränderte Log über opsi-logviewer an. (Neu laden über Kontext Menü oder Button in der Symbolleiste nicht vergessen).

  • Auf diese Art und Weise, also über die Wiederholung der Punkte:

    • Anpassung des Skriptes und speichern

    • Skript ausführen

    • Log überprüfen
      können Sie nach und nach Ihre Skripte so anpassen, dass sie das tun, was Sie wünschen.

Hinweise zur Lösung von Detail-Problemen finden Sie im nächsten Kapitel. Im übernächsten Kapitel wird erklärt, wie Sie aus den so erstellten Skripten ein opsi-Produkt erstellen, das Sie auf dem opsi-Server installieren können.

'Integrierte' Tests

Bei den 'integrierten Test' wird immer gleich das ganze Projekt per opsi auf einem Testclient ausgeführt. Gehen Sie dazu wie folgt vor:

  • Öffnen Sie das Script setup.opsiscript in einem Editor und führen Sie gewünschte Änderungen durch (Speichern nicht vergessen). Dazu gibt es mehrere Möglichkeiten:

    • Öffnen Sie das Projekt im _opsi PackageBuilder' und öffnen von dort den Editor.

    • Im Prinzip können Sie auch jeden anderen beliebigen Editor verwenden.
      Wir empfehlen den Editor 'jEdit' mit opsi-script Syntax-Highlighting, wie Sie ihn in der Grundausstattung der opsi-Produkte finden.

  • Produkt Packen

    • Variante 1: Öffnen Sie das Projekt im opsi PackageBuilder und starten Sie das Packen über den Button Packen.

    • Variante 2: Melden Sie sich per Terminal (z.B. Putty) auf dem opsi-server an und wechseln Sie in das Projektverzeichnis auf der Workbench. Packen Sie das Produkt per Befehl opsi-makepackage.

  • Produkt auf dem opsi-server installieren.

    • Variante 1: Starten Sie das Installieren im opsi PackageBuilder über den Button Installieren.

    • Variante 2: Starten Sie das Installieren im Terminal im Projektverzeichnis mit dem Befehl opsi-package-manager -i <myproctid_version.opsi>. Dabei ist <myproctid_version.opsi> der Dateiname der im vorherigen Schritt beim packen ausgegeben wurde.

  • Produkt über opsi-configed auswählen und starten

    1. Im Tab Clients den Testclient auswählen

    2. Im Tab Produktkonfiguration das Produkt auswählen. Sollte das Produkt nicht sichtbar sein (was nach dem ersten Installieren normal ist) einmal über das Menü 'Datei / Alle Daten neu laden' bzw. den Button ganz links in der Symbolleiste die Daten neu laden

    3. Für das gewählte Produkt die Aktionsanforderung setup setzen und speichern.

    4. Den Client starten oder bei laufenden Client per Kontextmenü on_demand starten.

    5. Abwarten bis das Produkt auf dem Client durchgelaufen ist.

      • Im Tab 'Logfiles / instlog' die Log-Datei inspizieren, um nachzuvollziehen, wie der opsi-script das Skript interpretiert.
        Achten Sie dabei darauf, das Sie hier mit dem Schieberegler rechts unten den angezeigten Loglevel einstellen können.

  • Auf diese Art und Weise, also über die Wiederholung der Punkte:

    • Anpassung des Skriptes und speichern

    • Produkt packen

    • Produkt auf dem Server installieren

    • Produkt auf dem Client ausführen

    • Log überprüfen
      können Sie nach und nach Ihre Skripte so anpassen, dass sie das tun, was Sie wünschen.

Packen mit opsi-makepackage

Danach können Sie das Produkt packen. Gehen Sie dazu in das Stammverzeichnis des Produkts und rufen Sie 'opsi-makepackage' auf. Es wird nun das Produkt gepackt.

Es ist zu empfehlen die Pakete gleich mit einer zugehörigen md5-Prüfsummendatei zu erstellen. Diese Datei wird unter anderem vom opsi-package-updater genutzt, um nach der Paketübertragung die Paketintegrität sicher zu stellen. Eine solche Datei wird automatisch erstellt, aber für besondere Einsatzszenarien kann die Erstellung unterdrückt werden.

Bei der Übertragung von Paketen auf opsi-Depotserver kann auf 'zsync' zurück gegriffen werden, um nur Unterschiede zwischen verschiedenen Paketen zu übertragen. Damit dieses Verfahren verwendet werde kann, wird eine Datei besondere .zsync-Datei benötigt. Eine solche Datei wird automatisch erstellt, aber für besondere Einsatzszenarien kann die Erstellung unterdrückt werden.

Wenn es beim Erstellen großer Pakete zu Platzproblemen im temporären Verzeichnis /tmp kommt, ist es möglich mittels --temp-directory ein abweichendes temporäres Verzeichnis anzugeben.

Wenn schon ein Paket dieser Version existiert, so zeigt opsi-makepackage eine Rückfrage:

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:

Mit o wählen Sie überschreiben, mit c brechen Sie den Vorgang ab und mit n können Sie wählen, dass Sie nach einer neuen Product- bzw. Package-Version gefragt werden.

Das gepackte Paket können Sie mit opsi-package-manager --install <paketdatei> auf dem Server installieren.

Mehr Details zum opsi-makepackage finden Sie im opsi-manual:
opsi-makepackage

Installieren mit opsi-package-manager

Um das gepackte Produkt zu installieren gibt es den Befehl opsi-package-manager . Gehen Sie dazu in das Stammverzeichnis des Produkts und rufen Sie folgenden Befehl auf.

opsi-package-manager -i <myproductid_version.opsi>

Mehr Details zum opsi-package-manager finden Sie im opsi-manual:
opsi-package-manager

Beispiel einer 'control' Datei

[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

Erstellen eines opsi-paketes mit dem CLI tool opsi-newprod

opsi-newprod ist ein Kommandozeilen Werkzeug zum Erstellen eines opsi-product Gerüstes.

Zum Erstellen wechselt man in dieses Verzeichnis und ruft opsi-newprod auf. Das Programm fragt daraufhin nach dem Typ des zu erstellenden Paketes. Dies ist üblicherweise der Typ localboot für Produkte, die über den 'opsi-client-agent'/'opsi-winst' installiert werden. Der Typ netboot steht für Produkte, die über das opsi-Linux-Bootimage ausgeführt werden (wie z.B. die Betriebssystem-Installationen).

Screenshot: Auswahl des Produkttyps: localboot
Abbildung 29. Auswahl des Produkttyps: localboot

Wählen Sie nun mit Tab OK (oder bestätigen mit F12). Nun müssen Sie die wesentlichen Produktdaten eingeben. Am oberen Rand ist hierzu eine Hilfe, die erläutert was die Felder bedeuten.

Screenshot: Eingabe der Produktinformationen
Abbildung 30. Eingabe der Produktinformationen
Product Id

ist ein eindeutiger Bezeichner für das Produkt in der Regel unabhängig von der Version
Bitte nur Kleinbuchstaben verwenden, keine Umlaute, keine Leerzeichen, keine Sonderzeichen - '-' ist als Trenner erlaubt.

Product name

ist der Klartextname des Produkts (wir empfehlen die Vermeidung von Umlauten, '-' ist erlaubt, keine Leerzeichen).

Description

ist eine ergänzende Beschreibung zum Produkt, die z.B. im opsi-Configeditor unter Beschreibung angezeigt wird.

Advice

ist eine ergänzende Beschreibung, in der Regel zum Umgang mit dem Produkt, die zu beachten ist und im opsi-Configeditor unter Notiz angezeigt wird.

Product version

ist die Version der eingepackten Software (max. 32 Zeichen).

Package Version

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

License required

hat bei localboot Produkten keinen Einfluss. Bei netboot Produkten entscheidet diese Option, ob ein Lizenzkey aus dem Lizenzmanagement geholt wird.

Priority

beeinflusst die Installationsreihenfolge. Mögliche Werte liegen zwischen 100 (ganz am Anfang) und -100 (ganz am Ende). Existieren auch Produktabhängigkeiten, so beeinflussen diese zusätzlich die Installationsreihenfolge.

Screenshot: Eingabe der opsi-winst-Skript Namen für unterschiedliche Aktionen
Abbildung 31. Eingabe der opsi-winst-Skript Namen für unterschiedliche Aktionen

Nach Eingabe der Produktinformationen werden Sie aufgefordert, die Skripte anzugeben, die Sie für die unterschiedlichen möglichen Aktionen bereit stellen werden.

Üblicherweise heißt das Setup script gleich setup.opsiscript.

Üblicherweise heißt das Uninstall script gleich uninstall.opsiscript.

Ein Update-Script 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 auch das Update-Skript ausgeführt.

Ein Always-Script wird bei jedem aktiv werden des opsi-Clientagenten ausgeführt (z.B. bei jedem Boot).

Ein Once-Script hat den Folgestatus not_installed. Es handelt sich hierbei um einen sehr selten verwendeten Schalter, den Sie ignorieren sollten, wenn Sie nicht genau wissen, was Sie damit tun wollen.

Ein Custom-Script verändert weder Folgeaktion noch 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.

Ein userLoginScript dient dazu nach dem Login des users Modifikationen am Profil des eingeloggten users vorzunehmen. Dies Funktioniert nur im Zusammenhang mit der opsi Erweiterung 'User Profile Management' und ist im entsprechenden Kapitel des opsi-Handbuchs beschrieben.

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 selber beschrieben ist, können Sie eine oder mehrere Produktabhängigkeiten definieren. Wollen Sie keine Produktabhängigkeit definieren so geben Sie No ein.

Screenshot: Eine (weitere) Produktabhängigkeit definieren: Ja / Nein
Abbildung 32. Eine (weitere) Produktabhängigkeit definieren: Ja / Nein

Zur Erstellung einer Produktabhängigkeit geben Sie die folgenden Daten an. Beachten Sie auch die Hilfe im oberen Teil des Fensters:

Screenshot: Eingabe der Daten zur Erstellung einer Produktabhängigkeit
Abbildung 33. Eingabe der Daten zur Erstellung einer Produktabhängigkeit
Dependency for Action

Für welche Aktion des Produktes, welches Sie gerade erstellen, soll die Abhängigkeit gelten (nur setup implementiert).

Required product id

Productid (Bezeichner) des Produkts zu dem eine Abhängigkeit besteht.

Required action

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

Required installation status

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

Requirement type

Installationsreihenfolge. Wenn das Produkt, zu dem eine Abhängigkeit besteht, installiert sein muss bevor mit der Installation des aktuellen Produkts begonnen werden kann, dann ist dies before. Muss es nach dem aktuellen Produkt installiert werden so ist dies after. Ist die Reihenfolge egal so muss hier nichts eingetragen werden.

Hinweis:

Leider gibt es derzeit keinen generischen Mechanismus für Deinstallations-Produktabhängigkeiten. Zuverlässig ist der ProductDependency-Mechanismus nur für action: setup und die hierbei zu triggernden (before- oder after-) setup Aktionen und installed Status. Ein requiredAction: uninstall führt leider definitiv zu Fehlern.

Nachdem eine Produktabhängigkeit definiert ist, werden Sie wieder gefragt, ob Sie eine (weitere) Produktabhängigkeit definieren wollen. Wenn ja, wiederholt sich der Vorgang; wenn nein, so werden Sie gefragt, ob Sie eine Produkteigenschaft (Zusatzschalter) definieren wollen mit dem Sie die Installation des Produktes modifizieren können.

Noch ein Hinweis:

Die tatsächliche Installationsreihenfolge ermittelt sich aus einer Kombination von Produktabhängigkeiten und Produktpriorisierung. Details hierzu finden Sie im opsi-Handbuch im Kapitel 'Beeinflussung der Installationsreihenfolge durch Prioritäten und Produktabhängigkeiten'

Screenshot: Eine (weitere) Produkteigenschaft definieren
Abbildung 34. Eine (weitere) Produkteigenschaft definieren

Antworten Sie ja, so müssen Sie die Produkteigenschaft beschreiben:

Die Produkteigenschaft wird clientspezifisch gespeichert und besteht aus einem Namen (key) der verschiedene Werte (Values) zugeordnet bekommen kann und die dann vom opsi-winst-Skript abgefragt werden können.

Zunächst müssen Sie angeben, ob es sich um ein Textwert (unicode) oder um einen logische Wert also wahr/falsch (boolean) handelt. Wenn Sie unsicher sind, wählen Sie unicode.

Screenshot: Datentyp der Produkteigenschaft wählen
Abbildung 35. Datentyp der Produkteigenschaft wählen

Weiterhin wird eine Beschreibung benötigt, die im opsi-configed als Hilfe angezeigt wird. Weiterhin müssen Sie, durch Kommas getrennt, alle Werte angeben, die der Key annehmen darf. Wird hier nichts angegeben, so kann später im opsi-Configeditor ein beliebiger Wert eingegeben werden. Über Editable (true/false) können Sie entscheiden, ob neben der vorgegebenen Liste auch andere Werte eingegeben werden dürfen.

Enthält ein Wert einen Backslash \, so muss dieser doppelt angegeben werden.
Eine Pfadangabe kann beispielsweise wie folgt aussehen: C:\\temp
Screenshot: Beschreibung der Produkteigenschaft
Abbildung 36. Beschreibung der Produkteigenschaft

Im Folgefenster müssen Sie festlegen, was der Defaultwert dieser Produkteigenschaft ist.

Screenshot: Festlegung des Defaultwerts der Produkteigenschaft
Abbildung 37. Festlegung des Defaultwerts der Produkteigenschaft

Wenn Sie als Typ 'boolean' wählen, so reduziert sich die Beschreibung auf 'Property name' und 'Property description'.

Screenshot: Beschreibung eines boolschen Properties
Abbildung 38. Beschreibung eines boolschen Properties

Nachdem eine Produkteigenschaft definiert ist, werden Sie wieder gefragt, ob Sie eine (weitere) Produkteigenschaft definieren wollen. Wenn ja, wiederholt sich der Vorgang; wenn nein, so werden Sie als nächstes nach Name und Mail-Adresse gefragt. Diese werden im Changelog des Paketes verwendet und müssen angegeben werden.

Screenshot: Eingabe der Maintainer Daten
Abbildung 39. Eingabe der Maintainer Daten

Danach ist das Grundgerüst des Produktes fertig gestellt.

Mithilfe des ls Befehls finden Sie die oben beschriebene Verzeichnis Struktur. Wechseln Sie in den OPSI-Ordner und setzen Sie erneut den ls Befehl ab. Hier befindet sich unter anderem die 'control'-Datei, welche die eben eingegebenen Daten enthält und Ihnen auch die Möglichkeit bietet, diese im Editor zu kontrollieren oder zu modifizieren.

Hinweise zu den Teilaufgaben in der Paketierung

Opsi-setup-detector: Support custom directory

Der opsi-setup-detector enthält in dem Tab "Produkt Konfiguration 1" die Checkbox:
Unterstütze custom directory : Das Produkt erhält ein zusätzliches Verzeichnis 'custom' welches Kunden spezifische Dateien enthalten kann. Bei der Installation einer neuen Version des Paketes auf dem Server wird das vorhandene custom Verzeichnis erhalten. Der Code enthält Vorlagen um Dateien aus diesem Verzeichnis in die Installation einzufügen.

In die setup.opsiscript wird eingefügt:
Der Aufruf einer Files Sektion um Dateien vom 'custom' Verzeichnis auf den Client zu kopieren:

; copy custom files to install dir
Files_copy_from_custom_dir

sowie die dazugehörige Sektion. In diesem Beispiel wird der Inhalt das 'custom' Verzeichnisses in das Installationsverzeichnis kopiert:

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

Weiterhin wird das 'custom' Verzeichnis selbst erzeugt und eine OPSI\preinst und OPSI\postinst Datei, welche dafür sorgen, das der Inhalt des 'custom' Verzeichnisses auf dem Depot bei Installationen von Produktupdates erhalten bleibt.

Opsi-setup-detector: Installiere von lokalem, temporären Verzeichnis

Der opsi-setup-detector enthält in dem Tab "Produkt Konfiguration 1" die Checkbox:
Installiere von lokalem, temporären Verzeichnis : Die installationsdateien werden zunächst in ein lokales, temporäres Verzeichnis kopiert und dann aus diesem Verzeichnis heraus installiert. Insbesondere sinnvoll für alles was bei der Installation die Netzwerkverbindung beeinträchtigen könnte (z.B. Treiber).

Es wird ein zusätzliches boolsches Property erzeugt: install_from_local_tmpdir mit dem Default 'False' und der Beschreibung: 'Bestimmt ob die Installationsdateien nach lokal kopiert werden'.

In die setup.opsiscript wird eingefügt:
Der Aufruf einer Files Sektion um die Installerdateien vom $installerSourceDir$ Verzeichnis auf den Client zu kopieren. Sowie den Aufruf um nach der Installation die temporären Dateien wieder zu löschen:

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

sowie die dazugehörigen Sektionen.

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

Opsi-setup-detector: Behandle Lizenzkeys

Der opsi-setup-detector enthält in dem Tab "Produkt Konfiguration 1" die Checkbox:
Behandle Lizenzkeys : Fügt Property und Code zur Behandlung von Lizenzkeys hinzu.

Es wird ein zusätzliches Property erzeugt: secretlicense_or_pool mit dem Default '' und der Beschreibung: 'Lizenzkey oder opsi Lizenzpool'. Das Schlüsselwort 'secret' im Propertynamen führt dazu, dass im opsi-configed, der Wert des Properties nur maskiert angezeigt wird.

In die setup.opsiscript wird eingefügt:
Der Aufruf von get_licensekey_byPoolOrKey prüft ob der Propertywert evtl. ein Lizenzpool name aus der opsi-Erweiterung Lizenzmanagement ist.
Wenn ja, so wird ein Lizenzkey aus diesem Pool geliefert.
Wenn nein, so wird der Inhalt des Property als Lizenzkey geliefert.

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

In die uninstall.opsiscript wird 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

Opsi-setup-detector: DesktopIcon

Der opsi-setup-detector enthält in dem Tab "Produkt Konfiguration 1" die Checkbox:
DesktopIcon : Fügt Property und Code zur Behandlung von Desktop Icons hinzu.

Es wird ein zusätzliches boolsches Property erzeugt: desktopicon mit dem Default 'False' und der Beschreibung: 'Soll es ein Desktopicon geben ?'.

In die setup.opsiscript wird eingefügt:
Der Aufruf einer Linkfolder Sektion zum Erstellen oder Entfernen des Desktop Icon:

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

sowie die dazugehörigen Sektionen, welche auch in die uninstall.opsiscript eingefügt werden:

[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 delinc.opsiinc wird eingefügt:

comment "Start Remove Desktop Icon Handling :"
Linkfolder_remove_desktop_icon

Opsi-setup-detector: Customize Profile

Der opsi-setup-detector enthält in dem Tab "Produkt Konfiguration 1" die Checkbox:

Customize Profile : Ergänzt den Code um eine 'Profileactions' Sektion um Anpassungen in den lokalen Userprofilen durchzuführen. Diese Funktionalität wird auch über ein loginscript für 'Roaming Profiles' bereitgestellt.

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

In die setup.opsiscript wird eingefügt:
Der Aufruf einer ProfileActions Sektion. Diese wird je nach Aufruftyp für alle lokalen Profile oder für den gerade eingeloggtem Benutzer ausgeführt: Für Details siehe : https://docs.opsi.org/opsi-docs-de/4.2/manual/modules/user-profile.html

; Run the customization for user profiles
ProfileActions

sowie die dazugehörigen Sektionen, welche templates für Aufrufe zur Manipulation der User Profiles sind.:

[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

Installation mit angemeldetem Benutzer

Vereinzelt taucht das Problem auf, dass sich Installationen nur bei angemeldetem Benutzer durchführen lassen. Ein Hinweis auf diese Problematik ist es, wenn ein opsi-script-Skript das eine unattended Installation enthält, beim manuellen Aufruf durch einen administrativen Benutzer funktioniert, im Rahmen der automatischen Installation über opsi jedoch scheitert.

Eine mögliche Ursache ist dann, dass dieses Setupprogramm einen angemeldeten Benutzer bzw. den Zugriff auf ein Benutzer-Profil benötigt.

In einem solchen Fall können Sie Ihre Installation in ein opsi-Rahmenpaket einbinden das diese benötigten Voraussetzungen schafft.
Dies können Sie über den opsi-setup-detector über die Windows Aufgabe Analysiere Datei und erzeuge ein Paket 'with user' erledigen.

Customizing nach einer silent/unattended Installation

Häufig will man nach einer erfolgreichen Silent-Installation Anpassungen an der Installation vornehmen. Hierzu bietet der opsi-script ein mächtiges Werkzeug. Doch bevor dies eingesetzt werden kann muss oft ermittelt werden, welche in der graphischen Oberfläche getätigten Änderungen zu welchen Veränderungen in Dateien und der Registry führen.

Hierzu können Werkzeuge verwendet werden wie z.B.:

Einbindung mittels interaktiven Setup-Programms und automatisierten Antworten

Eine weitere schnelle Möglichkeit zur Einbindung in die automatische Softwareverteilung ist das 'Setup mit automatisierten Antworten'. Hierzu wird eine Steuerungs-Software verwendet, die über ein Skript die Interaktion eines Anwenders mit den erscheinenden Dialog-Fenstern automatisiert.
Wir empfehlen hierfür den Einsatz der Software AutoHotkey oder AutoIt.

'AutoIt' bietet eine ganze Reihe zusätzlicher Möglichkeiten, den Setup-Prozess zu steuern. Auch eventuelle Fehlerzustände können (so vorher bekannt) mit dem Einsatz von [ADLIB]-Sektionen im Skript abgefangen werden.

Ein prinzipielles Problem bleibt 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.

Sehr gut kann auch eine Kombination aus beiden Ansätzen funktionieren: Das Silent-Setup übernimmt die eigentliche Installation und ein AutoIt-Skript fängt bekannte Sonderbedingungen ab.

Wenn das Ausführen von Installationen in der opsi-client-agent Konfiguration auf einen anderen Desktop verlegt wird oder der Desktop gesperrt wird, haben verschiedene autoit Funktionen Probleme.

Daher sollten in 'opsi-script' Skripten die folgenden Funktionen gemieden werden:

  • winwait()

  • winactivate()

  • Send()

Das sind leider genau die 3 am meisten verwendeten.

Wir empfehlen zur Ersetzung dieser Befehle die Verwendung der mit dem opsi-script mit gelieferten autIt Library: C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-script\lib\opsi-autoit-lib.au3. Diese bietet neben den hier vorgestellten erweiterten Funktionen auch noch ein logging. Sie können diese Datei in das Produktverzeichnis kopieren und dann in den AutoIT code einbinden mit: #include "%scriptpath%\opsi-autoit-lib.au3"

winwait()
kann ersetzt werden durch die Funktion
opsiwinwait($title, $text, $maxseconds, $logname)

Send()
kann ersetzt werden durch die Funktion
opsiControlClick($title, $text, $id, $maxseconds, $logname)
bzw. durch
opsiControlSetText($title, $text, $id,$sendtext, $maxseconds, $logname)

Es empfiehlt sich zur Identifikation der Controls mit der Au3info.exe die 'ControlId' ermittelt werden. Bitte die numerische 'ControlId' verwenden, andere Varianten scheinen Probleme zu machen.

Beispiele finden sie in: C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-script\lib\ in den Dateien autoit_example_1.txt und autoit_example_1.txt.

Analyse und Neu-Paketieren

Wenn der Entwickler einer Anwendung ein Paket zur Auslieferung der Anwendung schnürt, kennt er die benötigten Komponenten. Im Nachhinein, wenn schon ein Paket existiert, das mittels eines Setup-Programm zu installieren ist, kann die Kenntnis, welche Komponenten installiert werden müssen, damit eine Anwendung wie gewünscht auf einem Arbeitsplatzrechner lauffähig ist, aus der Studie der Effekte bei der Ausführung des vorhandenen Setup-Programms gewonnen werden.

Eine Reihe von Werkzeuge zum Analysieren von Setup-Programmen kommen hierbei in Frage. So z.B.:

Verfahren zur Deinstallation von Produkten

Um eine installierte Software von einem Rechner zu entfernen, kann ein Deinstallations-Skript erstellt werden. Grundsätzlich besteht bei einer Deinstallation die Schwierigkeit, dass nicht immer klar ist, wie das Produkt auf dem Rechner vorliegt und was alles entfernt werden muss. Auch nach der Installation können neue Dateien oder Registry-Einträge, die die Software betreffen, hinzugekommen sein. Weiterhin muss darauf geachtet werden nicht zu viel zu entfernen, um die Systemstabilität nicht zu gefährden. Meist weiß nur der Hersteller genau, wie mit seinem Produkt bei der Deinstallation umzugehen ist. Ähnlich wie bei der Installation, existieren zu diesem Zweck Deinstallations-Routinen, die dem Produkt beiliegen. Wenn es die Möglichkeit gibt, diese ohne Benutzer-Interaktion auszuführen, kann dies schon ein entscheidender Schritt sein. Ist eine solche Routine nicht vorhanden oder muss diese erweitert werden, so existieren viele opsi-script-Befehle, die zur Deinstallation nützlich sein können. Im Folgenden soll nun ein Überblick über Möglichkeiten zur Deinstallation gegeben werden, die durch Beispiele verdeutlicht werden.

Verwenden einer Deinstallations-Routine

Liefert der Hersteller des Produkts ein Programm (oder ein MSI-Paket) zur Deinstallation, so muss zunächst geprüft werden, ob dies auch ohne Benutzer-Interaktion ausgeführt werden kann (silent-mode). Sollte dies nicht von Hause aus möglich sein, kann der Einsatz eines AutoIt-Skriptes in Verbindung mit der Deinstallations-Routine hilfreich sein. Der Aufruf der ausführbaren Datei kann im opsi-script-Skript in einer Winbatch-Sektion geschehen, z.B.:

[WinBatch_start_ThunderbirdUninstall]
"%SystemRoot%\UninstallThunderbird.exe" /ma

Trotz dieser Unterstützung des Herstellers sollte man sich jedoch nicht auf die korrekte Beseitigung des Produkts verlassen und auf einem Testsystem zusätzlich prüfen, ob das System nach der Deinstallation weiter stabil läuft und ob Dateien oder Registry-Einträge zurückgeblieben sind.

Sollten diese Methoden nicht oder nicht vollständig funktionieren, so muss mit einem opsi-script-Skript nachgeholfen werden, wie es im nächsten Abschnitt beschrieben ist.

Nützliche opsi-script-Befehle zur Deinstallation

Wurde ein Produkt mit den opsi-script-Funktionen installiert oder gibt es keine Deinstallation vom Hersteller, so muss ein eigenes opsi-script-Skript zu Deinstallation geschrieben werden. Um den Programmierer bei dieser Arbeit zu unterstützen stellt der 'opsi-script' einige Funktionen bereit, die speziell bei der Deinstallation notwendig oder hilfreich sind. Es soll an dieser Stelle nur ein kurzer Überblick gegeben werden, eine genaue Beschreibung der Befehle und deren Parameter findet sich im opsi-script-Handbuch.

Der einfachste Fall ist das Löschen einer oder mehrerer Dateien vom System. Dies geschieht in einer Files-Sektion mittels des Befehls

delete -f Dateiname

oder für ein Verzeichnis mit Unterverzeichnissen

delete -sf Verzeichnisname\

Der Parameter f steht dabei für force, um die Datei wirklich zu löschen, auch wenn diese schreibgeschützt ist, der Parameter s für subdirectories (mit Unterverzeichnissen/rekursiv). Soll eine Datei oder ein Verzeichnis aus allen Benutzer-Profilen gelöscht werden, so kann diese Files-Sektion mit dem Parameter /AllNTUserProfiles aufgerufen werden. (siehe opsi-script-Handbuch)

Möchte man einen Verzeichnisbaum löschen, in dem sich auch Dateien mit dem Attribut „versteckt“ oder „systemdatei“ befinden, muss momentan ein Umweg über den Befehl rmdir gegangen werden, der über eine 'ShellScript'-Sektion aufgerufen werden kann.

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

Muss vor dem Löschen evtl. ein laufender Prozess beendet werden, so kann dies mit dem Namen des Prozesses (zu sehen im Task-Manager) und dem opsi-script-Befehl KillTask geschehen:

KillTask "thunderbird.exe"

Sollte das Produkt – oder Teile davon – als Service laufen, so muss dieser vor der Deinstallation beendet werden. Man kann dazu den Service in der Registry auf “inaktiv“ schalten und den Rechner neu starten oder aber man benutzt den System-Befehl net mit dem Parameter stop, um den Service sofort zu stoppen und anschließend – ohne Neustart – die zugehörigen Dateien zu löschen.

net stop <servicename>

Besondere Vorsicht ist beim Löschen von .dll-Dateien geboten, die noch von anderen Produkten verwendet werden könnten. Sie müssen individuell behandelt werden, weshalb hier leider kein allgemein gültiges Rezept gegeben werden kann.

Um einzelne Einträge aus der Registry mittels opsi-script zu löschen, kommt der Befehl DeleteVar zum Einsatz, der innerhalb einer 'Registry'-Sektion eines opsi-script-Skripts verwendet werden kann. Er löscht Einträge aus dem momentan geöffneten Key:

DeleteVar <VarName>

Möchte man einen Registry-Key samt seiner Unterschlüssel und Registry-Variablen löschen, so geschieht dies mittels des opsi-script-Befehls DeleteKey, z.B.:

DeleteKey [HKLM\Software\Macromedia]

Verfahren zur Deinstallation von MSI Produkten

Falls das Produkt als MSI-Paket bereitgestellt und mittels 'msiexec' installiert wurde, ist es in der Regel auch eine Deinstallation mittels 'msiexec' möglich. Dazu ruft man den msiexec.exe mit dem Parameter /x auf. Um die Benutzer-Interaktion zu deaktivieren, kann zusätzlich der Parameter /qb-! übergeben werden.
Um das MSI Paket zu identifizieren muß weiterhin noch die GUID (Global Unique ID) des Paketes übergeben werden. Die GUID identifiziert das MSI Paket und ist Bestandteil der MSI-Datei. Diese ID ist eindeutig, Produkt-spezifisch und auf allen Systemen, auf denen das MSI-Paket installiert ist, gleich.
Sie findet sich zum Beispiel im Zweig HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall der Registry.
Ein Beispiel einer Deinstallation mittels dieser GUID sieht folgendermaßen aus:

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

Die GUID kann sich beim selben Produkt von Version zu Version ändern. Um vorhandene und evtl. ältere Installationen zu löschen, muss also ermittelt werden welche GUID diese Installationen haben.
Eine Möglichkeit dies zu tun geht über den MsiName des Paketes welcher vom opsi-setup-detector aus der MSI-Datei ermittelt werden kann. Der MsiName wird im oben erwähnten Uninstalleintrag in der Registry als DisplayName verwendet. Daher kann der MsiName verwendet werden um die passenden GUID’s in der Registry zu finden.
Um das zu tun, müssen Informationen zu Architektur und Version vom Ende des MsiName abgeschnitten werden und das ganze in eine regular expression verpackt werden.

Dies ist der Code der vom opsi-setup-detector zu Deinstallation von MSI erzeugt wird:

; Finding the MsiId by the Displayname from Registry:
; Be sure that the Displayname is set correctly:
Set $DisplayName$ = 'short msi name'
; escape all regex relevant chars with '\' : '\^$.|?*+()[{'
set $DisplayNameRegex$ = escapeRegexMetaChars($DisplayName$)
; '(?i)' = case insensitive ; '.*' = 0 or more of any thing
set $DisplayNameRegex$ = '(?i)'+$DisplayNameRegex$+'.*'
Set $UninstallList$ = getGuidListByDisplaynameRegex($DisplayNameRegex$)
;-----------------------------------------------------

; ---------------------------------------------------------------
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

Kurze Beschreibung was in diesem Scriptteil passiert:

  • Set $DisplayName$ = 'short msi name'
    Setzen der Variable $DisplayName$ auf den MsiName gekürzt um störende anhängende Informationen.

  • Den $DisplayName$ als regular expression Suchstring präparieren:
    Alle regular expression Sonderzeichen verstecken (maskieren):
    set $DisplayNameRegex$ = escapeRegexMetaChars($DisplayName$)
    Angeben, das der Suchstring am Anfang der Zeile steht und 0 oder mehr beliebige Zeichen folgen dürfen:
    set $DisplayNameRegex$ = '(?i)'+$DisplayNameRegex$+'.*'

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

  • Die Deinstallation durchführen: Nun können wir die Liste durchgehen und die gefundenen GUIDs zur Deinstalltion verwenden. Die passiert in der Sektion: [Sub_Uninstallation_msi]

Bekannte Besonderheiten der 64 Bit-Unterstützung

Der 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 allgemein beim Arbeiten auf 64-Bit-Systemen beachten Sie bitte das entsprechende Kapitel im opsi-script manual, 64 Bit-Unterstützung unter Windows.