Syntax und Bedeutung der primären Sektionen eines opsi-script Skriptes [W/L/M]
Wie bereits in Abschnitt Primäre und sekundäre Unterprogramme des opsi-script Skriptes dargestellt, zeichnen sich die Actions-Sektion dadurch aus, dass sie den globalen Ablauf der Abarbeitung eines opsi-script-Skriptes beschreiben und insbesondere die Möglichkeit des Aufrufs von Unterprogrammen, sekundärer oder geschachtelter primärer Sektionen bieten.
Diese Unterprogramme heißen Sub-Sektionen – welche wiederum in der Lage sind, rekursiv weitere Sub-Sektionen aufzurufen.
Der vorliegende Abschnitt beschreibt den Aufbau und die Verwendungsweisen der primären Sektionen des opsi-script Skriptes.
Die primären Sektionen [W/L/M]
In einem Skript können vier Arten primärer Sektionen vorkommen:
-
eine Initial-Sektion zu Beginn des Skriptes (kann entfallen),
-
danach eine Actions-Sektion sowie
-
(beliebig viele) Sub-Sektionen.
-
eine ProfileActions Sektion
Initial
- und Actions
-Sektion sind bis auf die Reihenfolge gleichwertig (Initial sollte an erster Stelle stehen). In der Initial Sektion sollten statische Einstellungen und -werte bestimmt werden (wie z.B. der Loglevel). Inzwischen empfehlen wir, die Initial Sektion aus gründen der Übersichtlichkeit weg zulassen. In der Actions-Sektion ist die eigentliche Abfolge der vom Skript gesteuerten Programmaktionen beschrieben ist und kann als Hauptprogramm eines opsi-script Skriptes gesehen werden.
Sub
-Sektionen sind syntaktisch mit der Initial- und der Actions-Sektion vergleichbar, werden aber über die Actions
-Sektion aufgerufen. In ihnen können auch wieder weitere Sub
-Sektionen aufgerufen werden.
Der Name von Sub-Sektionen muss mit 'Sub' beginnen. Der nachfolgende Namensbestandteil kann frei gewählt werden, z.B. Sub_InstallBrowser
. Der Name dient dann (in gleicher Weise wie bei den sekundären Sektionen) als Funktionsaufruf. Der Inhalt der Funktion bestimmt sich durch den Inhalt einer Sektion betitelt mit dem Namen (in unserem Beispiel: [Sub_InstallBrowser]
).
Sub-Sektionen zweiter oder höherer Anforderung (Sub von Sub usw.) können keine weiteren inneren Sektionen beinhalten, aber es können externe Unterprogramme aufgerufen werden (siehe dazu Abschnitt "Aufrufe von Unterprogrammen"). |
Wenn (geschachtelte) Sub-Sektionen in externe Dateien ausgelagert werden, müssen die aufgerufenen Sekundären Sektionen üblicherweise in der Datei untergebracht werden, aus der sie aufgerufen werden. Je nach verwendeter Komplexität des Syntax müssen sie evtl. zusätzlich auch in der Hauptdatei untergebracht werden. |
Die ProfileActions
Sektion kann in einem normalen Installationsskript als Sub-Sektion mit speziellen Syntax Regeln dienen. Existiert diese Sektion in einem Script das als 'userLoginScript' aufgerufen wurde, so ist diese Sektion der Programmstart (statt Actions
). Siehe Kapitel 'User Profile Management' im opsi-manual sowie Kommandos für userLoginScripts / User Profile Management [W]
Parametrisierungsanweisungen für den opsi-script [W/L/M]
Festlegung der Protokollierungstiefe
Die alte Funktion LogLevel= ist ab opsi-script Version 4.10.3 nicht mehr empfohlen, verwenden Sie stattdess SetLogLevel . Um Rückwärtskompatibilität zu alten Skripten zu gewährleisten wird zu dem hiermit gesetzten Loglevel nochmal 4 hinzuaddiert.
|
Es gibt zwei ähnliche Varianten, um den Loglevel zu spezifizieren:
SetLogLevel =
<Zahl>
SetLogLevel =
<STRINGAUSDRUCK>
SetLogLevel definiert die Tiefe der Protokollierung der Operationen. Im ersten Fall kann die Nummer als Integer Wert oder als String-Ausdruck (vgl. String-Werte, String-Ausdrücke und String-Funktionen) angegeben werden. Im zweiten Fall versucht der opsi-script den String-Ausdruck als Nummer auszuwerten.
Es sind zehn Detaillierungsgrade wählbar von 0 bis 9
-
Auf Loglevel 6 wird geloggt:
Alle Programmanweisungen, alle Wertzuweisungen zu Stringvariablen, die Ergebnisse kompletter boolscher Ausdrücke (hinter if) -
Auf Loglevel 7 wird geloggt:
Alle Zuweisungen zu String-Listen-Variablen, die Ausgaben von externen Prozessen, soweit diese nicht einer String-Liste zugewiesen werden, die Ergebnisse der Teilauswertung boolscher Ausdrücke (hinter if) -
Auf Loglevel 8 wird geloggt:
String-Listen, die von Funktionen erzeugt werden, die Ausgaben von externen Prozessen, wenn diese einer String-Liste zugewiesen werden
Der Default ist "7".
siehe auch : opsi-script-configs_default_loglevel
siehe auch : opsi-script-configs_force_min_loglevel
Logdatei im Append-Mode senden
-
forceLogInAppendMode =
<boolean value> //since 4.12.3.6 (default=false);
Wenn true wird eine Logdatei, so sie über den Service an den Server gesendet wird, im Append-Mode gesendet.
Benötigte opsi-script Version [W/L/M]
Die Anweisung
requiredOpsiscriptVersion
<RELATIONSSYMBOL> <ZAHLENSTRING>
seit: 4.12.3.6
z.B.
requiredOpsiscriptVersion >= "4.12.3.6"
lässt den opsi-script überprüfen, ob die geforderte Versionseigenschaften vorliegt. Wenn nicht erscheint ein Fehlerfenster oder ein Fehler wird in das Log geschrieben und das Skript als 'failed' gekennzeichnet..
Es gibt keinen Default.
Eine ältere und noch unterstützte Form lautet (seit 4.3):
requiredWinstVersion
<RELATIONSSYMBOL> <ZAHLENSTRING>
Reaktion auf Fehler [W/L/M]
Zu unterscheiden sind zwei Sorten von Fehlern, die unterschiedlich behandelt werden müssen:
-
fehlerhafte Anweisungen, die der opsi-script nicht "versteht", d.h. deren Interpretation nicht möglich ist (syntaktischer Fehler),
-
aufgrund von "objektiven" Fehlersituationen scheiternde Anweisungen (Ausführungsfehler).
Normalerweise führen syntaktische Fehler neben einem Logeintrag zu einem 'failed' Status des Skript, Ausführungsfehler werden in einer Log-Datei protokolliert und können später analysiert werden.
Das Verhalten des opsi-script bei einem syntaktischen Fehler wird über die Konfiguration bestimmt.
-
ScriptErrorMessages =
<Wahrheitswert>
Wenn der Wert true ist (Default), werden Syntaxfehler bzw. Warnhinweise zum Skriptes als Message-Fenster auf dem Bildschirm angezeigt.
Für <Wahrheitswert> kann außer 'true' bzw. 'false' hier zwecks einer intuitiveren Bezeichnung auch 'on' bzw. 'off' eingesetzt werden.
Default=true
siehe auch: opsi-script-configs_ScriptErrorMessages
-
FatalOnSyntaxError =
<Wahrheitswert>-
'true' = (default) Bei einem Syntaxfehler wird das Script abgebrochen und 'failed' zurückgeliefert. Dem Server wird die Meldung 'Syntax Error' übergeben.
-
'false' = Bei einem Syntaxfehler wird das Script nicht abgebrochen.
Der Syntaxfehler wird in jedem Fall als 'Critical' in die Logdatei übernommen.
In jedem Fall wird der Errorcounter um 1 erhöht.
Seit 4.11.3.2
In älteren Versionen wird weder gelogged noch abgebrochen.
-
-
FatalOnRuntimeError =
<Wahrheitswert>
Ein RuntimeError ist ein Fehler in der Scriptlogik der zu einer verbotenen Operation führt. Ein Beispiel ist von einer String-Liste welche 2 Strings hat den 5. String zu fordern.-
'true' = Bei einem RuntimeError wird das Script abgebrochen und 'failed' zurückgeliefert. Dem Server wird die Meldung 'Runtime Error' übergeben.
-
'false' = (default) Bei einem Syntaxfehler wird das Script nicht abgebrochen. Der RuntimeError wird als 'Error' in die Logdatei übernommen und wird der Errorcounter um 1 erhöht.
Seit 4.11.4.3
-
Die beiden folgenden Einstellungen steuern die Reaktion auf Fehler bei der Ausführung des Skriptes.
-
ExitOnError
= <Wahrheitswert>
Mit dieser Anweisung wird festgelegt, ob bei Auftreten eines Fehlers die Abarbeitung des Skriptes beendet wird. Wenn <Wahrheitswert> 'true' oder 'yes' oder 'on' gesetzt wird, terminiert das Programm, andernfalls werden die Fehler lediglich protokolliert (default). -
TraceMode =
<Wahrheitswert>
Wird TraceMode eingeschaltet (Default ist false), wird jeder Eintrag ins Protokoll zusätzlich in einem Message-Fenster auf dem Bildschirm angezeigt und muss mit einem OK-Schalter bestätigt werden.
Vordergrund (StayOnTop) [W]
-
StayOnTop =
<Wahrheitswert>
Mittels StayOnTop = true (oder = on) kann bestimmt werden, dass im Batchmodus das opsi-script Fenster den Vordergrund des Bildschirms in Beschlag nimmt, sofern kein anderer Task den selben Status beansprucht. Im Dialogmodus hat der Wert der Variable keine Bedeutung.
Nach Programmiersystem-Handbuch soll der Wert nicht im laufenden Betrieb geändert werden. Zur Zeit sieht es so aus, als wäre ein einmaliges (Neu-) Setzen des Wertes möglich, ein Rücksetzen auf den vorherigen Wert während des Programmlaufs dann aber nicht mehr. |
StayOnTop
steht per Default auf false damit verhindert wird das Fehlermeldungen eventuell nicht sichtbar sind, weil der opsi-script im Vordergrund läuft.
Fenster Modus / Skin / Aktivitätsanzeige
-
SetSkinDirectory
<skindir> // [W/L/M]
Setzt das zu verwendende SkinDirectory und lädt den Skin. Wird bei diesem Befehl ein leerer oder ungültiger Pfad angegeben, so wird der Defaultpfad verwendet.
Der Defaultpfad ist%OpsiScriptDir%\skin
.
Beispiel:
SetSkinDirectory "%ScriptPath%\testskin"
sleepseconds 1
SetSkinDirectory ""
siehe auch: Skinnable opsi-script
-
NormalizeWinst
setzt das opsi-script Fenster auf 'normal' Modus.
-
IconizeWinst
setzt das opsi-script Fenster auf 'minimierten' Modus.
-
MaximizeWinst
setzt das opsi-script Fenster auf 'maximierten' Modus. // since 4.11.5.1
-
RestoreWinst
setzt das opsi-script Fenster auf den letzten Modus.
-
AutoActivityDisplay =
<boolean value> //since 4.11.4.7
(default=false);
Wenn true wird während des Laufs von externen Prozessen (winbatch,ShellScript,execwith Sektionen) ein (marquee) Fortschrittsbalken (der Endlos durch läuft) angezeigt.
siehe auch: opsi-script-configs_AutoActivityDisplay
Neueinlesen der Produktliste [W/L/M]
-
reloadProductList
//since 4.12.6.1
Lädt die Produktliste vom opsi-Server nach Durchführung des Skriptes in opsi-script neu ein. Ist die Produktliste nicht leer, wird sie erneut vom opsi-script abgearbeitet.reloadProductList
kann überall in der Actions-Sektion des Skriptes stehen. Die Empfehlung ist aber, der Logik entsprechend, den Befehl ans Ende der Sektion zu setzen.
String-Werte, String-Ausdrücke und String-Funktionen [W/L/M]
Ein String-Ausdruck kann
-
ein elementarer String-Wert
-
ein verschachtelter String-Wert
-
eine String-Variable
-
eine Verknüpfung von String-Ausdrücken oder
-
ein stringbasierter Funktionsaufruf sein.
Elementare String-Werte
Ein elementarer String-Wert ist jede Zeichenfolge, die von doppelten – " – oder von einfachen – ' – Anführungszeichen umrahmt ist:
'"<Zeichenfolge>"'
oder
''<Zeichenfolge>''
Zum Beispiel:
DefVar $BeispielString$
Set $BeispielString$ = "mein Text"
Strings in Strings (geschachtelte String-Werte)
Wenn in der Zeichenfolge Anführungszeichen vorkommen, muss zur Umrahmung die andere Variante des Anführungszeichens verwendet werden.
DefVar $citation$
Set $citation$ = 'he said "Yes"'
Zeichenfolgen, innerhalb derer möglicherweise bereits Schachtelungen von Anführungszeichen vorkommen, können mit
EscapeString:
<Abfolge von Buchstaben>
gesetzt werden. Z.B. bedeutet
DefVar $Meta_citation$
Set $Meta_citation$ = EscapeString: Set $citation$ = 'he said "Yes"'
dass auf der Variablen $Meta_citation$
am Ende exakt die Folge der Zeichen nach dem Doppelpunkt von EscapeString (inklusive des führenden Leerzeichens) steht, also
Set $citation$ = 'he said "Yes"'
String-Verknüpfung
Strings können mit dem Pluszeichen ("+") verknüpft werden.
<String expression> +
<String expression>
Beispiel:
DefVar $String1$
DefVar $String2$
DefVar $String3$
DefVar $String4$
Set $String1$ = "Mein Text"
Set $String2$ = "und"
Set $String3$ = "dein Text"
Set $String4$ = $String1$ + " " + $String2$ + " " + $String3$
$String4$
hat dann den Wert "Mein Text und dein Text".
String-Ausdrücke
Eine String-Variable der primären Sektion "beinhaltet" einen String-Wert. Ein String-Ausdruck kann einen elementaren String vertreten. Wie ein String gesetzt und definiert wird findet sich in Abschnitt String- (oder Text-) Variable.
Die folgenden Abschnitte zeigen die Variationsmöglichkeiten von String-Funktionen.
String-Funktionen (Betriebssystem ermitteln)
-
GetOS
[W/L/M]
Die Funktion ermittelt das laufende Betriebssystem. Derzeit liefert sie einen der folgenden Werte:-
"Windows_NT" (bei Windows NT - Windows 10)
-
"Linux"
-
"macOS"
-
-
GetNtVersion
[W]
(abgekündigt: use GetMSVersionInfo)
Für ein Betriebssystem mit Windows_NT ist eine Type-Nummer und eine Sub Type-Nummer charakteristisch. GetNtVersion gibt den genauen Sub Type-Namen aus. Mögliche Werte sind
"NT3"
"NT4"
"Win2k" (Windows 5.0)
"WinXP" (Windows 5.1)
"Windows Vista" (Windows 6)
Bei höheren (als 6.*) Windows-Versionen werden die Versionsnummern (5.2, … bzw. 6.0 ..) ausgegeben. Z.B. für Windows Server 2003 R2 Enterprise Edition erhält man
"Win NT 5.2" (Windows Server 2003)
In dem Fall, dass kein NT-Betriebssystem vorliegt, liefert die Funktion als Fehler-Wert:
"Kein OS vom Typ Windows NT"
-
GetMsVersionInfo
[W]
gibt für Windows Systeme die Information über die interne Version aus, z.B. produziert ein Windows 7 System das Ergebnis: "6.1". Window 11 liefert "10.0"
siehe daher auchGetMsVersionName
GetMsVersionInfo | Windows-Version |
---|---|
5.0 |
Windows 2000 |
5.1 |
Windows XP (Home, Prof) |
5.2 |
XP 64 Bit, 2003, Home Server, 2003 R2 |
6.0 |
Vista, 2008 |
6.1 |
Windows 7, 2008 R2 |
6.2 |
Windows 8, 2012 |
6.3 |
Windows 8.1, 2012 R2 |
10.0 |
Windows 10, Windows 11, 2016, 2019, 2022 |
siehe auch GetMSVersionMap
-
GetMsVersionName
[W] // since 4.12.4.35
gibt für Windows Systeme die Information über die marketing Version aus, z.B. produziert ein Windows 7 System das Ergebnis: "7.0". Window 11 liefert "11.0".
GetMsVersionName | Windows Version |
---|---|
5.0 |
Windows 2000 |
5.1 |
Windows XP (Home, Prof) |
5.2 |
XP 64 Bit, 2003, Home Server, 2003 R2 |
6.0 |
Vista, 2008 |
7.0 |
Windows 7, 2008 R2 |
8.0 |
Windows 8, 2012 |
8.1 |
Windows 8.1, 2012 R2 |
10.0 |
Windows 10, 2016, 2019 |
11.0 |
Windows 11, 2022 |
siehe auch GetMSVersionMap
siehe auch GetMsVersionInfo
-
getLinuxDistroType
[L]
liefert den Typ der laufenden Linuxdistribution. Mögliche Werte:-
'debian' (Debian / Ubuntu → use apt-get)
-
'redhat' (RedHat / CentOs → use yum)
-
'suse' (→ use zypper) (siehe auch
getLinuxVersionMap
)
-
-
getMacosVersionInfo : string
//macOS Version Information //since 4.12.1.0 [M]
siehe auch:getMacosVersionMap
-
GetSystemType
[W/L/M]
prüft die Architektur des installierten Betriebssystems. Im Fall eines 64 Bit-Betriebssystems ist der ausgegebene Wert '64 Bit System' ansonsten ist der Rückgabewert 'x86 System'.
-
getOSArchitecture
// OS Architecture //since 4.12.4.17 prüft die Prozessor Architektur des installierten Betriebssystems. Mögliche Werte sind:-
x86_32
(Intel / AMD X86 Architecture with 32 Bit) -
x86_64
(Intel / AMD X86 Architecture with 64 Bit) -
arm_64
(ARM Architecture with 64 Bit e.g Apple M1)
-
String-Funktionen zur Ermittlung von Umgebungs- und Aufrufparametern [W/L/M]
-
EnvVar (
<string>`)` [W/L/M]
Die Funktion liefert den aktuellen Wert einer Umgebungsvariablen. Z.B. wird durch EnvVar ("Username") der Name des eingeloggten Users ermittelt.
-
ParamStr
[W/L/M]
Die Funktion gibt den String aus, der im Aufruf von opsi-script nach dem optionalen Kommandozeilenparameter /parameter folgt. Ist der Kommandozeilenparameter nicht verwendet, liefert ParamStr den leeren String.
-
getLastExitCode
[W/L/M]
Die String-Funktion getLastExitCode gibt den ExitCode des letzten Prozessaufrufs der vorausgehenden 'WinBatch' / 'ShellScript' / 'ExecWith' Sektion aus.
Der Aufruf anderer opsi-script Befehle ( wie z.B. einer 'Files' Sektion) verändert den gefundenen ExitCode nicht.
Bei 'ShellScript' und 'ExecWith' Sektionen erhalten wir den Exitcode des Interpreters. Daher muss in der Regel der gewünschte Exitcode in der Sektion explizit übergeben werden.
Beispiel:
ShellScript_exit1
set $ConstTest$ = "1"
set $CompValue$ = getLastExitCode
if ($ConstTest$ = $CompValue$)
comment "ShellScript / ShellScript exitcode passed"
else
set $TestResult$ = "not o.k."
LogWarning "ShellScript / ShellScript exitcode failed"
endif
[ShellScript_exit1]
rem create an errolevel= 1
VERIFY OTHER 2> NUL
echo %ERRORLEVEL%
exit %ERRORLEVEL%
-
GetUserSID(
<Windows Username>`)` [W]
gibt die SID für den übergebenen Benutzer an (möglich mit der Domäne als Vorspann in Form von DOMAIN\USER).
-
GetUsercontext
[W]
Die Funktion gibt den String aus, der im Aufruf von opsi-script nach dem optionalen Kommandozeilenparameter /usercontext folgt. Ist der Kommandozeilenparameter nicht verwendet, liefertGetUsercontext
den leeren String.
Werte aus der Windows-Registry lesen und für sie aufbereiten [W]
-
getRegistryValue (
<keystr>, <varstr>)
: string //since 4.12.0.16 [W]
versucht in der Registry den als <keystr> übergebenen String-Wert als Registrykey zu öffnen und dort den Wert <varstr> zu lesen und als String zurückzugeben.
Wenn <keystr> bzw. die Variable <varstr> nicht existieren, wird eine Warnung in das Logfile geschrieben und der Leerstring als Defaultwert zurückgegeben.
Wenn der übergebene <varstr> leer ist, so wird der Standardwert des Keys ausgelesen.
Die Zugriffsart ist per Defaultsysnative
. Über den optionalen dritten Parameter kann die Zugriffsart auch explizit angegeben werden. Dabei muss der übergebene <access str> einer der folgenden Werte sein:32bit
,sysnative
,64bit
.
(siehe auch: Kapitel 64 Bit-Unterstützung)
Beispiele:
getRegistryValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", "Shell")
getRegistryValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", "Shell","64bit")
-
GetRegistryStringValue (
<string>`)`
Die Verwendung ist nicht mehr empfohlen, bitte stattdessengetRegistryValue
verwenden : [getRegistryValue]
versucht den übergebenen String-Wert als einen Ausdruck der Form
'[KEY] X'
zu interpretieren; im Erfolgsfall liest die Funktion den (String-) Wert zum Variablennamen 'X' des Schlüssels 'KEY' der Registry aus. Wird 'X' nicht übergeben so wird der Standardwert des Keys ausgelesen.
Wenn KEY bzw. die Variable X nicht existieren, wird eine Warnung in das Logfile geschrieben und der Leerstring als Defaultwert zurückgegeben.
Zum Beispiel ist
GetRegistryStringValue ("[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon] Shell")
üblicherweise "Explorer.exe", das default Windows Shell Programm (aber es könnten auch andere Programme als Shell eingetragen sein.)
Zum Beispiel liefert
Set $CompValue$ = GetRegistryStringValue32 ("[HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\opsi-script-test\test-4.0]")
wenn der Key vorher mit dem Standardeintrag 'standard entry' erzeugt wurde, den folgenden Logeintrag:
Registry started with redirection (32 Bit)
Registry key [HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\opsi-script-test\test-4.0] opened
Key closed
The value of the variable "$CompValue$" is now: "standard entry"
-
GetRegistryStringValue32(
<string>`)` → siehe Kapitel 64 Bit-Unterstützung
siehe auch :getRegistryValue
-
GetRegistryStringValue64(
<string>`)` → siehe Kapitel 64 Bit-Unterstützung
siehe auch :getRegistryValue
-
GetRegistryStringValueSysNative(
<string>`)` → siehe Kapitel 64 Bit-Unterstützung
siehe auch :getRegistryValue
-
RegString(
<string>`)`
wird vor allem benötigt, um Dateinamen in die Form zu wandeln, in der sie in die Registry eingetragen werden, das heißt, jeder Backslash des Arguments der Funktion wird verdoppelt. Z.B. liefert
RegString ("c:\windows\system\")
den Wert
'"c:\\windows\\system\\"'
-
which(
<command string>`) : string` //since 4.12.3.6 [W/L/M]
Liefert den vollständigen Pfad zum Befehl <command string>, wenn dieser Befehl im gesetzten Suchpfad liegt.
Analog dem Unix Befehl 'which'.
Werte aus Ini-Dateien lesen [W/L/M]
Es gibt – aus historischen Gründen – zwei Funktionen, um Werte aus Ini-Dateien zu lesen.
Als Ini-Datei wird dabei jede in "Sektionen" gegliederte Textdatei der Form
[Sektion1]
Varname1=Wert1
Varname2=Wert2
...
[Sektion2]
...
bezeichnet.
Die allgemeinste Funktion liest den Key-Wert aus einer Sektion der ini-Datei aus. Jeder Parameter kann als ein willkürlicher String-Ausdruck ausgegeben werden:
-
GetValueFromInifile (
<file path>, <section>, <key>, <default value>, OPTIONAL <encoding>`)` : string [W/L/M]
Die Funktion öffnet die Ini-Datei <file path> und sucht in deren Sektion <section> den <key> (auch 'Variable' genannt). Wenn diese Operation erfolgreich ist, wird der zum key gehörende Wert zurückgegeben, andernfalls <default value>.
Ab opsi-script 4.12.6.0 unterstütztGetValueFromInifile
einen fünften, optionalen Parameter <encoding>, der dabei hilft, die Ini-Datei in der richtigen Kodierung einzulesen. Wir empfehlen die Verwendung im Falle von speziellen Codierungen.
GetValueFromInifile("myfile","mysec","mykey","")
GetValueFromInifile("myfile","mysec","mykey","", "utf16-le")
-
GetIni (
<Stringausdruck> [ <character sequence> ] <character sequence>)
(abgekündigt, bitte verwenden: GetValueFromInifile)
Diese Funktion unterstützt eine Schreibweise, die sehr eng an die Schreibweise der Ini-Datei selbst angelehnt ist. Dabei kann allerdings nur der Dateiname durch einen String-Ausdruck dargestellt werden, die anderen Größen müssen explizit angegeben sein:
Der <Stringausdruck> wird als Dateiname ausgelesen, der Erste <character sequence> als Sektionsname, der Zweite als Schlüsselname.
'GetIni("MEINEINIDATEI"[meinesektion] meinkey)'
gibt diese selben Werte zurück wie
'GetValueFromInifile("MEINEINIDATEI","meinesektion","meinkey","")'
Produkt Properties auslesen [W/L/M]
-
GetProductProperty (
<PropertyName>, <DefaultValue>`)` [W/L/M]
wobei <PropertyName> und <DefaultValue> String-Ausdrücke sind. Die Funktion liefert die client-spezifischen Property-Werte für das aktuell installierte Produkt aus.
Dabei werden die aktuellen Werte beim opsi-server abgefragt.
Kann der aktuelle Wert des Properies nicht vom opsi-server ermittelt werden (z.B. weil das Skript nicht im Kontext des opsi-service läuft), so wird der zurückzugebende Wert wie folgt ermittelt:
Seit 4.12.4.32 wird zunächst geprüft ob sich im%ScriptPath%
eine Dateiproperties.conf
befindet. Wenn ja, wird versucht aus dieser Datei den Wert des Properties zu lesen. Dabei wird die Dateiproperties.conf
als Liste von key=value Paaren erwartet. Im Falle eines Strings wird hier ein Eintrag vom Muster<property name>=<string value>
erwartet. Beispiel:myproperty=myentry
.
Wird die Dateiproperties.conf
nicht gefunden oder enthält den gesuchten Eintrag nicht, so wird der<default value>
zurückgegeben.
Auf diese Weise können PC-spezifische Varianten einer Installation konfiguriert werden.
Außerhalb des opsi-service Kontextes oder wenn aus anderen Gründen der Aufruf fehlschlägt, wird der angegebene Defaultwert zurückgegeben.
Auf diese Weise können PC-spezifische Varianten einer Installation konfiguriert werden.
So wurde beispielsweise die opsi UltraVNC Netzwerk Viewer Installation mit folgenden Produkt Properties konfiguriert:
-
viewer = <yes> | <no>
-
policy = <factory_default> |
Innerhalb des Installationsskript werden die ausgewählten Werte wie folgt abgerufen
GetProductProperty("viewer", "yes")
GetProductProperty("policy", "factory_default")
Ab 4.12.4.32 ist bei Existenz der folgenden %ScriptPath%\properties.conf
Datei:
propstr = from file proplist = ["from file",huhu"]
das folgende Skript ausserhalb des opsi-service Kontextes erfolgreich:
[Actions]
DefStringList $list$
DefVar $str$
set $str$ = GetProductProperty('propstr','')
if $str$ = "from file"
comment "got it"
else
comment "failed"
endif
set $list$ = GetProductPropertyList('proplist','')
if takeString(0,$list$) = "from file"
comment "got it"
else
comment "failed"
endif
-
GetConfidentialProductProperty (
<PropertyName>, <DefaultValue>`)` //since 4.11.5.2
verhält sich wieGetProductProperty
nur das der resultierende Wert als confidential string behandelt und damit nicht gelogged wird.
Sinnvoll um z.B. Passwörter aus einem Produktproperty abzufragen. Siehe auch:SetConfidential
Siehe auch: asConfidential (string)
Siehe auch: asConfidential (list) -
IniVar(
<PropertyName>`)`
(abgekündigt: use GetProductProperty)
Informationen aus etc/hosts entnehmen [W/L/M]
-
GetHostsName(
<string>`)` [W/L/M]
liefert den Host-Namen zu einer gegebenen IP-Adresse entsprechend den Angaben in der Host-Datei (die, falls das Betriebssystem laut Environment-Variable OS "Windows_NT" ist, im Verzeichnis "%systemroot%\system32\drivers\etc\" gesucht wird, andernfalls in "C:\Windows\").
-
GetHostsAddr(
<string>`)` [W/L/M]
liefet die IP-Adresse zu einem gegebenen Host- bzw. Aliasnamen entsprechend der Auflösung in der Host-Datei.
String-Verarbeitung [W/L/M]
-
ExtractFilePath(
<string>`)` [W/L/M]
interpretiert den übergebenen String als Datei- bzw. Pfadnamen und gibt den Pfadanteil (den String-Wert bis einschließlich des letzten “\“ zurück).
Examples:
set $ConstTest$ = "C:\program files\test\"
Set $tmp$ = "C:\program files\test\test.exe"
set $CompValue$ = ExtractFilePath($tmp$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
-
ExtractFileExtension (
<path>`) : string` //since 4.12.1 [W/L/M]
interpretiert den übergebenen String als Datei- bzw. Pfadnamen und gibt vom Dateianteil die Extension zurück. (den String-Wert nach dem letzten “.“, mit dem Punkt).
Examples:
set $ConstTest$ = ".exe"
Set $tmp$ = "C:\program files\test\test.exe"
set $CompValue$ = ExtractFileExtension($tmp$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
-
ExtractFileName (
<path>`) : string` //since 4.12.1 [W/L/M]
interpretiert den übergebenen String als Datei- bzw. Pfadnamen und gibt den Dateianteil zurück. (den String-Wert nach dem letzten Pfadtrenner, ohne diesen).
Examples:
set $ConstTest$ = "test.exe"
Set $tmp$ = "C:\program files\test\test.exe"
set $CompValue$ = ExtractFileName($tmp$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
-
forcePathDelims (
<path string>`) : <path string>` // since 4.12.4.21 [W/L/M]
interpretiert den übergebenen String als Pfadnamen und setzt alle Pfadtrenner auf den für das laufende Betriebssystem typische Zeichen (Windows: '\', Linux und macOS: '/').
-
resolveSymlink (
<file name>`) : <file name>` // since 4.12.4.21 [W/L/M]
Ist die angegebene Datei <file name> ein symbolischer Link, so wird (rekursiv) ermittelt auf welche Datei dieser zeigt und das Ergenis zurückgegeben. Ansonsten wird der übergebene <file name> zurückgegeben.
-
StringSplit (`STRINGWERT1, STRINGWERT2, INDEX
)`
(abgekündigt: usesplitString
/takestring
)
siehe auch: splitString
siehe auch: takeString
-
takeString(
<index>,<list>`)` [W/L/M]
liefert aus der String-Liste <list> den String mit dem Index <index>.
Häufig verwendet in Kombination mit splitString :takeString(
<index>,splitString(
<string1>, <string2>`)`
(String-Listenverarbeitung).
Das Ergebnis ist, dass <string1> in Stücke zerlegt wird, die jeweils durch <string2> begrenzt sind, und das Stück mit <index> (Zählung bei 0 beginnend) genommen wird.
Zum Beispiel ergibt
takeString(3, splitString ("\\server\share\directory", "\"))
den Wert '"share"',
denn mit '\' zerlegt sich der vorgegebene String Wert in die Folge:
Index 0 - "" (Leerstring), weil vor dem ersten "\" nichts steht
Index 1 - "" (Leerstring), weil zwischen erstem und zweitem "\" nichts steht
Index 2 - "server"
Index 3 - "share"
Index 4 - "directory"
takestring
zählt abwärts, wenn der Index negativ ist, beginnend mit der Zahl der Elemente.
Deswegen bedeutet
takestring(-1, $list1$)
das letzte Element der String-Liste $list1$.
siehe auch: setStringInListAtIndex
-
SubstringBefore(
<string1>, <string2>`)`
(abgekündigt: use splitString / takestring) liefert das Anfangsstück von <string1>, wenn <string2> das Endstück ist. Z.B. hat
SubstringBefore ("C:\programme\staroffice\program\soffice.exe", "\program\soffice.exe")
den Wert '"C:\programme\staroffice"'.
-
getIndexFromListByContaining
(<list> : stringlist,<search string> : string`)` : <number> : string //since 4.12.0.13 [W/L/M]
Liefert den Index (als String) von dem ersten String in <list> in dem <search string> vorkommt. Wird <search string> nicht gefunden so wird ein Leerstring geliefert.
Die Überprüfung auf Gleichheit ist nicht Case Sensitive.
see also : [takeFirstStringContaining]
-
takeFirstStringContaining(
<list>,<search string>`)` [W/L/M]
Liefert den ersten String einer Liste der <search string> enthält. Liefert einen leeren String, wenn kein passender String gefunden wird.
see also : [getIndexFromListByContaining]
-
Trim(
<string>`)` [W/L/M]
Schneidet Leerzeichen am Anfang und Ende des <string> ab.
-
lower(
<string>`)` [W/L/M]
liefert <string> in Kleinbuchstaben
-
upper(
<string>`)` [W/L/M]
liefert <string> in Großbuchstaben
-
contains(
<str>, <substr>`)` [W/L/M]
Boolsche Funktion welche 'true' liefert wenn <substr> in <str> enthalten ist. Die Funktion arbeitet case sensitive.
Seit 4.11.3
Beispiel:
set $ConstTest$ = "1xy451Xy451XY45" set $CompValue$ ="xy" if contains($ConstTest$, $CompValue$) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif set $CompValue$ ="xY" if not(contains($ConstTest$, $CompValue$)) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif
-
stringReplace(
<string>, <oldPattern>, <newPattern>`)` [W/L/M]
Liefert einen String in dem in <string>, <oldPattern> durch <newPattern> ersetzt ist. Die Funktion arbeitet nicht case sensitive. Die Funktion ersetzt alle Vorkommen von <oldPattern>.
Seit 4.11.3
Beispiel:
set $ConstTest$ = "123451234512345" set $CompValue$ = stringReplace("1xy451Xy451XY45","xy","23") if ($ConstTest$ = $CompValue$) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif
-
strLength(
<string>`)` [W/L/M]
Liefert Anzahl der Zeichen in <string>
Seit 4.11.3
Beispiel:
set $tmp$ = "123456789" set $ConstTest$ = "9" set $CompValue$ = strLength($tmp$) if $ConstTest$ = $CompValue$ comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif
-
strPos(
<string>, <sub string>`)` [W/L/M]
Liefert die Position des ersten Vorkommens von <sub string> in <string>. Wird <sub string> nicht gefunden so liefert die Funktion "0". Die Funktion arbeitet case sensitive.
Seit 4.11.3
Beispiel:
set $tmp$ = "1xY451Xy451xy45" set $ConstTest$ = "7" set $CompValue$ = strPos($tmp$,"Xy") if $ConstTest$ = $CompValue$ comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif set $tmp$ = lower("1xY451Xy451xy45") set $ConstTest$ = "2" set $CompValue$ = strPos($tmp$,lower("xy")) if $ConstTest$ = $CompValue$ comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif
-
strPart(
<string>, <start pos>, <number of chars>`)` [W/L/M]
Liefert einen Teilstring von <string> beginnend mit <start pos> und <number of chars> lang. Wenn ab <str pos> weniger als <number of chars> vorhanden sind, so wird der String bis zum Ende geliefert.
Die Zählung der Zeichen beginnt mit 1.
Seit 4.11.3
Beispiel:
set $tmp$ = "123456789" set $ConstTest$ = "34" set $CompValue$ = strPart($tmp$,"3","2") if $ConstTest$ = $CompValue$ comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif set $tmp$ = "123456789" set $ConstTest$ = "56789" set $CompValue$ = strPart($tmp$, strPos($tmp$,"56"),strLength($tmp$)) if $ConstTest$ = $CompValue$ comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif
-
unquote(
<string>,<quote-string>`)` [W/L/M]
Wenn <string> mit dem Anführungszeichen <quote-string> versehen ist so liefert diese Funktion <string> ohne Anführungszeichen
Von <quote-string> wird nur das erste Zeichen berücksichtigt, wobei führende Whitespaces ignoriert werden.
Seit 4.11.2.1
see also : [unquote2]
set $ConstTest$ = "b" set $CompValue$ = unquote("'b'", "'") comment "compare values" if ($ConstTest$ = $CompValue$) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif comment "double quote" set $ConstTest$ = "b" set $CompValue$ = unquote('"b"', '"') comment "compare values" if ($ConstTest$ = $CompValue$) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif comment "quote string will be trimmed and then only the first char is used" comment "note: brackets are different chars" set $ConstTest$ = "b]" set $CompValue$ = unquote("[b]", " [{ ") comment "compare values" if ($ConstTest$ = $CompValue$) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif comment "not usable to remove brackets" set $ConstTest$ = "b]" set $CompValue$ = unquote("[b]", "[") set $CompValue$ = unquote($CompValue$,"]") set $CompValue$ = unquote("[b]", "]") set $CompValue$ = unquote($CompValue$,"[") set $CompValue$ = unquote(unquote("[b]", "["),"]") comment "compare values" if ($ConstTest$ = $CompValue$) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif comment "if string not quoted it will be come back without changes" set $ConstTest$ = "b" set $CompValue$ = unquote("b", "'") comment "compare values" if ($ConstTest$ = $CompValue$) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif
unquote2(<string>,<quote-string>)
// since 4.11.5.2 [W/L/M]
Funktioniert wie unquote(<string>,<quote-string>)
mit folgenden Unterschieden:
Wenn <quote-string> ein Zeichen lang ist, wird diese Zeichen als erwartetes 'Quote Zeichen' für den Anfang und das Ende von <string> genommen. Wenn <quote-string> zwei Zeichen lang ist, wird das erste Zeichen als erwartetes 'Quote Zeichen' für den Anfang und das zweite Zeichen als erwartetes 'Quote Zeichen' für den Ende von <string> genommen. Beispiel: "()"
Die Funktion liefert <string> unverändert zurück, wenn nicht sowohl für Anfang und Ende die erwarteten 'Quote Zeichen' gefunden werden.
see also : [unquote]
-
HexStrToDecStr(
<string>`)` [W/L/M]
wandelt einen String mit einem hexadezimalen Zahlwert in einen String mit dem entsprechenden decimalen Wert um. Enthält der Eingabe String führende Zeichen wie '0x' oder '$' werden diese ignoriert.
Im Fehlerfall: Leerstring
-
DecStrToHexStr (
<decstring>, <hexlength>`)` [W/L/M]
liefert einen <hexlength> langen String mit der hexadezimalen Darstellung von <decstring> zurück, wenn dieser die dezimale Darstellung eines Intergerwertes war. Im Fehlerfall: Leerstring
message "DecStrToHexStr"
set $ConstTest$ = "0407"
set $tmp$ = "1031"
set $CompValue$ = DecStrToHexStr($tmp$,"4")
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
message "DecStrToHexStr"
set $ConstTest$ = "407"
set $tmp$ = "1031"
set $CompValue$ = DecStrToHexStr($tmp$,"2")
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
-
base64EncodeStr(
<string>`)` [W/L/M]
liefert einen String mit dem base64 encodedten Wert von <string>.
-
base64DecodeStr(
<string>`)` [W/L/M]
liefert einen String mit dem base64 decodedten Wert von <string>.
message "base64EncodeStr"
set $ConstTest$ = "YWJjZGVm"
set $tmp$ = "abcdef"
set $CompValue$ = base64EncodeStr($tmp$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
comment ""
comment "------------------------------"
comment "Testing: "
message "base64DecodeStr"
set $ConstTest$ = "abcdef"
set $tmp$ = "YWJjZGVm"
set $CompValue$ = base64DecodeStr($tmp$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
-
encryptStringBlow(
<keystring>,<datastring>`) : string` //since 4.11.6 [W/L/M]
Verschlüsselt <datastring> mit dem Key <keystring> unter Verwendung von Blowfish und liefert den verschlüsselten Wert zurück.
-
decryptStringBlow(
<keystring>,<datastring>`) : string` //since 4.11.6 [W/L/M]
Entschlüsselt <datastring> mit dem Key <keystring> unter Verwendung von Blowfish und liefert den entschlüsselten Wert zurück.
set $ConstTest$ = "This string is very secret"
set $ConstTest$ = encryptStringBlow("linux123",$ConstTest$)
set $ConstTest$ = decryptStringBlow("linux123",$ConstTest$)
set $CompValue$ = "This string is very secret"
if ($ConstTest$ = $CompValue$)
comment "cryptStringBlow passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing cryptStringBlow failed"
endif
-
md5sumFromFile(
<path to file>`) : string` //since 4.11.6 [W/L/M]
Liefert die md5summe der unter <path to file> gefundenen Datei zurück.
Im Fehlerfall ist der Rückgabewert ein Leerstring.
set $ConstTest$ = md5sumFromFile("%ScriptPath%\test-files\crypt\dummy.msi")
set $CompValue$ = strLoadTextFile("%ScriptPath%\test-files\crypt\dummy.msi.md5")
if ($ConstTest$ = $CompValue$)
comment "md5sumFromFile passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing md5sumFromFile failed"
endif
-
hashFromFile (
<FileName>, <Hashing Algorithm>`)` : string [W/L/M]
Dies ist eine plattformunabhängige Hashing-Dateifunktion, die 80 Hashing-Algorithmen unterstützt.
Folgende Werte können für <Hashing Algorithm> verwendet werden: 'Gost', 'Grindahl256', 'Grindahl512', 'HAS160', 'Haval_3_128', 'Haval_4_128', 'Haval_5_128', 'Haval_3_160', 'Haval_4_160', 'Haval_5_160', 'Haval_3_192', 'Haval_4_192', 'Haval_5_192', 'Haval_3_224', 'Haval_4_224', 'Haval_5_224', 'Haval_3_256', 'Haval_4_256', 'Haval_5_256', 'MD2', 'MD4', 'MD5', 'Panama', 'RadioGatun32', 'RadioGatun64', 'RIPEMD', 'RIPEMD128', 'RIPEMD160', 'RIPEMD256', 'RIPEMD320', 'SHA0', 'SHA1', 'SHA2_244', 'SHA2_256', 'SHA2_384', 'SHA2_512', 'SHA2_512_224', 'SHA2_512_256', 'SHA3_224', 'SHA3_256', 'SHA3_384', 'SHA3_512', 'Shake_128', 'Shake_256', 'Snefru_8_128', 'Snefru_8_256', 'Tiger_3_128', 'Tiger_4_128', 'Tiger_5_128', 'Tiger_3_160', 'Tiger_4_160', 'Tiger_5_160', 'Tiger_3_192', 'Tiger_4_192', 'Tiger_5_192', 'Tiger2_3_128', 'Tiger2_4_128', 'Tiger2_5_128', 'Tiger2_3_160', 'Tiger2_4_160', 'Tiger2_5_160', 'Tiger2_3_192', 'Tiger2_4_192', 'Tiger2_5_192', 'WhirlPool', 'Blake2B', 'Blake2S', 'Keccak_224', 'Keccak_256', 'Keccak_288', 'Keccak_384', 'Keccak_512', 'GOST3411_2012_256', 'GOST3411_2012_512', 'Blake2XS', 'Blake2XB', 'Blake3_256', 'Blake3XOF', 'Blake2BP', 'Blake2SP'
encoding=utf8
[Actions]
DefVar $OS$
DefVar $FilePath$
DefVar $HashResult$
DefVar $CompValue$
; This online tool can be used to double check hash results : https://emn178.github.io/online-tools/
Set $OS$ = GetOS
switch $OS$
case "Windows_nt"
comment "We are running on Windows"
Set $FilePath$ = "C:\opsi\crypt\dummy.msi"
endcase
case "Linux"
comment "We are running on Linux"
Set $FilePath$ = "/home/opsi/crypt/dummy.msi"
endcase
case "macos"
comment "We are running on macOS"
Set $FilePath$ = "/home/opsi/crypt/dummy.msi"
endcase
endswitch
if FileExists($FilePath$)
comment "Testing HashFromFile - MD5"
Set $HashResult$ = HashFromFile($FilePath$, "MD5")
Set $CompValue$ = md5sumFromFile($FilePath$)
if ($HashResult$ = $CompValue$)
comment "Testing HashFromFile - MD5 passed"
else
LogWarning "Testing HashFromFile - MD5 failed"
endif
else
LogWarning "File not found"
endif
-
reencodestr(
<str>, <from>, <to>`)` //since 4.11.4.2 [W/L/M]
liefert den String <str> mit dem encoding <to> zurück wobei davon ausgegangen wird das <str> gemäß <from> encoded war. <from> und <to> sind dabei encodings wie sie im Kapitel opsi-script encoding aufgelistet sind.
see also: [reencodestrlist] siehe auch : [loadTextFile]
siehe auch : [strLoadTextFileWithEncoding]
siehe auch : [loadUnicodeTextFile]
siehe auch : [loadTextFileWithEncoding]
see also: Encoding related functions
-
strLoadTextFile (
<filename>)
//since 4.11.4.6 [W/L/M]
liefert die erste Zeile von <filename> als String.
siehe auch : [strLoadTextFileWithEncoding]
-
strLoadTextFileWithEncoding (
<filename> , <encoding>`) : string` [W/L/M]
liefert die erste Zeile von <filename> als String reencoded von <encoding>.
siehe auch : [loadTextFile]
siehe auch : [strLoadTextFile]
siehe auch : [loadUnicodeTextFile]
siehe auch : [loadTextFileWithEncoding]
siehe auch : opsi-script encoding
-
GetShortWinPathName(<longpath string>)
//since 4.11.5.2 [W]
Liefert den Shortpath (8.3) von <longpath string>. Lässt sich für <longpath string> kein Shortpath finden, so liefert die Funktion einen leeren String. + Beispiel:GetShortWinPathName("C:\Program Files (x86)")
liefert"C:\PROGRA~2"
Weitere String-Funktionen
-
RandomStr
[W/L/M]
liefert Zufallsstrings (der Länge 10), die aus Klein- und Großbuchstaben sowie Ziffern bestehen. Genauer: 2 Kleinbuchstaben, 2 Großbuchstaben, 2 Sonderzeichen und 4 Ziffern. Die möglichen Sonderzeichen sind:
'!','$','(',')','*','+','/',';','=','?','[',']','{','}','ß','~','§','°'
-
RandomStrWithParameters (<minLength>, <nLowerCases>, <nUpperCases>,<nDigits>,<nSpecialChars>): string
[W/L/M]
liefert Zufallsstring (z.B. um Passwörter zu generieren), dessen Eigenschaften sich durch die mitgegebenen Paramter wie folgt konfigurieren lässt:-
<minLength>: Länge des Strings,
-
<nLowerCases>: Anzahl der Kleinbuchstaben,
-
<nUpperCases>: Anzahl der Großbuchstaben,
-
<nDigits>: Anzahl der Ziffern,
-
<nSpecialChars>: Anzahl der Sonderzeichen.
Mögliche Sonderzeichen sind: '!','$','(',')','*','+','/',';','=','?','[',']','{','}','ß','~','§','°'
-
-
RandomIntStr(<number str>) : string
[W/L/M]
liefert eine zufällige Zahl zwischen 0 und <number str> als String.
-
CompareDotSeparatedNumbers(<string1>, <string2>)
[W/L/M]
vergleicht zwei Strings vom Typ <zahl>[.<zahl>[.<zahl>[.<zahl>]]] und liefert "0" bei Gleichheit, "1" wenn string1 größer ist und "-1" wenn string1 kleiner ist.
siehe auch boolsche funktionCompareDotSeparatedNumbers
: [CompareDotSeparatedNumbers_bool]
see also: [CompareDotSeparatedStrings_str]
Beispiel:
Der Code:
comment "Testing: "
message "CompareDotSeparatedNumbers"
set $string1$ = "1.2.3.4.5"
set $string2$ = "1.2.3.4.5"
set $ConstTest$ = "0"
set $CompValue$ = CompareDotSeparatedNumbers($string1$, $string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
comment $string1$+" is equal to "+$string2$
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "1.2.31.4.5"
set $string2$ = "1.2.13.4.5"
set $ConstTest$ = "1"
set $CompValue$ = CompareDotSeparatedNumbers($string1$, $string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
comment $string1$+" is higher then "+$string2$
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "1.2.3.4.5"
set $string2$ = "1.2.13.4.5"
set $ConstTest$ = "-1"
set $CompValue$ = CompareDotSeparatedNumbers($string1$, $string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
comment $string1$+" is lower then "+$string2$
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
comment ""
comment "------------------------------"
comment "Testing: "
message "CompareDotSeparatedStrings"
set $string1$ = "1.a.b.c.3"
set $string2$ = "1.a.b.c.3"
set $ConstTest$ = "0"
set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
comment $string1$+" is equal to "+$string2$
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
liefert folgenden Log:
comment: Testing:
message CompareDotSeparatedNumbers
Set $string1$ = "1.2.3.4.5"
The value of the variable "$string1$" is now: "1.2.3.4.5"
Set $string2$ = "1.2.3.4.5"
The value of the variable "$string2$" is now: "1.2.3.4.5"
Set $ConstTest$ = "0"
The value of the variable "$ConstTest$" is now: "0"
Set $CompValue$ = CompareDotSeparatedNumbers($string1$, $string2$)
The value of the variable "$CompValue$" is now: "0"
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: passed
comment: 1.2.3.4.5 is equal to 1.2.3.4.5
Else
EndIf
Set $string1$ = "1.2.31.4.5"
The value of the variable "$string1$" is now: "1.2.31.4.5"
Set $string2$ = "1.2.13.4.5"
The value of the variable "$string2$" is now: "1.2.13.4.5"
Set $ConstTest$ = "1"
The value of the variable "$ConstTest$" is now: "1"
Set $CompValue$ = CompareDotSeparatedNumbers($string1$, $string2$)
The value of the variable "$CompValue$" is now: "1"
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: passed
comment: 1.2.31.4.5 is higher then 1.2.13.4.5
Else
EndIf
Set $string1$ = "1.2.3.4.5"
The value of the variable "$string1$" is now: "1.2.3.4.5"
Set $string2$ = "1.2.13.4.5"
The value of the variable "$string2$" is now: "1.2.13.4.5"
Set $ConstTest$ = "-1"
The value of the variable "$ConstTest$" is now: "-1"
Set $CompValue$ = CompareDotSeparatedNumbers($string1$, $string2$)
The value of the variable "$CompValue$" is now: "-1"
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: passed
comment: 1.2.3.4.5 is lower then 1.2.13.4.5
Else
EndIf
-
CompareDotSeparatedStrings (
<string1>, <string2>`)` [W/L/M]
vergleicht zwei Strings vom Typ <string>.<string>[.<string>[.<string>]] und liefert "0" bei Gleichheit, "1" wenn string1 größer ist und "-1" wenn string1 kleiner ist. Der Vergleich ist nicht Case sensitive.
siehe auch boolsche funktionCompareDotSeparatedStrings
: [CompareDotSeparatedStrings_bool]
see also : [CompareDotSeparatedNumbers_bool]
Beispiel:
Der Code:
comment "Testing: "
message "CompareDotSeparatedStrings"
set $string1$ = "1.a.b.c.3"
set $string2$ = "1.a.b.c.3"
set $ConstTest$ = "0"
set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
comment $string1$+" is equal to "+$string2$
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "1.a.b.c.3"
set $string2$ = "1.A.B.C.3"
set $ConstTest$ = "0"
set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
comment $string1$+" is equal to "+$string2$
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "1.a.cb.c.3"
set $string2$ = "1.a.b.c.3"
set $ConstTest$ = "1"
set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
comment $string1$+" is higher then "+$string2$
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "1.a.ab.c.3"
set $string2$ = "1.a.b.c.3"
set $ConstTest$ = "-1"
set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
comment $string1$+" is lower then "+$string2$
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "1.2.13.4.5"
set $string2$ = "1.2.3.4.5"
set $ConstTest$ = "-1"
set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
comment $string1$+" is lower then "+$string2$
comment "using CompareDotSeparatedStrings give wrong results on numbers"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "1.2.3.4.5"
set $string2$ = "1.2.13.4.5"
set $ConstTest$ = "1"
set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
comment $string1$+" is higher then "+$string2$
comment "using CompareDotSeparatedStrings give wrong results on numbers"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
liefert folgenden Log:
comment: Testing:
message CompareDotSeparatedStrings
Set $string1$ = "1.a.b.c.3"
The value of the variable "$string1$" is now: "1.a.b.c.3"
Set $string2$ = "1.a.b.c.3"
The value of the variable "$string2$" is now: "1.a.b.c.3"
Set $ConstTest$ = "0"
The value of the variable "$ConstTest$" is now: "0"
Set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
The value of the variable "$CompValue$" is now: "0"
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: passed
comment: 1.a.b.c.3 is equal to 1.a.b.c.3
Else
EndIf
Set $string1$ = "1.a.b.c.3"
The value of the variable "$string1$" is now: "1.a.b.c.3"
Set $string2$ = "1.A.B.C.3"
The value of the variable "$string2$" is now: "1.A.B.C.3"
Set $ConstTest$ = "0"
The value of the variable "$ConstTest$" is now: "0"
Set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
The value of the variable "$CompValue$" is now: "0"
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: passed
comment: 1.a.b.c.3 is equal to 1.A.B.C.3
Else
EndIf
Set $string1$ = "1.a.cb.c.3"
The value of the variable "$string1$" is now: "1.a.cb.c.3"
Set $string2$ = "1.a.b.c.3"
The value of the variable "$string2$" is now: "1.a.b.c.3"
Set $ConstTest$ = "1"
The value of the variable "$ConstTest$" is now: "1"
Set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
The value of the variable "$CompValue$" is now: "1"
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: passed
comment: 1.a.cb.c.3 is higher then 1.a.b.c.3
Else
EndIf
Set $string1$ = "1.a.ab.c.3"
The value of the variable "$string1$" is now: "1.a.ab.c.3"
Set $string2$ = "1.a.b.c.3"
The value of the variable "$string2$" is now: "1.a.b.c.3"
Set $ConstTest$ = "-1"
The value of the variable "$ConstTest$" is now: "-1"
Set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
The value of the variable "$CompValue$" is now: "-1"
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: passed
comment: 1.a.ab.c.3 is lower then 1.a.b.c.3
Else
EndIf
Set $string1$ = "1.2.13.4.5"
The value of the variable "$string1$" is now: "1.2.13.4.5"
Set $string2$ = "1.2.3.4.5"
The value of the variable "$string2$" is now: "1.2.3.4.5"
Set $ConstTest$ = "-1"
The value of the variable "$ConstTest$" is now: "-1"
Set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
The value of the variable "$CompValue$" is now: "-1"
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: passed
comment: 1.2.13.4.5 is lower then 1.2.3.4.5
comment: using CompareDotSeparatedStrings give wrong results on numbers
Else
EndIf
Set $string1$ = "1.2.3.4.5"
The value of the variable "$string1$" is now: "1.2.3.4.5"
Set $string2$ = "1.2.13.4.5"
The value of the variable "$string2$" is now: "1.2.13.4.5"
Set $ConstTest$ = "1"
The value of the variable "$ConstTest$" is now: "1"
Set $CompValue$ = CompareDotSeparatedStrings($string1$, $string2$)
The value of the variable "$CompValue$" is now: "1"
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: passed
comment: 1.2.3.4.5 is higher then 1.2.13.4.5
comment: using CompareDotSeparatedStrings give wrong results on numbers
Else
EndIf
-
getDiffTimeSec
[W/L/M]
liefert einen String mit dem ganzahligen Wert der vergangenen Sekunden seit dem letzten Aufruf vonmarktime
.
Seit Version 4.11.3.1
-
timeStampAsFloatStr : string
(Floating Number - format: 'days.decimal days') //since 4.11.6 [W/L/M]
Liefert einen aktuellen Timestamp als Fließkommazahlstring. Dabei ist Zahl vor dem Komma die Tage seit dem 30. Dezember 1899. Nach dem Komma kommt die Zeit in Bruchteilen des Tages.
Just for Fun: Warum nicht der 31. Dezember 1899: ?
siehe http://www.delphibasics.co.uk/RTL.asp?Name=TDateTime
-
SidToName(
<well known sid>`)` [W]
liefert einen String mit dem lokalisierten Namen der mit <well known sid> bezeichneten Gruppe. Zum Beispiel für 'S-1-5-32-544' je nach Lokalisierung des Betriebsystems 'Administratoren' oder 'Administrators'.
Seit Version 4.11.3.1
-
GetMyIpByTarget(
<target ip addr>`)` [W/L/M]
liefert einen String mit der IP-Adresse des Interfaces, welches das Betriebssystem verwenden wird, wenn es versucht <target ip addr> zu erreichen. Diese Funktion liefert sicherer den korrekten Wert als die Verwendung der Konstante%IPAddress%
.
Seit Version 4.11.3.1
Beispiel:
set $CompValue$ = getMyIpByTarget("%opsiServer%")
siehe auch : [GetIpByName]
siehe auch : IPAddress
-
GetIpByName(
<ip addr / ip name>`)` [W/L/M]
liefert die IP-Adresse des mit <ip addr / ip name> angegebenen Rechners
Seit Version 4.11.3.2
set $ConstTest$ = "%IPAddress%" set $string1$ = "%IPAddress%" set $CompValue$ = getIpByName($string1$) if ($ConstTest$ = $CompValue$) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif set $CompValue$ = getIpByName("%HostID%") if ($ConstTest$ = $CompValue$) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif set $CompValue$ = getIpByName("%PCName%") if ($ConstTest$ = $CompValue$) comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif
siehe auch : [GetMyIpByTarget]
-
stringinput(
< message str>,< boolstr confidential>`) : string` //since 4.12.1.2 [W/L/M]
Interaktive Funktion.
Fragt interaktiv unter Ausgabe von < message str> einen String ab und liefert diesen zurück.
Wenn < boolstr confidential> = "true" ist, so wird die interaktive Eingabe mit "*" maskiert. Im grafischen Modus gipt es einen Button mit einem 'Auge' Symbol, der die Eingabe lesbar macht.
Wenn < boolstr confidential> = "true" ist, so ist die Eingabe unmaskiert.
Im grafischen Modus erfolgt die Abfrage im Rahmen eines modalen Fensters, ansonsten auf der Kommandozeile.
-
replaceOpsiConstants(
<string>`) : string` //since 4.12.3.6 [W/L/M]
Ersetzt alle Vorkommen von opsi Konstanten in '<string>' durch ihre Werte und gibt der resultierenden String zurück.
siehe auch : [replaceOpsiConstants_list]
-
fileHasBom (
<file name>`) : boolean` //since 4.12.4.17 [W/L/M]
Diese Funktion liest die ersten 4 Bytes der gegebenen Datei und prüft ob diese einBOM
sind. Wird einBOM
gefunden, so ist der Rückgabewert 'true' ansonsten 'false'.
Mehr zuBOM
finden Sie hier: https://de.wikipedia.org/wiki/Byte_Order_Mark
siehe auch : opsi-script encoding
see also: Encoding related functions siehe auch : [strLoadTextFileWithEncoding]
siehe auch : [loadUnicodeTextFile]
siehe auch : [loadTextFileWithEncoding]
(String-) Funktionen für die Lizenzverwaltung [W/L/M]
-
DemandLicenseKey(`poolId [, productId [,windowsSoftwareId]]
)`
Über die opsi-Webservicefunktion getAndAssignSoftwareLicenseKey wird vom opsi Service abgefragt, ob es für den Computer eine reservierte Lizenz gibt.
Die Datenbasis auf Grund deren die Lizenzen vergeben werden, kann die Computer ID sein, die Produkt ID oder die Windows Software ID (diese Möglichkeiten bestehen, wenn diese Vorgaben in der Lizenzkonfiguration definiert ist).
poolId, productId, windowsSoftwareId sind Strings (bzw. String-Ausdrücke). Wenn die licensePoolId nicht explizit gesetzt ist, bleibt der erste Parameter ein leerer String "". Das gilt auch für die anderen IDs – sofern diese nicht näher definiert werden.
Die Funktion gibt den Lizenzschlüssel zurück, der aus der Datenbasis ausgewählt wurde.
Beispiele:
set $mykey$ = DemandLicenseKey ("pool_office2007")
set $mykey$ = DemandLicenseKey ("", "office2007")
set $mykey$ = DemandLicenseKey ("", "", "{3248F0A8-6813-11D6-A77B}")
-
FreeLicense(`poolId [, productId [,windowsSoftwareId]]]
)`
Über die Funktion freeSoftwareLicense des opsi Services wird die aktuell belegte Lizenz frei gegeben. Diese Syntax ist analog zum Syntax DemandLicenseKey zu sehen: Beispiel:
DefVar $opsiresult$ set $opsiresult$ = FreeLicense("pool_office2007")
'$opsiresult$' wird zu einem leeren String umgesetzt, wenn kein Fehler auftritt und wenn eine Fehler auftritt, wird der Fehlertext ausgegeben.
Abrufen der Fehlerinformationen von Serviceaufrufen [W/L/M]
-
getLastServiceErrorClass
liefert einen String zurück, welcher den Namen der Fehlerklasse des letzten Serviceaufrufs zurück. Wenn der letzte Serviceaufruf keine Fehlermeldung verursacht hat, gibt die Funktion den Wert "None" zurück.
-
getLastServiceErrorMessage
liefert einen String zurück, welcher die Fehlermeldung des letzten Serviceaufrufs entspricht. Wenn der letzte Serviceaufruf keine Fehlermeldung verursacht hat, gibt die Funktion den Wert "None" zurück.
Da die Nachrichtenstrings sich immer mal wieder ändern, wird für die Logik des Grundskriptes die Verwendung des Klassennamen empfohlen.
Beispiel:
if getLastServiceErrorClass = "None"
comment "kein Fehler aufgetreten"
endif
Verarbeitung von String-Listen [W/L/M]
Eine String-Liste (oder ein String-Listenwert) ist eine Abfolge von String-Werten. Der Wert einer String-Liste umfasst also alle Strings dieser Liste. Für diese Werte gibt es die Variable der String-Listen. Seit 4.12.4.32 können auch optional initiale Werte mitgegeben werden. Sie werden wie folgt definiert
DefStringList
<VarName> [= <inital value>]
Ein String-Listenwert wird einer String-Listenvariable zugeteilt:
Set
<VarName> =
<StringListValue>
String-Listenwert (string list expressions
) können auf unterschiedliche weise entstehen:
-
Aus einer Funktion welche eine String-Liste liefert
-
Aus einer String-Liste Variable
-
Seit 4.12.4.32 aus einem String im json style, welche als String-Liste gelesen werden kann
Für die folgenden Beispiele sei generell eine String-Listen-Variable '$list1$' definiert:
DefStringList $list1$
Seit 4.12.4.32 ist die einfachste Methode die Verwendung eines Strings im json style, welche als String-Liste gelesen werden kann:
["<string>"]
Beispiel:
set $list1$ = '["ab","cd","de"]'
Das selbe Ergebnis kann mit der Funktion CreateStringlist
erreicht werden:
set $list1$ = createstringlist("ab","cd","de")
String-Listen können auf vielfältige Weise erzeugt bzw. „eingefangen“ werden. Sie werden in String-Listen-Ausdrücken verarbeitet. Der einfachste String-Listen-Ausdruck ist das Setzen eines (String-Listen-) Wertes auf eine (String-Listen-) Variable.
Diese Variable ($list1$
) lässt sich auf ganz unterschiedliche Weise mit Inhalten füllen:
Wenn wir Variablen mit <String0>, <StringVal>, .. benennen bedeutet das, dass diese für jeden belieben String-Ausdruck stehen können.
Wir beginnen mit einer speziellen und sehr hilfreichen Art von String-Listen: Funktionen – also aufgerufene Hashes oder zugehörige Arrays – welche aus einer Zeile von dem Aufruf 'KEY=VALUE' stammen. Tatsache ist, dass jede Funktion eine Funktion ermitteln sollte, welche einen VALUE mit einem KEY assoziiert. Jeder KEY sollte in dem ersten Abschnitt einer Zeile auftreten (während verschiedene KEYs mit identischen VALUE verbunden sein können).
Info Maps
-
getHWBiosInfoMap
//since 4.11.4 [L/W]
Liefert Infos zur Hardware aus dem BIOS Keys sind (mit Beispiel Werten):
bios.Vendor=Award Software International, Inc. bios.Version=F9b bios.Start Segment=E000 bios.ReleaseDate=07/08/2010 bios.RomSize=1024 k sysinfo.Manufacturer=Gigabyte Technology Co., Ltd. sysinfo.Product Name=GA-MA78GM-UD2H sysinfo.Version= sysinfo.Serial Number= sysinfo.UUID=303032343144323730434336FFFFFFFF sysinfo.SKU Number= sysinfo.Family= board.Manufacturer=Gigabyte Technology Co., Ltd. board.Product=GA-MA78GM-UD2H board.Version=x.x board.Serial Number= board.Asset Tag= board.Feature Flags=01101001 board.Location in Chassis= board.Chassis Handle=6261 board.Board Type=79 Unknown board.Number of Contained Object Handles=116 enclosure.Manufacturer=Gigabyte Technology Co., Ltd. enclosure.Version= enclosure.Serial Number= enclosure.Asset Tag Number= enclosure.Type=Desktop enclosure.Power Supply State=Unknown enclosure.BootUp State=Unknown
-
getMacosVersionMap : stringlist
//macOS Version map //since 4.12.1.0 [M]
Beispiel:
Set $macOSinfomap$ = getMacosVersionMap
ergibt (zum Beispiel) folgenden log:
The value of the variable "$macOSinfomap$" is now: (string 0)Release=11.0 (string 1)Build=20A5364e (string 2)kernel name=Darwin (string 3)node name=vmmac1100onmm1.uib.local (string 4)kernel release=20.1.0 (string 5)kernel version=Darwin Kernel Version 20.1.0: Fri Aug 28 20:45:30 PDT 2020; root:xnu-7195.40.65.0.2~61/RELEASE_X86_64 (string 6)machine=x86_64 (string 7)processor=i386 (string 8)operating system=macOS
-
getLinuxVersionMap
//since 4.11.4 [L]
Keys sind (mit Beispiel Werten):
Distributor ID=Ubuntu Description=Ubuntu 12.04.2 LTS Release=12.04 Codename=precise kernel name=Linux node name=detlefvm05 kernel release=3.2.0-40-generic-pae kernel version=#64-Ubuntu SMP Mon Mar 25 21:44:41 UTC 2013 machine=i686 processor=athlon hardware platform=i386 operating system=GNU/Linux SubRelease
-
getMSVersionMap
[W]
fragt die Betriebssysteminformationen lokal ab und schreibt die Informationen in eine String-Liste.
siehe auch GetMsVersionInfo
siehe auch GetMsVersionName
Im Moment existieren folgende Schlüssel
-
major_version
-
minor_version
-
build_number
-
platform_id
-
csd_version
-
service_pack_major
-
service_pack_minor
-
suite_mask
-
product_type_nr
-
2003r2
-
ReleaseID
-
prodInfoText
-
prodInfoNumber
Die Ergebnisse von suite_mask und product_type_nr sind Zahlen, die aus bitweisen-or-Verknüpfungen der folgenden Werte gebildet sein können.
product_type_nr
SuiteMask
-
ReleaseID
. Der dazugehörige Wert gibt die Release von 'Windows 10' an wie z.B. '1511'.
Leerstring wenn nicht vorhanden.
Der Wert kommt aus der Registry: "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" "ReleaseID" -
prodInfoText
.Der dazugehörige Wert gibt die verwendeten Windows Edition als String an wie z.B. 'PRODUCT_PROFESSIONAL'. -
prodInfoNumber
.Der dazugehörige Wert gibt die verwendeten Windows Edition als Zahl an wie z.B. '48'.
ProdInfoNumber und ProdInfoText
DecNum |
HexNum |
Text |
00 |
00 |
An unknown product |
01 |
01 |
Ultimate Edition" |
02 |
02 |
Home Basic Edition |
03 |
03 |
Home Premium Edition |
04 |
04 |
Enterprise Edition |
05 |
05 |
Home Basic Edition |
06 |
06 |
Business Edition |
07 |
07 |
Server Standard Edition (full installation) |
08 |
08 |
Server Datacenter Edition (full installation) |
09 |
09 |
Small Business Server |
10 |
0A |
Server Enterprise Edition (full installation) |
11 |
0B |
Starter Edition |
12 |
0C |
Server Datacenter Edition (core installation) |
13 |
0D |
Server Standard Edition (core installation) |
14 |
0E |
Server Enterprise Edition (core installation) |
15 |
0F |
Server Enterprise Edition for Itanium-based Systems |
16 |
10 |
Business Edition |
17 |
11 |
Web Server Edition (full installation) |
18 |
12 |
Cluster Server Edition |
19 |
13 |
Home Server Edition |
20 |
14 |
Storage Server Express Edition |
21 |
15 |
Storage Server Standard Edition |
22 |
16 |
Storage Server Workgroup Edition |
23 |
17 |
Storage Server Enterprise Edition |
24 |
18 |
Server for Small Business Edition |
25 |
19 |
Small Business Server Premium Edition |
26 |
1A |
PRODUCT_HOME_PREMIUM_N |
27 |
1B |
PRODUCT_ENTERPRISE_N |
28 |
1C |
PRODUCT_ULTIMATE_N |
29 |
1D |
PRODUCT_WEB_SERVER_CORE |
30 |
1E |
Windows Essential Business Server Management Server |
31 |
1F |
Windows Essential Business Server Security Server |
32 |
20 |
Windows Essential Business Server Messaging Server |
33 |
21 |
Server Foundation |
34 |
22 |
PRODUCT_HOME_PREMIUM_SERVER |
35 |
23 |
PRODUCT_SERVER_FOR_SMALLBUSINESS_V |
36 |
24 |
Server Standard Edition without Hyper-V (full installation) |
37 |
25 |
Server Datacenter Edition without Hyper-V (full installation) |
38 |
26 |
Server Enterprise Edition without Hyper-V (full installation) |
39 |
27 |
Server Datacenter Edition without Hyper-V (core installation) |
40 |
28 |
Server Standard Edition without Hyper-V (core installation) |
41 |
29 |
Server Enterprise Edition without Hyper-V (core installation) |
48 |
30 |
PRODUCT_PROFESSIONAL |
49 |
31 |
PRODUCT_PROFESSIONAL_N |
50 |
32 |
PRODUCT_SB_SOLUTION_SERVER |
51 |
33 |
PRODUCT_SERVER_FOR_SB_SOLUTIONS |
52 |
34 |
PRODUCT_STANDARD_SERVER_SOLUTIONS |
53 |
35 |
PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE |
54 |
36 |
PRODUCT_SB_SOLUTION_SERVER_EM |
55 |
37 |
PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM |
56 |
38 |
PRODUCT_SOLUTION_EMBEDDEDSERVER |
57 |
39 |
PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE |
59 |
3B |
PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT |
60 |
3C |
PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL |
61 |
3D |
PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC |
62 |
3E |
PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC |
63 |
3F |
PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE |
64 |
40 |
PRODUCT_CLUSTER_SERVER_V |
65 |
41 |
PRODUCT_EMBEDDED |
66 |
42 |
PRODUCT_STARTER_E |
67 |
43 |
PRODUCT_HOME_BASIC_E |
68 |
44 |
PRODUCT_HOME_PREMIUM_E |
69 |
45 |
PRODUCT_PROFESSIONAL_E |
70 |
46 |
PRODUCT_ENTERPRISE_E |
71 |
47 |
PRODUCT_ULTIMATE_E |
72 |
48 |
PRODUCT_ENTERPRISE_EVALUATION |
84 |
54 |
PRODUCT_ENTERPRISE_N_EVALUATION |
98 |
62 |
PRODUCT_CORE_N |
99 |
63 |
PRODUCT_CORE_COUNTRYSPECIFIC |
100 |
64 |
PRODUCT_CORE_SINGLELANGUAGE |
101 |
65 |
PRODUCT_CORE |
121 |
79 |
PRODUCT_EDUCATION |
122 |
7A |
PRODUCT_EDUCATION_N |
125 |
7D |
Windows Enterprise 2015 LTSB |
126 |
7E |
Windows Enterprise 2015 LTSB N |
129 |
81 |
Windows Enterprise 2015 LTSB Evaluation |
130 |
82 |
Windows Enterprise 2015 LTSB N Evaluation |
Beispiel:
Der Code
DefStringList $INST_Resultlist$
DefStringList $INST_Resultlist2$
message "getMSVersionMap"
comment "get value by winst function"
set $INST_Resultlist$ = getMSVersionMap
Liefert z.B. im Log:
message getMSVersionMap
comment: get value by winst function
Set $INST_Resultlist$ = getMSVersionMap
retrieving strings from getMSVersionMap [switch to loglevel 7 for debugging]
(string 0)major_version=5
(string 1)minor_version=1
(string 2)build_number=2600
(string 3)platform_id=2
(string 4)csd_version=Service Pack 3
(string 5)service_pack_major=3
(string 6)service_pack_minor=0
(string 7)suite_mask=256
(string 8)product_type_nr=1
(string 9)2003r2=false
Background infos for getMSVersionMap |
-
getFileInfoMap(
<file name>) : stringlist
[W] -
getFileInfoMap32(
<file name>) : stringlist
//since 4.11.6.6 [W] -
getFileInfoMap64(
<file name>) : stringlist
//since 4.11.6.6 [W] -
getFileInfoMapSynative(
<file name>) : stringlist
//since 4.11.6.6 [W]
findet die Versionsinformationen, die im FILENAME verborgen sind und schreibt sie in eine String-Listen Funktion.
Zur Zeit existieren folgende Schlüssel,
-
Comments
-
CompanyName
-
FileDescription
-
FileVersion
-
InternalName
-
LegalCopyright
-
LegalTrademarks
-
OriginalFilename
-
PrivateBuild
-
ProductName
-
ProductVersion
-
SpecialBuild
-
Language name <index>
-
Language ID <index>
-
file version with dots
-
file version
-
product version
Verwendung: Wenn wir folgendes Skriptteil definieren und aufrufen
DefStringList FileInfo
DefVar $InterestingFile$
Set $InterestingFile$ = "c:\program files\my program.exe"
set FileInfo = getFileInfoMap($InterestingFile$)
bekommen wir die Werte, die zum Schlüssel "FileVersion" dazugehören, über den Aufruf
DefVar $result$
set $result$ = getValue("FileVersion", FileInfo)
ausgegeben (für die Funktion getValue vgl. Abschnitt (Wieder-) Gewinnen von Einzelstrings aus String-Listen oder Dateien).
Beispiel:
Der Code:
set $InterestingFile$ = "%OpsiScriptDir%\winst.exe"
if not (FileExists($InterestingFile$))
set $InterestingFile$ = "%OpsiScriptDir%\winst32.exe"
endif
set $INST_Resultlist$ = getFileInfoMap($InterestingFile$)
liefert z.B. im Log
Set $InterestingFile$ = "N:\develop\delphi\winst32\trunk\winst.exe"
The value of the variable is now: "N:\develop\delphi\winst32\trunk\winst.exe"
If
Starting query if file exist ...
FileExists($InterestingFile$) <<< result true
not (FileExists($InterestingFile$)) <<< result false
Then
EndIf
Set $INST_Resultlist$ = getFileInfoMap($InterestingFile$)
retrieving strings from getFileInfoMap [switch to loglevel 7 for debugging]
(string 0)Language name 0=Deutsch (Deutschland)
(string 1)Language ID 0=1031
(string 2)file version=1125942857039872
(string 3)file version with dots=4.10.8.0
(string 4)product version=1125942857039872
(string 5)Comments=
(string 6)CompanyName=uib gmbh (www.uib.de)
(string 7)FileDescription=opsi.org
(string 8)FileVersion=4.10.8.0
(string 9)InternalName=
(string 10)LegalCopyright=uib gmbh under GPL
(string 11)LegalTrademarks=opsi
(string 12)OriginalFilename=
(string 13)PrivateBuild=
(string 14)ProductName=opsi-script
(string 15)ProductVersion=4.0
(string 16)SpecialBuild=
-
getLocaleInfoMap
[W]
fragt die Systeminformationen lokal ab und schreibt die Informationen in eine String-Liste.
Im Moment existieren folgende Schlüssel
-
language_id_2chars (eine „Zwei-Buchstaben“ Namensangabe der default Systemsprache)
-
language_id (eine „Drei-Buchstaben“ Namensangabe der default Systemsprache inklusive der Sprachenuntertypen)
-
localized_name_of_language
-
English_name_of_language
-
abbreviated_language_name
-
native_name_of_language
-
country_code
-
localized_name_of_country
-
English_name_of_country
-
abbreviated_country_name
-
native_name_of_country
-
default_language_id
-
default_language_id_decimal
-
default_country_code
-
default_oem_code_page
-
default_ansi_code_page
-
default_mac_code_page
-
system_default_language_id Hexadecimal Windows locale Id
-
system_default_posix Sprache_Region (Posix Style)
-
system_default_lang_region Sprache-Region (BCP 47 Style)
Die system_default Keys geben Informationen über die Sprache des installierten Betriebssystems. Die anderen Keys geben Informationen über die Lokalisierung der GUI.
Beispiel:
Der Code:
message "Locale Infos"
set $INST_Resultlist$ = getLocaleInfoMap
liefert z.B. folgendes Log:
message Locale Infos
Set $INST_Resultlist$ = getLocaleInfoMap
retrieving strings from getLocaleInfoMap [switch to loglevel 7 for debugging]
(string 0)language_id_2chars=DE
(string 1)language_id=DEU
(string 2)localized_name_of_language=Deutsch (Deutschland)
(string 3)English_name_of_language=German
(string 4)abbreviated_language_name=DEU
(string 5)native_name_of_language=Deutsch
(string 6)country_code=49
(string 7)localized_name_of_country=Deutschland
(string 8)English_name_of_country=Germany
(string 9)abbreviated_country_name=DEU
(string 10)native_name_of_country=Deutschland
(string 11)default_language_id=0407
(string 12)default_language_id_decimal=1031
(string 13)default_country_code=49
(string 14)default_oem_code_page=850
(string 15)default_ansi_code_page=1252
(string 16)default_mac_code_page=10000
(string 17)system_default_language_id=0407
(string 18)system_default_posix=de_DE
(string 19)system_default_lang_region=de-DE
Verwendung: Wenn wir den Aufruf wie folgt definieren
DefStringList $languageInfo$
set $languageInfo$ = getLocaleInfoMap
bekommen wir den Wert mit dem KEY "language_id_2chars" über den Aufruf
DefVar $result$
set $result$ = getValue("language_id_2chars", $languageInfo$)
(für die Funktion getValue vgl. Abschnitt (Wieder-) Gewinnen von Einzelstrings aus String-Listen oder Dateien). Wir können nun Skripte mit folgender Konstruktion verwenden
if getValue("language_id_2chars", languageInfo) = "DE"
; installiere deutsche Version
else
if getValue("language_id_2chars", languageInfo) = "EN"
; installiere englische Version
endif
endif
Background infos for getLocaleInfoMap: |
Die Funktion GetLocaleInfoMap ersetzt die ältere GetLocaleInfo, da diese Werte ausliest, die schwierig zu interpretieren sind:
-
getLocaleInfo
(abgekündigt): BitteGetLocaleInfoMap
verwenden.
-
getProductMap
// since 4.11.2.4 [W/L/M]
liefert eine info map über das opsi product welches gerade installiert wird.
Die Funktion arbeitet nur korrekt, wenn opsi-script im opsi service mode aufgerufen wird.
keys sind: id, name, description, advice, productversion, packageversion, priority, installationstate, lastactionrequest, lastactionresult, installedversion, installedpackage, installedmodificationtime, actionrequest
Beispiel:
set $INST_Resultlist$ = getProductMap
set $string1$ = getValue("id", $INST_Resultlist$)
liefert z.B. folgenden log:
Set $INST_Resultlist$ = getProductMap
retrieving strings from getProductMap [switch to loglevel 7 for debugging]
(string 0)id=opsi-script-test
(string 1)name=opsi-script test
(string 2)description=Test and example script for opsi-script
(string 3)advice=
(string 4)productversion=4.11.2
(string 5)packageversion=1
(string 6)priority=0
(string 7)installationstate=unknown
(string 8)lastactionrequest=setup
(string 9)lastactionresult=successful
(string 10)installedversion=4.11.2
(string 11)installedpackage=1
(string 12)installedmodificationtime=
(string 13)actionrequest=setup
Set $string1$ = getValue("id", $INST_Resultlist$)
retrieving strings from $INST_Resultlist$ [switch to loglevel 7 for debugging]
(string 0)id=opsi-script-test
(string 1)name=opsi-script test
(string 2)description=Test and example script for opsi-script
(string 3)advice=
(string 4)productversion=4.11.2
(string 5)packageversion=1
(string 6)priority=0
(string 7)installationstate=unknown
(string 8)lastactionrequest=setup
(string 9)lastactionresult=successful
(string 10)installedversion=4.11.2
(string 11)installedpackage=1
(string 12)installedmodificationtime=
(string 13)actionrequest=setup
The value of the variable "$string1$" is now: "opsi-script-test"
-
editmap(
< strlist>`) : stringlist` //since 4.12.1.2 [W/L/M]
Interaktive Funktion.
Zeigt die übergebene < strlist> als <key>=<value> Paare in Form einer Liste an und gibt die Möglichkeit die Werte (values) zu ändern. Nach Abschluß des Editiervorgangs wird die editierte Variante von < strlist> zurückgegeben.
Im grafischen Modus erfolgt die Abfrage im Rahmen eines modalen Fensters, ansonsten auf der Kommandozeile.
-
getListFromWMI(
<wmi namespace str>,<wmi class str>,<property list>,<condition str>`) : stringlist` //since 4.12.1.0 [W]
Liefert eine info map der Werte die aus der WMI Klasse <wmi class str> ermittelt wurden. Diese info map kann begrenzt werden auf die Liste der Eigenschaften aus <property list> und durch die Bedingung aus <condition str>. Wenn <property list> leer ist, so werden die Werte für alle Eigenschaften der Klasse zurückgegeben.
Achtung: Wenn <property list> eine Eigenschaft enthält, welche nicht in der Klasse <wmi class str> enthalten ist, so schlägt die Abfrage fehl.
Abfragen mit Angabe von Eigenschaften <property list> sind schneller als Abfragen ohne.
Wenn der Namespace <wmi namespace str> leer ist, so wird als Defaultroot\cimv2
verwendet.
Bei einem Fehler wird eine leere Liste zurückgegeben.
Beispiel:
; this is valid because both properties are valid
set $list1$ = createStringList ('Model','Manufacturer')
set $str1$ = 'root\cimv2'
set $str2$ = 'Win32_ComputerSystem'
set $str3$ = ''
set $resultlist$ = getListFromWMI($str1$,$str2$,$list1$,$str3$)
produziert z.B. folgenden Log:
Set $list1$ = createStringList ('Model','Manufacturer')
The value of the variable "$list1$" is now:
(string 0)Model
(string 1)Manufacturer
Set $str1$ = 'root\cimv2'
The value of the variable "$str1$" is now: "root\cimv2"
Set $str2$ = 'Win32_ComputerSystem'
The value of the variable "$str2$" is now: "Win32_ComputerSystem"
Set $str3$ = ''
The value of the variable "$str3$" is now: ""
Set $resultlist$ = getListFromWMI($str1$,$str2$,$list1$,$str3$)
The value of the variable "$resultlist$" is now:
(string 0)Model=HP Pavilion Desktop PC 570-p0xx
(string 1)Manufacturer=HP
Beispiel:
comment "Testing for os architecture"
set $ConstTest$ = GetSystemType
set $list1$ = createStringList ('systemtype')
set $str1$ = ''
set $str2$ = 'Win32_ComputerSystem'
set $str3$ = ''
set $resultlist$ = getListFromWMI($str1$,$str2$,$list1$,$str3$)
produziert z.B. folgenden Log:
comment: Testing for os architecture
Set $ConstTest$ = GetSystemType
The value of the variable "$ConstTest$" is now: "64 Bit System"
Set $list1$ = createStringList ('systemtype')
The value of the variable "$list1$" is now:
(string 0)systemtype
Set $str1$ = ''
The value of the variable "$str1$" is now: ""
Set $str2$ = 'Win32_ComputerSystem'
The value of the variable "$str2$" is now: "Win32_ComputerSystem"
Set $str3$ = ''
The value of the variable "$str3$" is now: ""
Set $resultlist$ = getListFromWMI($str1$,$str2$,$list1$,$str3$)
The value of the variable "$resultlist$" is now:
(string 0)systemtype=x64-based PC
Beispiel:
comment "Testing for freespace"
;wmic LogicalDisk "%Systemdrive%" get freespace
set $list1$ = createStringList ('freespace')
set $str1$ = 'root\cimv2'
set $str2$ = 'Win32_LogicalDisk'
set $str3$ = 'where Name="%Systemdrive%"'
markerrornumber
set $resultlist$ = getListFromWMI($str1$,$str2$,$list1$,$str3$)
if errorsOccuredSinceMark = 0
set $CompValue$ = getValue("freespace", $resultlist$)
set $CompValue$ = calculate($CompValue$+ '-1')
if (HasMinimumSpace ("%Systemdrive%", $CompValue$))
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $CompValue$ = calculate($CompValue$+ '+10')
if (HasMinimumSpace ("%Systemdrive%", $CompValue$))
set $TestResult$ = "not o.k."
LogWarning "failed"
else
comment "passed"
endif
endif
produziert z.B. folgenden Log:
comment: Testing for freespace
Set $list1$ = createStringList ('freespace')
The value of the variable "$list1$" is now:
(string 0)freespace
Set $str1$ = 'root\cimv2'
The value of the variable "$str1$" is now: "root\cimv2"
Set $str2$ = 'Win32_LogicalDisk'
The value of the variable "$str2$" is now: "Win32_LogicalDisk"
Set $str3$ = 'where Name="C:"'
The value of the variable "$str3$" is now: "where Name="C:""
Marked error number 1
Set $resultlist$ = getListFromWMI($str1$,$str2$,$list1$,$str3$)
The value of the variable "$resultlist$" is now:
(string 0)freespace=235092250624
If
errorsOccuredSinceMark = 0 <<< result true
Then
Set $CompValue$ = getValue("freespace", $resultlist$)
The value of the variable "$CompValue$" is now: "235092250624"
Set $CompValue$ = calculate($CompValue$+ '-1')
The value of the variable "$CompValue$" is now: "235092250623"
If
Free on Disk C:: 235.092.250.624 bytes This is more than the required amount of 235.092.250.623 bytes
HasMinimumSpace ("C:", $CompValue$) <<< result true
(HasMinimumSpace ("C:", $CompValue$)) <<< result true
Then
comment: passed
Else
EndIf
Set $CompValue$ = calculate($CompValue$+ '+10')
The value of the variable "$CompValue$" is now: "235092250633"
If
Free on Disk C:: 235.092.250.624 bytes This is less than the required amount of 235.092.250.633 bytes
HasMinimumSpace ("C:", $CompValue$) <<< result false
(HasMinimumSpace ("C:", $CompValue$)) <<< result false
Then
Else
comment: passed
EndIf
EndIf
Beispiel:
comment "Testing for drive count"
;wmic LogicalDisk "%Systemdrive%" get name
set $list1$ = createStringList ('Name')
set $str1$ = ''
set $str2$ = 'Win32_LogicalDisk'
set $str3$ = ''
set $resultlist$ = getListFromWMI($str1$,$str2$,$list1$,$str3$)
set $CompValue$ = count($resultlist$)
set $resultlist$ = powershellCall('get-psdrive -psprovider filesystem | select-object -expand Name')
set $ConstTest$ = count($resultlist$)
if ($ConstTest$ = $CompValue$)
comment "getListFromWMI passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing getListFromWMI failed"
endif
produziert z.B. folgenden Log:
comment: Testing for drive count
The value of the variable "$list1$" is now:
(string 0)Name
The value of the variable "$str1$" is now: ""
The value of the variable "$str2$" is now: "Win32_LogicalDisk"
The value of the variable "$str3$" is now: ""
The value of the variable "$resultlist$" is now:
(string 0)Name=C:
(string 1)Name=D:
(string 2)Name=E:
(string 3)Name=F:
(string 4)Name=L:
(string 5)Name=N:
(string 6)Name=R:
(string 7)Name=S:
(string 8)Name=W:
(string 9)Name=Y:
(string 10)Name=Z:
The value of the variable "$CompValue$" is now: "11"
PowershellCall Executing: get-psdrive -psprovider filesystem | select-object -expand Name ; mode: sysnative
ShellCall Executing: "C:\WINDOWS\system32\\cmd.exe" /C "powershell.exe get-executionpolicy"
Powershell excution policy = Bypass
ShellCall Executing: "C:\WINDOWS\system32\\cmd.exe" /C "powershell.exe set-executionpolicy ByPass"
Execution of tmp-internal powershell.exe winst /sysnative
Save to file with encoding: system
ExitCode 0
The file: c:\opsi.org\tmp\_opsiscript_N97cDr97Km.ps1 has been deleted
ShellCall Executing: "C:\WINDOWS\system32\\cmd.exe" /C "powershell.exe set-executionpolicy Bypass"
The value of the variable "$resultlist$" is now:
(string 0)C
(string 1)D
(string 2)E
(string 3)F
(string 4)L
(string 5)N
(string 6)R
(string 7)S
(string 8)W
(string 9)Y
(string 10)Z
The value of the variable "$ConstTest$" is now: "11"
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: getListFromWMI passed
Else
EndIf
Erzeugung von String-Listen aus vorgegebenen String-Werten [W/L/M]
-
createStringList (`Stringwert0, Stringwert1 ,… `)
[W/L/M]
erzeugt eine neue Liste aus den aufgeführten einzelnen String-Werten, z.B. liefert
set $list1$ = createStringList ('a','b', 'c', 'd')
die ersten vier Buchstaben des Alphabets.
-
splitString (`Stringwert1, Stringwert2
)` [W/L/M]
erzeugt die Liste der Teilstrings von String-Wert1, die jeweils durch String-Wert2 voneinander getrennt sind. Z.B. bildet
set $list1$ = splitString ("\\server\share\directory", "\")
die Liste
'"", "", "server", "share", "directory"'
Ist der übergebene String confidential, so werden es die hier enstehenden Teile auch sein.
-
splitStringOnWhiteSpace (
<string>`)` [W/L/M]
zerlegt <string> in die durch "leere" Zwischenräume definierten Abschnitte. Das heißt z.B.
set $list1$ = splitStringOnWhiteSpace("Status Lokal Remote Netzwerk")
liefert die Liste
'"Status", "Lokal", "Remote", "Netzwerk"'
unabhängig davon, wie viele Leerzeichen oder ggf. Tabulatorzeichen zwischen den "Wörtern" stehen.
Ist der übergebene String confidential, so werden es die hier entstehenden Teile auch sein.
Laden der Zeilen einer Textdatei in eine String-Liste
-
loadTextFile (`Dateiname
)` [W/L/M]
liest die Zeilen der Datei des (als String) angegebenen Namens ein und generiert aus ihnen eine String-Liste.
-
LoadTextFileWithEncoding(
<file name>,
<encoding>`)` [W/L/M]
Liefert eine Stringliste mit dem Inhalt von <file name> welcher beim Einlesen von <encoding> in das laufende Encoding des Systems konvertiert wurde.
-
loadUnicodeTextFile (`Dateiname
)` [W/L/M]
liest die Zeilen der Unicode-Datei des (als String) angegebenen Namens ein und generiert aus ihnen eine String-Liste.
Die Strings in der String-Liste werden dabei (gemäß den Betriebssystem-Defaults) in 8 Bit-Code konvertiert.
-
getSectionNames (`Dateiname
)` [W/L/M]
liest die ausgewählte Datei als eine ini-Datei aus, durchsucht alle Zeilen nach dem Begriff
'[<SectionName>]' und gibt die einfachen Sektionsnamen (ohne Klammern) aus.
-
GetSectionFromInifile(<Sektion>,<INI-Datei>): stringlist
[W/L/M]
Sucht <Sektion> in der INI-Datei und gibt den kompletten Inhalt der Sektion (mit Sektionsbezeichnung) als Stringliste zurück.
(Wieder-) Gewinnen von Einzelstrings aus String-Listen oder Dateien [W/L/M]
-
composeString (
<StringListe>, <LinkString>`)` [W/L/M]
Mit dieser Funktion lässt sich die Zerlegung eines Strings in einer String-Liste z.B. nach vorheriger Transformation (s. den Abschnitt „Transformation von String-Listen“) – rückgängig machen.
Zum Beispiel:
Wenn $list1$ für die Liste 'a', 'b', 'c', 'd', 'e' steht, erhält die String-Variable line mittels$line$ = composeString ($list1$, " | ")
den Wert '"a | b | c | d | e".' -
takeString(
<index>,<list>`)` [W/L/M]
liefert aus der String-Liste <list> den String mit dem Index <index>
zum Beispiel liefert (wenn $list1$ wie eben die Liste der ersten fünf Buchstaben des Alphabets ist)takeString (2, list1)
den String 'c' (der Index beruht auf einer mit 0 beginnenden Nummerierung der Listenelemente).
Hat Index einen negative Wert, werden die Werte ausgehend vom Ende der Liste gelesen, z.B. gibt
takeString (-1, list1)
das letzte Listenelement zurück; das ist 'e'.
siehe auch : setStringInListAtIndex
siehe auch : takeString -
takeFirstStringContaining(
<list>,<search string>`)` [W/L/M]
Liefert den ersten String einer Liste der <search string> enthält. Liefert einen leeren String wenn kein passender String gefunden wird.
siehe auch : takeFirstStringContaining
-
getValue(
<key>, <list>`)` [W/L/M]
Diese Funktion versucht eine String-Liste <list> als eine Liste aus Zeilen der Form
'key=value'
auszulesen.
Dazu sucht die Funktion die erste Zeile, wo der String-Key vor dem Gleicheitszeichen erscheint und gibt den Rest der Zeile zurück (der String, der nach dem Gleicheitszeichen folgt). Wenn es keinen passende Zeile gibt, wird der Wert 'NULL' zurückgegeben.
Die Funktion ist z.B. hilfreich für die Nutzung von Info maps wie sie von Funktionen wiegetLocaleInfoMap
,getFileVersionMap
, geliefert werden. siehe auch: Info Maps.
-
getValueBySeparator(
<key string>,<separator string>,<hash string list>)
//since 4.11.2.1 [W/L/M]
arbeitet wiegetValue
aber der Trenner zwischen 'key' und 'value' (<separator string>) muss angegeben werden so das mit maps gearbeitet werden kann wie
'key:value'
-
setValueByKey(
<key>, <value>, <targetlist>)
: stringlist [W/L/M]
Setzt in der String-Liste <targetlist> den Wert des String-Key <key> auf den Wert <value>. Dafür muss die String-Liste <targetlist> eine Key/Value-Liste sein, das heißt jeder Eintrag ist von der Form
'key=value'.
Sind die Key/Value-Paare in <targetlist> nicht durch=
getrennt sondern durch einen anderen Seperator, dann muss dieser der Funktion als Argument mitgegeben werden.
Beispiel:
Set $KeyValueList$ = createStringList('key1=value1','key2=value2') Set $NewList$ = setValueByKey('key2','newvalue',$KeyValueList$) ; then $NewList$ = ['key1=value1','key2=newvalue'] Set $KeyValueListWithDifferentSeperator$ = createStringList('key1:value1','key2:value2') Set $NewListWithDifferentSeperator$ = setValueByKey('key2','newvalue',$KeyValueListWithDifferentSeperator$,':') ; then $NewListWithDifferentSeperator$ = ['key1:value1','key2:newvalue']
-
getValueFromFile(
<key string>, <file name>`)` //since 4.11.4.4 [W/L/M]
Sucht in <file name> nach einem key/value Paar mit dem key <key string> und separator string '=' und liefert den gefundenen value. Wenn <key string> nicht gefunden wird, liefert die Funktion einen leeren string.
-
getValueFromFileBySeparator(
<key string>,<separator string>, <file name>`)` //since 4.11.4.4 [W/L/M]
Sucht in <file name> nach einem key/value Paar mit dem key <key string> und separator string <separator string> und liefert den gefundenen value. Wenn <key string> nicht gefunden wird, liefert die Funktion einen leeren string.
-
count (
<list>`) : string` [W/L/M]
Die Funktion zählt die Elemente einer String-Liste <list>; das Resultat wird in einen String gewandelt. Ist $list1$ z.B.
'a', 'b', 'c', 'd', 'e'
so hatcount ($list1$)
den Wert "5".
String-Listen-Erzeugung mithilfe von Sektionsaufrufen
-
retrieveSection (`Sektionsname
)` [W/L/M]
gibt die Zeilen einer aufgerufene Sektion aus.
-
getOutStreamFromSection (`Sectionname
)` [W/L/M]
„fängt“ – derzeit beiShellScript
(ShellInAnIcon
),ExecWith
undExecPython
Aufrufen – die Ausgabe der Kommandozeilenprogramme in der Form einer String-Liste ein. Z.B. liefert der AusdruckgetOutStreamFromSection ('ShellScript_netstart')
wenn die aufgerufene Sektion definiert ist durch
set $list$ = getOutStreamFromSection ('ShellScript_netstart') [ShellScript_netstart] net start
eine Reihe von Zeilen, die u.a. die Auflistung aller laufenden Dienste enthalten und dann weiter bearbeitet werden können.
siehe auch : getReturnListFromSection
siehe auch: executeSection
Seit 4.11.4.2 gibt es für einfache Befehle und besonders (aber nicht nur) für den Einsatz unter Linux folgende 'Abkürzung', welche unter Windows im 'sysnative' mode läuft:
-
shellCall (
<command string>`) : stringlist (output)` //since 4.11.4.2 [W/L/M]
set $list$= shellCall('net start')
ist eine Abkürzung von:
set $list$ = getOutStreamFromSection ('ShellScript_netstart winst /sysnative')
[ShellScript_netstart]
net start
siehe auch: shellCall_list
-
shellCall (
<command string>`) : noresult` //since 4.11.6.1 [W/L/M]
shellCall('net start')
Is a shortcut for this expression:
ShellScript_netstart winst /sysnative
[ShellScript_netstart]
net start
siehe auch: shellCall
-
shellCall (
<command string>`) : string (exitcode)` //since 4.11.6.1 [W/L/M]
set $exitcode$ = shellCall('net start')
Is a shortcut for this expression:
ShellScript_netstart winst /sysnative
set $exitcode$ = getLastExitcode
[ShellScript_netstart]
net start
siehe auch: shellCall_str
-
getReturnListFromSection (
Sectionname)
[W/L/M]
In Sektionen bestimmter Typen – derzeit implementiert nur fürXMLPatch
-undopsiServiceCall
-Sektionen – existiert eine spezifische Return-Anweisung, die ein Ergebnis der Sektion als String-Liste zur Verfügung stellt.
XMLPatch
Beispiel:
Die Anweisung
set $list1$ =getReturnListFromSection ('XMLPatch_mime "c:\mimetypes.rdf"')
liefert eine spezifisch selektierte Liste von Knoten der XML-Datei mimetypes.rdf. Näheres zu XMLPatch
-Sektionen ist der Dokumentation im Kapitel opsi-script-xmlpatch zu entnehmen.
OpsiServiceCall
Beispiel:
DefStringList $result$
Set $result$=getReturnListFromSection("opsiservicecall_clientIdsList")
[opsiservicecall_clientIdsList]
"method":"getClientIds_list"
"params":[]
siehe auch: getOutStreamFromSection siehe auch: executeSection
String-Listen aus der Registry [W]
-
getRegistryKeyList32(
<regkey>`)`
Liefert eine Liste mit dem Namen aller Keys direkt unterhalb von <regkey>.
32 Bit Modus (mit Redirection). Seit 4.11.3
-
getRegistryKeyList64(
<regkey>`)`
Liefert eine Liste mit dem Namen aller Keys direkt unterhalb von <regkey>.
64 Bit Modus (ohne Redirection). Seit 4.11.3
-
getRegistryKeyListSysnative(
<regkey>`)`
Liefert eine Liste mit dem Namen aller Keys direkt unterhalb von <regkey>.
Modus abhängig von der Architektur des Betriebssystems. Seit 4.11.3
-
getRegistryKeyList(
<regkey>, <access str>`)`
Fasst die vorigen drei Funktionen zusammen, das heißt, die Funktion liefert eine Liste mit dem Namen aller Keys direkt unterhalb von <regkey>, wobei der Modus (32bit
,64bit
,sysnative
) als <access str> mitgegeben wird. Seit 4.12.5.0
-
getRegistryVarList32(
<regkey>`)`
Liefert eine Liste mit dem Namen aller Werte direkt unterhalb von <regkey>.
32 Bit Modus (mit Redirection). Seit 4.11.3
-
getRegistryVarList64(
<regkey>`)`
Liefert eine Liste mit dem Namen aller Werte direkt unterhalb von <regkey>.
64 Bit Modus (ohne Redirection). Seit 4.11.3
-
getRegistryVarListSysnative(
<regkey>`)`
Liefert eine Liste mit dem Namen aller Werte direkt unterhalb von <regkey>.
Modus abhängig von der Architektur des Betriebssystems. Seit 4.11.3
-
getRegistryVarList(
<regkey>, <access str>`)`
Fasst die vorigen drei Funktionen zusammen, das heißt, die Funktion liefert eine Liste mit dem Namen aller Werte direkt unterhalb von <regkey>, wobei der Modus (32bit
,64bit
,sysnative
) als <access str> mitgegeben wird. Seit 4.12.5.0
-
getRegistryVarMap32(
<regkey>`)`
Liefert eine Map mit den Namen=Value Paaren aller Werte direkt unterhalb von <regkey>.
32 Bit Modus (mit Redirection). Seit 4.11.3
-
getRegistryVarMap64(
<regkey>`)`
Liefert eine Map mit den Namen=Value Paaren aller Werte direkt unterhalb von <regkey>.
64 Bit Modus (ohne Redirection). Seit 4.11.3
-
getRegistryVarMapSysnative(
<regkey>`)`
Liefert eine Map mit den Namen=Value Paaren aller Werte direkt unterhalb von <regkey>.
Modus abhängig von der Architektur des Betriebssystems. Seit 4.11.3
-
getRegistryVarMap(
<regkey>, <access str>`)`
Fasst die vorigen drei Funktionen zusammen, das heißt, die Funktion liefert eine Map mit den Namen=Value Paaren aller Werte direkt unterhalb von <regkey>, wobei der Modus (32bit
,64bit
,sysnative
) als <access str> mitgegeben wird. Seit 4.12.5.0
Beispiel:
Wir erzeugen Registryeinträge mit folgender Sektion durch den Aufruf von:
Registry_createkeys /32Bit
[Registry_createkeys]
openkey [HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\opsi-script-test]
set "var1" = "value1"
set "var2" = REG_SZ:"value2"
set "var3" = REG_EXPAND_SZ:"value3"
set "var4" = REG_DWORD:444
; REG_QWORD wird unterstützt seit 4.12.6
set "var5" = REG_QWORD:18446744073709551615
set "var6" = REG_BINARY:05 05 05 0F 10
set "var7" = REG_MULTI_SZ:"value6|value7|de"
openkey [HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\opsi-script-test\key1]
openkey [HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\opsi-script-test\key2]
openkey [HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\opsi-script-test\key3]
openkey [HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\opsi-script-test\key4]
Dann liefern uns:
set $list$ = getRegistryVarList32("hklm\software\opsi.org\opsi-script-test")
beziehungsweise
set $list$ = getRegistryVarList("hklm\software\opsi.org\opsi-script-test","32bit")
folgenden Log:
Registry started with redirection (32 Bit) The value of the variable "$list$" is now: (string 0)var1 (string 1)var2 (string 2)var3 (string 3)var4 (string 4)var5 (string 5)var6
Dann liefern uns:
set $list$ = getRegistryVarMap32("hklm\software\opsi.org\opsi-script-test")
beziehungsweise
set $list$ = getRegistryVarMap("hklm\software\opsi.org\opsi-script-test","32bit")
folgenden Log:
Registry started with redirection (32 Bit) The value of the variable "$list$" is now: (string 0)var1=value1 (string 1)var2=value2 (string 2)var3=value3 (string 3)var4=444 (string 4)var5=05 05 05 0F 10 (string 5)var6=value6
Dann liefern uns:
set $list$ = getRegistryKeyList32("hklm\software\opsi.org\opsi-script-test")
beziehungsweise
set $list$ = getRegistryKeyList("hklm\software\opsi.org\opsi-script-test","32bit")
folgenden Log:
Registry started with redirection (32 Bit) The value of the variable "$list$" is now: (string 1)key1 (string 2)key2 (string 3)key3 (string 4)key4
String-Listen aus Produkt Properties [W/L/M]
-
getProductPropertyList(
<propname>,<default value>`)` [W/L/M] // seit 4.11.3
Liefert eine Liste mit den aktiven Werten des multivalue Properties <propname>.
Die FunktionGetProductProperty
würde in diesem Fall die einzelnen Werte als einen kommaseparierten String zurückliefern. Dieses Vorgehen ist aber problematisch wenn Kommas auch in der Werten vorkommen.
Kann der aktuelle Wert des Properies nicht vom opsi-server ermittelt werden (z.B. weil das Skript nicht im Kontext des opsi-service läuft), so wird der zurückzugebende Wert wie folgt ermittelt:
Seit 4.12.4.32 wird zunächst geprüft ob sich im%ScriptPath%
eine Dateiproperties.conf
befindet. Wenn ja, wird versucht aus dieser Datei den Wert des Properties zu lesen. Dabei wird die Dateiproperties.conf
als Liste von key=value Paaren erwartet. Im Falle einer Stringliste wird hier ein Eintrag vom Muster<property name>=<list value>
erwartet. Beispiel:myproperty=["entry1","entry2","entry3"]
.
Wird die Dateiproperties.conf
nicht gefunden oder enthält den gesuchten Eintrag nicht, so wird der<default value>
zurückgegeben.
<default value>
kann beigetProductPropertyList
(seit 4.11.5.6) sowohl ein Stringausdruck sein, welcher das erste Element der einer Liste beschreibt, oder eine Liste.
Seit 4.12.4.32 kann die Liste auch als Zeichenkette angegeben werden. Beispiel'["ab","cd","de"]'
Die als<default value>
angebene Liste wird zurückgegeben, wenn der die aktuellen Werte des Servers nicht verfügbar sind.
Beispiel:
DefStringList $list$
;Property "dummymulti" has the values: ("ab", "cd", "ef", "g,h")
set $list$ = GetProductPropertyList ("dummymulti","True")
if not ("" = takeFirstStringContaining($list$,"g,h"))
comment "GetProductPropertyList passed"
else
set $TestResult$ = "not o.k."
LogWarning "GetProductPropertyList failed"
endif
set $ConstTest$ = "ab,cd,ef,g,h"
set $CompValue$ = GetProductProperty ("dummymulti","True")
if ($ConstTest$ = $CompValue$)
comment "GetProductProperty passed"
else
set $TestResult$ = "not o.k."
LogWarning "GetProductProperty failed"
endif
;;;;;;another Example to get a list as default-property
DefStringList $list$
DefStringList $propertyList$
Set $propertyList$ = createStringList('ab','cd','de')
Set $list$ = GetProductPropertyList ("dummymulti",$propertyList$)
;;;;;; since 4.12.4.32 also possible:
Set $list$ = GetProductPropertyList ("dummymulti",'["ab","cd","de"]')
Ab 4.12.4.32 ist bei Existenz der folgenden %ScriptPath%\properties.conf
:
propstr = from file proplist = ["from file",huhu"]
das folgende Skript ausserhalb des opsi-service Kontextes erfolgreich:
[Actions]
DefStringList $list$
DefVar $str$
set $str$ = GetProductProperty('propstr','')
if $str$ = "from file"
comment "got it"
else
comment "failed"
endif
set $list$ = GetProductPropertyList('proplist','')
if takeString(0,$list$) = "from file"
comment "got it"
else
comment "failed"
endif
siehe auch : [asConfidential_list]
Sonstige String-Listen [W/L/M]
-
getProfilesDirList
[W/L/M]
Liefert eine Liste der Pfade zu den lokalen Profilen.
[W] : Profile welche die folgenden Worte enthalten, werden nicht berücksichtigt: -
'localservice'
-
'networkservice'
-
'systemprofile'
Das Profil des 'Default Users' ist Bestandteil der Liste.
All User
oder Public
sind nicht Bestandteil der Liste.
[L] : Es werden die Heimatverzeichnisse der user mit einer UID >= 1000 geliefert, sofern das Verzeichnis auch existiert.
Beispiel:
set $list1$ = getProfilesDirList
ergibt folgenden Log:
Set $list1$ = getProfilesDirList Registry started with redirection (32 Bit) retrieving strings from getProfilesDirList [switch to loglevel 7 for debugging] (string 0)C:\Users\Administrator (string 1)C:\Users\Default
-
GetProcessList
//since 4.11.1.2; gives list of exename;pid;dom/user [W/L/M]
Liefert eine Liste der laufenden Prozesse.
Für jeden Prozess gibt es eine Zeile mit den folgenden ';' separierten Prozessinformationen:-
[W]: 'Prozess Name'. [L]: 'Kurzname des Prozesses'
-
[W/L/M]: 'PID'
-
[W]: 'Domain/User'. [L]: 'User'
-
[L]: 'Komplette Kommandozeile des laufenden Prozesses'
-
-
listFiles (<Pfad>, <Suchmaske>, <DurchsucheUnterordner>, [<Umleitung>]) : stringlist
[W/L/M]
Liefert eine Stringliste aller gefundenen Dateien im <Pfad> (z.B: "C:\Windows\system32") zurück, die der angegebenen <Suchmaske> (z.B: "*.dll") entsprechen. <Suchmaske> kann mehrere durch Semikolon getrennte Elemente enthalten.
Wird <DurchsucheUnterordner> auf "True" gesetzt werden bei der Suche auch die Unterverzeichnisse mit einbezogen. Ist der Wert "False" werden Unterordner nicht einbezogen.
[W] Das Setzen des optionalen Parameters <Umleitung> auf "64bit" oder "SysNative" durchsucht auch (System)ordner die ansonsten aufgrund von Umleitung von 32-bit Programmen auf 64-bit Systemen nicht durchsuchbar wären (nur 64bit Windows). Siehe hierzu auch 64 Bit-Unterstützung unter Windows [W]
Beispiel:
message "Test of function listFiles"
DefVar $Path$
DefStringList $Files$
Set $Path$ = "%System%"
Set $Files$ = listFiles($Path$,"*.Devices.*.dll","False")
ergibt folgenden Log:
message Test of function listFiles (created string list $Files$) Set $Path$ = "C:\Windows\system32" The value of the variable "$Path$" is now: "C:\Windows\system32" Set $Files$ = listFiles($Path$,"*.Devices.*.dll*","False") The value of the variable "$Files$" is now: (string 0)C:\Windows\system32\Windows.Devices.AllJoyn.dll (string 1)C:\Windows\system32\Windows.Devices.Background.dll (string 2)C:\Windows\system32\Windows.Devices.Background.ps.dll (string 3)C:\Windows\system32\Windows.Devices.Bluetooth.dll (string 4)C:\Windows\system32\Windows.Devices.Custom.dll (string 5)C:\Windows\system32\Windows.Devices.Custom.ps.dll (string 6)C:\Windows\system32\Windows.Devices.Enumeration.dll (string 7)C:\Windows\system32\Windows.Devices.Haptics.dll (string 8)C:\Windows\system32\Windows.Devices.HumanInterfaceDevice.dll (string 9)C:\Windows\system32\Windows.Devices.Lights.dll (string 10)C:\Windows\system32\Windows.Devices.LowLevel.dll (string 11)C:\Windows\system32\Windows.Devices.Midi.dll (string 12)C:\Windows\system32\Windows.Devices.Perception.dll (string 13)C:\Windows\system32\Windows.Devices.Picker.dll (string 14)C:\Windows\system32\Windows.Devices.PointOfService.dll (string 15)C:\Windows\system32\Windows.Devices.Portable.dll (string 16)C:\Windows\system32\Windows.Devices.Printers.dll (string 17)C:\Windows\system32\Windows.Devices.Printers.Extensions.dll (string 18)C:\Windows\system32\Windows.Devices.Radios.dll (string 19)C:\Windows\system32\Windows.Devices.Scanners.dll (string 20)C:\Windows\system32\Windows.Devices.Sensors.dll (string 21)C:\Windows\system32\Windows.Devices.SerialCommunication.dll (string 22)C:\Windows\system32\Windows.Devices.SmartCards.dll (string 23)C:\Windows\system32\Windows.Devices.SmartCards.Phone.dll (string 24)C:\Windows\system32\Windows.Devices.Usb.dll (string 25)C:\Windows\system32\Windows.Devices.WiFi.dll (string 26)C:\Windows\system32\Windows.Devices.WiFiDirect.dll (string 27)C:\Windows\system32\Windows.Internal.Devices.Sensors.dll
-
replaceOpsiConstants(
<string list>`) : stringlist` //since 4.12.3.6 [W/L/M]
Ersetzt alle Vorkommen von opsi Konstanten in '<string list>' durch ihre Werte und gibt die resultierende Stringliste zurück.
siehe auch : replaceOpsiConstants (string)
Transformation von String-Listen [W/L/M]
-
getSubList (
<Startindex> : <Endindex>, <list>)
[W/L/M]
Liefert eine Teilliste einer vorgegebenen Liste.
Funktion:
Wenn $list$ z.B. für die Liste der Buchstaben 'a', 'b', 'c', 'd', 'e' steht, so liefert
set $list1$ = getSubList(1 : 3, $list$)
'b', 'c', 'd' (Startindex und Endindex sind die Nummer des Listenelements, wenn mit 0 beginnend gezählt wird).
Defaultwert des Startindex ist 0, des Endindex der letzte Index der Liste.
Z.B. ergibt mit obiger Festlegung für $list$
set $list1$ = getSubList(1 : , $list$)
'b', 'c', 'd', 'e'.
set $list1$ = getSubList(:, $list$)
ist genau eine Kopie der ursprünglichen Liste.
Es besteht die Möglichkeit den Endindex mit Rückwärtszählung zu bestimmen:
set $list1$ = getSubList(1 : -1, $list$)
ist die Teilliste der Elemente vom 1. bis zum letzten Element der ursprünglichen Liste – im obigen Beispiel also wieder 'b', 'c', 'd','e'.
set $list1$ = getSubList(1 : -2, $list$)
ist die Teilliste der Elemente vom 1. bis zum vorletzten Element der ursprünglichen Liste – im obigen Beispiel also wieder 'b', 'c', 'd'.
Seit Version 4.12.0.35 können neben Zahlen auch Stringausdrücke verwendet werden, also Strings, Stringvariablen und Funktionen, welche einen String zurückliefern.
set $tmp1$ = "1"
set $tmp2$ = "3"
set $list1$ = getSubList( $tmp1$ : $tmp2$ , $list1$)
set $list2$ = createStringList("","-1","0","1","2","3","4","5","6",)
set $list1$ = getSubList(takestring(3,$list2$):takestring(5,$list2$), $list1$)
-
getListContaining(
<list>,<search string>`) : stringlist` [W/L/M]
Liefert eine Teilliste mit allen Strings, welche den <search string> enthalten.
-
getListContainingList(
<list1>,<list2>`) : stringlist` //since 4.11.3.7 [W/L/M]
Liefert die Schnittmenge von list1 und list2
-
getSubListByMatch (
<search string>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M]
Liefert eine Teilliste von <target list> mit allen Strings, welche mit dem <search string> identisch sind.
Die Überprüfung auf Gleichheit ist nicht Case Sensitive.
-
getSubListByMatch (
<search list>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M]
Liefert eine Teilliste von <target list> mit allen Strings, welche mit einem der Strings aus <search list> identisch sind.
Die Überprüfung auf Gleichheit ist nicht Case Sensitive.
-
getSubListByContaining (
<search string>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M]
Liefert eine Teilliste von <target list> mit allen Strings, in welchen <search string> vorkommt.
Die Überprüfung auf Gleichheit ist nicht Case Sensitive.
-
getSubListByContaining (
<search list>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M]
Liefert eine Teilliste von <target list> mit allen Strings, in denen einer der Strings aus <search list> vorkommt.
Die Überprüfung auf Gleichheit ist nicht Case Sensitive.
-
getSubListByKey (
<search string>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M]
Liefert eine Teilliste von <target list> mit allen Strings, welche mit '<search string>=' anfangen.
Die Überprüfung auf Gleichheit ist nicht Case Sensitive.
-
getSubListByKey (
<search list>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M]
Liefert eine Teilliste von der Key/Value Paar Liste <target list> mit allen Strings, deren Key in <search list> vorkommt.
Die Überprüfung auf Gleichheit ist nicht Case Sensitive.
-
getKeyList (
<list>`)` :stringlist //since 4.12.0.14 [W/L/M]
Liefert von einer Liste von Key/Value Paaren im Format Key=Value die Liste aller Keys. Ist ein Eintrag in <list> nicht im Format Key=Value, so wird der komplette String zurückgeliefert. -
takeFirstStringContaining(
<list>,<search string>`)` [W/L/M]
Liefert den ersten String von <list> welcher den <search string> enthält.
Liefert einen Leerstring wenn <search string> nicht gefunden wird.
siehe auch : [takeFirstStringContaining]
-
addtolist(
<list>,<string>`)` [W/L/M]
Hängt den String <string> an die Liste <list> an.
-
addlisttolist(
<list1>,<list2>`)` [W/L/M]
Hängt die Liste <list2> an die Liste <list1> an.
-
reverse (
<list>`)` [W/L/M]
kehrt die Reihenfolge der Aufzählung um – aus 'a', 'b', 'c', 'd', 'e' wird mit
set $list1$ = reverse ($list$)
also 'e', 'd', 'c', 'b', 'a'.
-
emptylist (
<list>`)` //since 4.11.3.7 [W/L/M]
Leert die Liste.
-
reencodestrlist(
<list>, <from>, <to>`)` //since 4.11.4.2 [W/L/M]
liefert die Stringliste <list> mit dem Encoding <to> zurück. Dabei wird davon ausgangen, dass <list> gemäß <from> encoded war. <from> und <to> sind dabei Encodings wie sie im Kapitel opsi-script encoding aufgelistet sind.
-
removeFromListByContaining(
<search string>`,` <target list>`) : stringlist` //since 4.11.5.1 [W/L/M]
Liefert eine Kopie von <target list> bei der alle Zeilen entfernt sind in denen <search string> vorkommt. Der Vergleich ist case insensitiv.
-
removeFromListByContaining(
<search list>`,` <target list>`) : stringlist` [W/L/M]
Liefert eine Kopie von <target list> bei der alle Zeilen entfernt sind in denen ein String aus <search list> vorkommt. Der Vergleich ist case insensitiv.
Beispiele:
File "%Scriptpath%\test-files\encoding\10lines.txt" is:
line 1 line 2 line 3 line 4 line 5 line 6 line 7 line 8 line 9 line 10
Code von opsi-script-test:
comment ""
comment "------------------------------"
comment "Testing: "
message "removeFromListByContaining"
set $string1$ = "%Scriptpath%\test-files\encoding\10lines.txt"
set $list1$ = loadTextFileWithEncoding($string1$, "cp1252")
comment "search with string"
comment "search with string constant"
set $ConstTest$ = "9"
set $list2$ = removeFromListByContaining("line 5", $list1$)
set $CompValue$ = count($list2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $ConstTest$ = "9"
set $list2$ = removeFromListByContaining("LINE 5", $list1$)
comment "the match is case insensitive"
set $CompValue$ = count($list2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $ConstTest$ = "0"
set $list2$ = removeFromListByContaining("line", $list1$)
set $CompValue$ = count($list2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $ConstTest$ = "8"
comment "searchstr 1 will found in 'line 1' and 'line 10'"
set $list2$ = removeFromListByContaining("1", $list1$)
set $CompValue$ = count($list2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
comment "search with string function"
set $ConstTest$ = "9"
set $list2$ = removeFromListByContaining(trim(" line 5 "), $list1$)
set $CompValue$ = count($list2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
comment "search with string variable"
set $string1$ = "line 5"
set $ConstTest$ = "9"
set $list2$ = removeFromListByContaining($string1$, $list1$)
set $CompValue$ = count($list2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
comment "search with string list"
comment "search with string list variable"
set $list3$ = createStringList ('1', '2', '3', '4', '5')
comment "searchstr 1 will found in 'line 1' and 'line 10'"
set $ConstTest$ = "4"
set $list2$ = removeFromListByContaining($list3$, $list1$)
set $CompValue$ = count($list2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
comment "search with string list variable"
comment "searchstr 1 will found in 'line 1' and 'line 10'"
set $ConstTest$ = "4"
set $list2$ = removeFromListByContaining(createStringList ('1', '2', '3', '4', '5'), $list1$)
set $CompValue$ = count($list2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
-
removeFromListByMatch(
<searchstring>,<target list>`) : stringlist` //since 4.11.6 [W/L/M]
Liefert eine Kopie von <target list> bei der alle Zeilen entfernt sind die gleich <search string> sind. Der Vergleich ist case insensitiv.
see also : [removeFromListByContaining_str]
see also : [removeFromListByContaining_list]
-
setStringInListAtIndex(
<newstring>,<list>,<indexstr>`) : stringlist` //since 4.11.6 [W/L/M]
Liefert eine Kopie von <list>, bei der der String an der Stelle <indexstr> durch <newstring> ersetzt ist. Wenn <indexstr> zu groß ist, wird <newstring> angehängt.
Im Fehlerfall ist das Ergebnis eine leere Liste.
see also : [takeString]
-
areListsEqual(<strlist1>, <strlist2>, <flag>) : boolean
Vergleicht die beiden Stringlisten <strlist1> und <strlist2> und gibt wahr (true) zurück wenn sie gleich sind. Dabei steuert der Parameter <flag> wie verglichen wird:
flag=FLAG_AUTOMODE
: case-insensitiver Vergleich. Die Stringlisten können Schlüssel/Wert-Stringlisten (Schlüssel1=Wert1) oder einfache Stringlisten sein
flag=FLAG_AUTO_CS
: case-sensitiver Vergleich. Die Stringlisten können Schlüssel/Wert-Stringlisten (Schlüssel1=Wert1) oder einfache Stringlisten sein
flag=FLAG_STRING_CS
: case-sensitiver Vergleich von einfachen Stringlisten (d.h. ein Schlüssel/Wert-Format wird nicht berücksichtigt).
Iteration durch String-Listen [W/L/M]
Eine besonders wichtige Anwendung von String-Listen beruht auf der Möglichkeit, die Elemente einer String-Liste zu durchlaufen und für jedes Element eine vorgegebenes Anweisungsschema auszuführen:
Die Syntax für eine solche Iteration („Wiederholungsanweisung“) lautet:
-
for
%s%in
<list>do
<eine Anweisung>
Dabei wird %s% durch diesen Ausdruck und nur für diese Stelle als String-Variable deklariert und ist danach wieder unbekannt. Innerhalb der Anweisung wird jedes Vorkommen von %s% (oder wie auch immer eine entsprechende Variable benannt ist) der Reihe nach durch die verschiedenen Elemente der Liste ersetzt.
Die Ersetzung ist (wie bei Systemkonstanten) rein textuell, d.h. genau die Zeichenfolge %s% wird z.B. durch die Werte a b c - ersetzt. Sind die Strings 'a','b','c' gemeint, muss in der auszuführenden Anweisung %s% von Anführungszeichen eingeschlossen sein. |
Ein Beispiel: Wenn $list1$ für 'a', 'b', 'c', 'd', 'e' steht und $line$ als String-Variable deklariert ist, so bedeutet:
for %s% in $list1$ do set $line$ = $line$ + "%s%"
der Reihe nach
$line$ = $line$ + "a"
$line$ = $line$ + "b"
$line$ = $line$ + "c"
$line$ = $line$ + "d"
$line$ = $line$ + "e"
so dass am Ende $line$ den Wert 'abcde' trägt. Wenn wir die einfachen Anführungszeichen um das %s% weglassen würden, bekämen wir bei jedem Schritt der Iteration einen Syntaxfehler gemeldet.
opsiservicecall und JSON Funktionen [W/L/M]
Diese Funktionen dienen dazu JSON Ausdrücke auf String oder Stringlisten zu analysieren
und zu modifizieren. Notwendig ist hierfür, die Struktur des zu bearbeitenden JSON-Ausdrucks zu kennen
und zu verstehen.
Diese Funktionen können auch hilfreich sein um opsiservicecall Sektionen zu verwenden.
-
jsonIsValid(
<jsonstr>`) : boolean` //since 4.11.6: [W/L/M]
Liefert 'true' zurück wenn, <jsonstr> einen gültigen JSON Ausdruck enthält.
-
jsonIsArray(
<jsonstr>`) : boolean` //since 4.11.6: [W/L/M]
Liefert 'true' zurück wenn, <jsonstr> ein gültiges JSON Array enthält.
-
jsonIsObject(
<jsonstr>`) : boolean` //since 4.11.6: [W/L/M]
Liefert 'true' zurück wenn, <jsonstr> ein gültiges JSON Object enthält.
-
jsonAsObjectHasKey(
<jsonstr>,<keystr>`) : boolean` //since 4.11.6: [W/L/M]
Liefert 'true' zurück wenn, <jsonstr> ein gültiges JSON Object welches <keystr> als key enthält.
Folgendes Beispiel würde 'true' zurückliefern:
jsonAsObjectHasKey('{"productVersion" : "4.4.1","packageVersion" : "2","productId" : "jedit"}','productId')
-
jsonAsArrayCountElements(
<jsonstr>`) : intstr` //since 4.11.6: [W/L/M]
Wenn <jsonstr> ein gültiges JSON Array enthält ist der Rückgabewert ein String mit der Zahl der Elemente des Arrays.
Im Fehlerfall = '"0"'
-
jsonAsObjectCountElements(
<jsonstr>`) : intstr` //since 4.11.6: [W/L/M]
Wenn <jsonstr> ein gültiges JSON Objkt enthält ist der Rückgabewert ein String mit der Zahl der Elemente des Objektes.
Im Fehlerfall = '"0"'
-
jsonAsArrayGetElementByIndex(
<jsonstr>, <indexstr>`) : jsonstring` //since 4.11.6: [W/L/M]
Liefert vom JSON Array <jsonstr> das Element mit dem Index <indexstr>
Der Index beginnt bei 0.
Im Fehlerfall = '""'
-
jsonAsObjectGetValueByKey(
<jsonstr>, <keystr>`) : valuestring` //since 4.11.6: [W/L/M]
Liefert vom JSON Object <jsonstr> den Wert des Key <keystr>
Im Fehlerfall = '""'
-
jsonAsObjectSetValueByKey(
<jsonstr>, <keystr>,<valuestring>`) : jsonstring` //since 4.11.6: [W/L/M]
Liefert einen String mit dem in <jsonstr> übergebenen JSON Object bei dem für den Key <keystr> der Wert <valuestring> gesetzt ist. Ist der Key nicht vorhanden, so wird er erzeugt.
Wenn <valuestring> als Stringwert erzeugt werden soll (also in doppelten Anführungszeichen), dann verwenden Sie besser die folgende Funktion: [jsonAsObjectSetStringtypeValueByKey].
Im Fehlerfall = '""'
-
jsonAsObjectSetStringtypeValueByKey(
<jsonstr>, <keystr>,<valuestring>`) : jsonstring` //since 4.11.6: [W/L/M]
Liefert einen String mit dem in <jsonstr> übergebenen JSON Object bei dem für den Key <keystr> der Wert <valuestring> als String (also in doppelten Anführungszeichen) gesetzt ist. Ist der Key nicht vorhanden, so wird er erzeugt.
Wenn <valuestring> nicht als Stringwert erzeugt werden soll , dann verwenden Sie besser die vorherige Funktion: [jsonAsObjectSetValueByKey].
Im Fehlerfall = '""'
-
jsonAsObjectDeleteByKey(
<jsonstr>, <keystr>`) : jsonstring` //since 4.11.6.4: [W/L/M]
Liefert einen String mit dem in <jsonstr> übergebenen JSON Object bei dem das key-value Paar mit dem Key <keystr> entfernt wurde.
-
jsonAsArrayPutObjectByIndex(
<jsonstr>, <indexstr>, <objectstr>`) : jsonstring` //since 4.11.6: [W/L/M]
Liefert einen String mit dem in <jsonstr> übergebenen JSON Array bei dem am Index <indexstr> das Object <objectstr> gesetzt ist.
Im Fehlerfall = '""'
-
jsonAsArrayDeleteObjectByIndex(
<jsonstr>, <indexstr>`) : jsonstring` //since 4.11.6.4: [W/L/M]
Liefert einen String mit dem in <jsonstr> übergebenen JSON Array bei dem das Objekt am Index <indexstr> entfernt wurde.
Im Fehlerfall = '""'
-
jsonAsArrayToStringList(
<jsonstr>`) : stringlist` //since 4.11.6: [W/L/M]
Liefert eine Stringliste mit dem in <jsonstr> übergebenen JSON Array als Stringliste mit einem Arrayelement pro Zeile.
-
jsonStringListToJsonArray(
<strlist>`) : jsonstr` //since 4.11.6: [W/L/M]
Liefert einen String mit einem JSON Array der die Zeilen der Stringliste <strlist> als Elemente enthält.
-
jsonAsObjectGetKeyList(
<jsonstr>`) : stringlist` //since 4.11.6: [W/L/M]
Liefert eine Stringliste mit den Keys der im JSON Object <jsonstr> vorhandnen Keys.
Beispiel:
Lese productOnClients Objekte aus einer Datei, ändere die clientId
auf den Wert der aktuellen Maschine und schreibe die Objekte über den opsi-webservice zurück.
DefVar $poc_file$
DefVar $objectStr$
DefVar $ArrayStr$
DefVar $pid$
DefStringlist $resultlist$
DefStringlist $resultlist1$
DefStringlist $productIdList$
DefStringlist $pocList$
Message "Delete productOnClient from opsi backend ..."
set $resultlist$ = getReturnListFromSection("opsiservicecall_getPOC")
Set $ArrayStr$ = takestring(0, $resultlist$)
if not(jsonIsValid($ArrayStr$))
LogError "got no valid json from Service"
isFatalError
endif
if not(jsonIsArray($ArrayStr$))
LogError "got no json Array from Service"
isFatalError
endif
comment "extract productIds ..."
comment "clean target list"
set $productIdList$ = emptylist($productIdList$)
comment "get stringlist "
set $pocList$ = jsonAsArrayToStringList($ArrayStr$)
for %aktpoc% in $pocList$ do sub_fill_product_ids
for %aktProductId% in $productIdList$ do opsiServiceCall_del_productOnClient
Message "Restore productOnClient from file ..."
comment " get Restore data from file ..."
Set $ArrayStr$ = strLoadTextFile($poc_file$)
if not(jsonIsValid($ArrayStr$))
LogError "got no valid json from file"
isFatalError
endif
if not(jsonIsArray($ArrayStr$))
LogError "got no json Array from file"
isFatalError
endif
comment "get list from array"
set $pocList$ = jsonAsArrayToStringList($ArrayStr$)
comment "loop over list"
for %pocindex% = "0" to calculate(count($pocList$)+"-1") do sub_set_clientid_in_poclist
comment "convert modified list to jason array"
set $ArrayStr$ = jsonStringListToJsonArray($pocList$)
set $ArrayStr$ = unquote2($ArrayStr$,"[]")
comment "write back"
opsiServiceCall_updatePOC
[sub_fill_product_ids]
set $objectstr$ = '%aktpoc%'
set $pid$ = jsonAsObjectGetValueByKey($objectstr$, "productId" )
set $productIdList$ = addToList($productIdList$,$pid$)
[sub_set_clientid_in_poclist]
set $objectStr$ = takeString("%pocindex%", $poclist$)
set $objectStr$ = jsonAsObjectSetStringtypeValueByKey(($objectStr$, "clientId","%opsiserviceUser%")
set $poclist$ = setStringInListAtIndex($objectStr$,$poclist$,"%pocindex%")
[opsiServiceCall_updatePOC]
"method": "productOnClient_updateObjects"
"params": [
'$ArrayStr$',
]
[opsiservicecall_getPOC]
"method": "productOnClient_getObjects"
"params":[
"[]",
'{"clientId":"%opsiserviceUser%","productType":"LocalbootProduct"}'
]
[opsiServiceCall_del_productOnClient]
"method": "productOnClient_delete"
"params": [
'%aktProductId%',
'%opsiserviceuser%',
]
Umgang mit Zahlen [W/L/M]
Es gibt im opsi-script keine speziellen Variablen für Zahlen. Es gibt allerdings einige Funktionen welche beim Umgang mit Zahlen helfen.
-
calculate(
<str>`)` [W/L/M]
Stringfunktion welch den arithmetischen Ausdruck im String <str> berechnet und als gerundeten integer string zurückgibt.
Intern werden die Berechnungen mit reellen Zahlen durchgeführt. Die Funktion kennt derzeit die Operatoren`, `-`, `*`, `/` sowie Klammern `(`,`)`. + Im Fehlerfall wird ein leerer String zurückgegeben und der Errorcounter um eins erhöht Enthält der übergebene String Zeichen die keine Zahlen oder gültige Operatoren sind, so ist dies ein Fehler. + Fehlt der zweite Operator, so wird hierfür der erste verwendet: 5 = 10 ; 5* = 25. Daher sollte beim Zusammensetzen des übergebenen strings verwendete Variablen z.B. mit der Funktion `isNumber
auf Gültigkeit geprüft werden.
Seit 4.11.3.5
siehe auch : [isNumber]
Beispiele:
set $ConstTest$ = "0"
set $CompValue$ = calculate("-1+1")
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $ConstTest$ = "1"
set $CompValue$ = calculate("0+1")
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $ConstTest$ = "-1"
set $CompValue$ = calculate("0-1")
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "5"
set $string2$ = "5"
set $ConstTest$ = "25"
set $CompValue$ = calculate($string1$+"*"+$string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "5"
set $string2$ = "5"
set $ConstTest$ = "1"
set $CompValue$ = calculate($string1$+"/"+$string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "5"
set $string2$ = "0"
set $ConstTest$ = ""
comment " expecting devision by zero error and empty string result"
set $CompValue$ = calculate($string1$+"/"+$string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "9"
set $string2$ = "10"
set $ConstTest$ = "1"
comment "result 0.9 is rounded to 1 "
set $CompValue$ = calculate($string1$+"/"+$string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "10"
set $string2$ = "9"
set $ConstTest$ = "1"
comment "result 1.1111 is rounded to 1 "
set $CompValue$ = calculate($string1$+"/"+$string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "5"
set $string2$ = "5"
set $ConstTest$ = "55"
comment " rule * before +"
set $CompValue$ = calculate($string1$+"+"+$string2$+"*10")
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "5"
set $string2$ = "5"
set $ConstTest$ = "100"
comment "brackets before rule * before + "
set $CompValue$ = calculate("("+$string1$+"+"+$string2$+")*10")
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "5"
set $string2$ = "ten"
set $ConstTest$ = ""
comment "invalid char error"
set $CompValue$ = calculate($string1$+"*"+$string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "5"
set $string2$ = ""
set $ConstTest$ = "25"
comment "5* is interpreted as 5*5"
set $CompValue$ = calculate($string1$+"*")
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "5"
set $string2$ = ""
set $ConstTest$ = "10"
comment "5+ is interpreted as 5+5"
set $CompValue$ = calculate($string1$+"+")
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "nothing"
set $string2$ = "foo"
set $ConstTest$ = ""
comment "invalid char error"
set $CompValue$ = calculate($string1$+"*"+$string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $string1$ = "5"
set $string2$ = "foo"
set $ConstTest$ = ""
comment "invalid char error"
set $CompValue$ = calculate($string1$+"/"+$string2$)
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
Für weitere Beispiele beachten Sie das Produkt 'opsi-script-test' und dort den Bereich '$Flag_calculate$ = "on"'
Es gibt einen Vergleichsausdruck um zwei Strings wie (integer) Zahlen zu vergleichen. Wenn einer der Werte nicht in eine Zahl übertragen werden kann, wird ein Fehler ausgegeben.
Diese Zahlenvergleichsausdrücke haben die gleich Form wie die String-Vergleichsausdrücke, allerdings wird dem dem Vergleichszeichen ein INT vorangestellt:
<STRINGAUSDRUCK> INT
<Vergleichszeichen> <STRINGAUSDRUCK>
So können Ausdrücke wie
if $Name1$ INT<= $Name2$
oder
if $Number1$ INT>= $Number2$
gebildet werden.
siehe auch: Boolesche Ausdrücke
-
isNumber(
<str>`)` [W/L/M]
Boolsche Funktion welche 'true' liefert wenn <str> einen ganzahligen Wert (integer) representiert.
Seit 4.11.3
see also : [calculate]
XML2 Funktionen [W/L/M]
Die XML2 Implementierung ist derzeit (4.2019 Version 4.12.1) neu. Das bedeutet das die Implementierung noch unvollständig ist. Daher werden sich bestimmt einige Dinge in den nächsten Releses hinzugefügt werden. Wenn Sie Probleme finden oder Featurewünsche haben, so scheuen Sie nicht uns zu kontaktieren. Diese neue 'XML2' Sektion und die 'XML2' Funktionen ersetzen die alte und nur für Windows verfügbare XMLPatch Sections. |
Für die in diesem Kapitel verwendeten Begrifflichkeiten (wording) lesen Sie bitte das Kapitel XML Struktur und Begriffe
XML Dateien sind in der Regel im encoding UTF-8 verfasst.
Dies wird von den 'XML2' Funktionen so vorausgesetzt.
Bei der XML2 Sektion gibt es die Möglichkeit auch andere Encodings anzugeben.
getXml2DocumentFromFile(
<path to xml file>`) : xml2stringlist` //since 4.12.1
Liest die in <path to xml file> gegebene xml Datei und liefert eine Stringliste zurück vom Format xml2stringlist welche in anderen xml2 Funktionen weiterverwendet werden kann.
Für Beispiele siehe 'XML2 Sektionen' / 'Beispiele' XML2 Beispiele
getXml2Document(
<stringlist with xml>`) : xml2stringlist` //since 4.12.1
Wenn die <stringlist with xml> gültiges xml enthält, so liefert die Funktion eine Stringliste zurück vom Format xml2stringlist welche in anderen xml2 Funktionen weiterverwendet werden kann.
xml2GetFirstChildNodeByName(
<xml2stringlist>, <node name str>`) : xml2stringlist` //since 4.12.1.
Sucht in der übergebenen <xml2stringlist> das erste Vorkommen eines node mit dem Namen <node name str> und liefert diesen node (mit allen child nodes) als xml2stringlist zurück.
Für Beispiele siehe 'XML2 Sektionen' / 'Beispiele' XML2 Beispiele
getXml2UniqueChildnodeByName(
<xml2stringlist>, <node name str>`) : xml2stringlist` //since 4.12.1.
Sucht in der übergebenen <xml2stringlist> nach Vorkommen eines node mit dem Namen <node name str> prüft ob dieser <node name str> nur einmal vorkommt und liefert diesen node (mit allen child nodes) als xml2stringlist zurück.
Wird kein Vorkommen oder mehrere gefunden, wird eine leere liste zurückgegeben.
getXml2AttributeValueByKey(
<xml2stringlist>, <attr name str>`) : string` //since 4.12.1.
Sucht in der übergebenen <xml2stringlist> den ersten node und in diesem node nach einem attribut mit dem Namen <attr name str> und liefert den Wert dieses Attributes als string zurück.
Wenn das Attribute nicht gefunden wird oder bei einem anderen Fehler wird ein leerer String zurückgeliefert.
Für Beispiele siehe 'XML2 Sektionen' / 'Beispiele' XML2 Beispiele
getXml2Text(
<xml2stringlist>`) : string` //since 4.12.1.
Liefert die als <xml2stringlist> übergebenen xml Daten als einzeilen String zurück.
siehe auch : XML related functions (XML2)
siehe auch : XML2 Sektion
Funktionen um TOML Dateien zu bearbeiten [W/L/M]
Ab opsi-script v. 4.12.5 unterstützt opsi-script die Handhabung von TOML-Dateien.
opsi-script unterstützt derzeit nicht die Behandlung von Kommentaren innerhalb von TOML-Dateien. Beim Einfügen von Daten in Tabellen/Bereichen mit Kommentaren gehen diese evtl. verloren. |
Die offiziellen TOML-Spezifikationen finden sie unter https://toml.io/en/ |
TOML-Dateien sind normalerweise in UTF-8 codiert. Die 'TOML'-Funktionen erwarten also, dass die angegebenen TOML-Dateien in UTF-8 vorliegen.
Ein vollständiges Beispiel-Skript mit allen TOML-Funktionen ist weiter unten zu finden.
-
LoadTOMLFile(
<TOMLfilePath: String>`) : StringList` //seit 4.12.5.0
Liest die TOML-Datei <TOMLfilePath> ein und gibt den Dateiinhalt als Stringliste zurück.
-
ReadTOMLFile(
<TOMLfilePath: String>`) : String` //seit 4.12.5.0
Liest die TOML-Datei <TOML-Dateipfad> ein und gibt den Dateiinhalt als String zurück.
Dieser String wird zum Manipulieren von TOML-Dateien in den kommenden Funktionen verwendet.
Bitte beachten Sie, dass diese Funktion keine Kommentare speichert. |
-
GetTOMLAsStringList(
<TOMLcontents: String>`) : StringList` //seit 4.12.5.0
Parst den TOML-String-Inhalt <TOMLcontents> und gibt eine Stringliste des geparsten TOML-Inhalts zurück.
-
GetTOMLAsString(
<TOMLcontents: String>`) : String` //seit 4.12.5.0
Parst den TOML-String-Inhalt <TOMLcontents> und gibt einen String des geparsten TOML-Inhalts zurück.
-
GetTOMLKeys(
<TOMLcontents: String>`) : StringList` //seit 4.12.5.0
Sucht im angegebenen <TOMLcontents>-String nach allen Keys und gibt eine StringListe der gefundenen Keys zurück.
Wenn kein Key gefunden wird, wird eine leere Stringliste zurückgegeben.
Diese Funktion gibt nur die Keys des angegebenen Strings zurück, die als root tabelle analysiert wurden, einschließlich der Namen ihrer Untertabellen. Sie enthält nicht die Keys irgendeiner Untertabelle. |
-
GetTOMLTableNames(
<TOMLcontents: String>`) : StringList` //seit 4.12.5.0
Sucht in der angegebenen <TOMLcontents>-String nach allen Tabellen der Stammtabelle und gibt eine Stringliste mit den Namen der gefundenen Tabellen zurück.
Wenn keine Tabelle gefunden wird, wird eine leere Stringliste zurückgegeben.
-
GetTOMLTable(
<TOMLcontents: String> , <table name : String>`) : StringList` //seit 4.12.5.0
Sucht in den angegebenen <TOMLcontents>-String nach einer Tabelle mit dem angegebenen <table name> und gibt eine Stringliste des gefundenen Tabelleninhalts zurück.
-
GetTOMLTableAsString(
<TOMLcontents: String> , <table name : String>`) : String` //seit 4.12.5.0.
Sucht in den angegebenen <TOMLcontents>-String nach einer Tabelle mit dem angegebenen <table name> und gibt einen String des gefundenen Tabelleninhalts zurück.
-
GetValueFromTOML(
<TOMLcontents: String> , <keyPath: String> , <defaultValue: String>`) : String` //seit 4.12.5.0
Sucht in der angegebenen <TOMLcontents>-String nach dem Key, der mit <keyPath> definiert ist, also:-
Ein einfacher Key, wenn sich der Key in der Stammtabelle befindet.
-
Ein zusammengesetzter Key-Path: Abfolge der Tabellennamen, die das gesuchte Key-Value-Paar enthalten. Zum Beispiel: "Tabelle.Untertabelle.Key"
und gibt einen String mit dem entsprechenden Value zurück, falls gefunden.
-
Wenn der angegebene Key nicht gefunden wird oder der angegebene Key-Path falsch oder unvollständig ist oder kein Value gefunden wurde, wird die Eingabezeichenfolge <defaultValue> zurückgegeben.
Diese Funktion gibt den genauen Value als String-Ausgabe zurück. Wenn also beispielsweise der gesuchte Value ein String mit dem Inhalt "opsi" ist, dann ist das Ergebnis dieser Funktion: '"opsi"' |
-
ModifyTOML(
<TOMLcontents: String> , <command: String> , <keyPath: String> , <value: String>`) : String` //seit 4.12.5.0
Diese Funktion ermöglicht es, den als Eingabe angegebenen <TOMLcontents>-String mithilfe von 4 Befehlen zu ändern:-
'ADD' : Fügt das Eingabepaar <keyPath>-<value> hinzu, wenn der Key nicht existiert. Es gibt einen neuen modifizierten TOMLcontens-String zurück.
Wenn der <keyPath> existiert, nimmt diese Funktion keine Änderungen vor. Derselbe Eingabe-String <TOMLcontents> wird zurückgegeben. -
'SET' : Legt ein neues <keyPath>-<value>-Paar fest, unabhängig davon ob der Key existiert oder nicht. Mit <Value> wird der entsprechende Value geändert.
Die Funktion gibt den neuen modifizierten TOMLcontens-String zurück. -
'CHANGE ' : Ändert den entsprechenden Value im <keyPath> auf den angegebenen <value>. Es gibt einen neuen modifizierten TOMLcontens-String zurück.
Wenn der KeyPath/Key nicht existiert, wird nichts getan. Derselbe Eingabe-String <TOMLcontents> wird zurückgegeben. -
'DEL' : Löscht den <keyPath> und den dazugehörigen Value. Es gibt einen neuen modifizierten TOMLcontens-String zurück.
Wenn der keyPath nicht existiert, wird nichts getan. Derselbe Eingabe-String <TOMLcontents> wird zurückgegeben.
-
Wenn eine Behandlungsausnahme auftritt, wird der selbe Eingabe-<TOMLcontents>-String zurückgegeben.
Wenn ein Fehler auftritt, wird ein leerer String zurückgegeben.
Beachten Sie, dass beim Hinzufügen von Werten die TOML-Notation innerhalb des Eingabe-String-Parameters gemäß der offiziellen Spezifikation berücksichtigt werden muss (siehe https://toml.io/en/). |
Zum Beispiel:
-
Wenn Sie einen Value vom Typ String mit dem Inhalt "Neuer Wert" hinzufügen möchten, sollte er wie folgt zwischen doppelten Anführungszeichen geschrieben werden:
<Value> = ' "Neuer Value" ' -
Wenn Sie einen Value vom Typ Boolean mit dem Inhalt True hinzufügen möchten, sollte er wie folgt geschrieben werden:
<Value> = 'True' -
Wenn Sie einen Value vom Typ Zahl mit dem Inhalt 1.1 hinzufügen möchten (Floats werden mit einem . geschrieben, nicht mit einem , ), sollte er wie folgt geschrieben werden:
<Value> = ' 1.1 ' -
Wenn Sie einen Value vom Typ Array mit dem Inhalt ["erster Value", "zweiter Value"] hinzufügen möchten, sollte er wie folgt geschrieben werden:
<Value> = ' ["erster Value", "zweiter Value"] ' -
Wenn Sie einen Datumstypwert mit dem Inhalt 2022-02-02T16:16:00Z-16:16 hinzufügen möchten, sollte er wie folgt geschrieben werden:
<Value> = ' 2022-02-02T16:16:00Z-16:16 '
Alle Beispiele sind im Skript-Beispiel weiter unten enthalten.
-
DeleteTableFromTOML(
<TOMLcontents: String> , <tablePath: String>`) : String` //seit 4.12.5.0
Löscht den gesamten angegebenen <tablePath> mit seinen Key-Value-Paaren und Untertabellen, sofern vorhanden, aus dem angegebenen <TOMLcontents>-String.
Wenn der angegebene <tablePath> nicht gefunden wird, werden keine Änderungen vorgenommen und derselbe Eingabe-String <TOMLcontents> wird zurückgegeben.
-
SaveToTOMLFile(
<TOMLcontents: String> , <TOML file Path: String>`) : boolean` //seit 4.12.5.0
Speichert den <TOMLcontents>-String im TOML-Format im angegebenen <TOML file path>.
Läuft das Speichern der Datei fehlerfrei, wird „True“ zurückgegeben.
Wenn Fehler auftreten, wird "False" zurückgegeben.
-
ConvertTOMLtoJSON(
<TOMLcontents: String>`) : String` //seit 4.12.5
Konvertiert den angegebenen <TOMLcontents> String in einen JSON-formatierten String.
-
ConvertTOMLfileToJSONfile(
<TOMLfilePath: String> , <JSONfilePath: String>`) : boolean` //seit 4.12.5.0
Diese Funktion konvertiert den Inhalt der angegebenen TOML-Datei <TOMLfilePath> in einen JSON-String und speichert ihn unter dem angegbenen <JSONfilePath>.
Läuft das Speichern der Datei fehlerfrei, wird „True“ zurückgegeben.
Wenn Fehler auftreten, wird "False" zurückgegeben.
Beispiel:
Datei "TOMLfile.toml" ist:
# This is a TOML document. title = "TOML Example" [owner] name = "Tom Preston-Werner" dob = 1979-05-27T07:32:00-08:00 [database] server = "192.168.1.1" ports = [ 8000, 8001, 8002 ] connection_max = 5000 enabled = true [servers] [servers.alpha] ip = "10.0.0.1" dc = "eqdc10" [servers.beta] ip = "10.0.0.2" dc = "eqdc10" [clients] data = [ ["gamma", "delta"], [1, 2] ] hosts = [ "alpha", "omega" ]
comment "Testing TOML functions"
DefVar $TOMLFile$
DefVar $TOMLString$
DefStringList $TOMLlist$
DefVar $TOMLdata$
Set $TOMLFile$ = $HomeTestFiles$ + "TOMLfile.toml"
Set $TOMLlist$ = LoadTOMLFile($TOMLFile$)
Set $TOMLString$ = ReadTOMLFile($TOMLFile$)
Set $TOMLlist$ = GetTOMLKeys($TOMLString$)
Set $TOMLlist$ = GetTOMLTableNames($TOMLString$)
Set $TOMLlist$ = GetTOMLTable($TOMLString$, "owner")
Set $TOMLdata$ = GetTOMLTableAsString($TOMLString$, "owner")
Set $TOMLdata$ = GetTOMLTableAsString($TOMLString$, "servers")
Set $TOMLlist$ = GetTOMLTableNames($TOMLdata$)
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "" , "defaultValue" )
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , " " , "defaultValue" )
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "key" , "defaultValue" )
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "title" , "defaultValue" )
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "owner.name" , "defaultValue")
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "servers.alpha.ip" , "defaultValue")
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "servers.beta.key" , "defaultValue" )
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "clients.data " , "defaultValue" )
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "database.ports" , "defaultValue" )
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "database.connection_max" , "defaultValue")
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "database.enabled" , "defaultValue")
Set $TOMLdata$ = GetValueFromTOML( $TOMLString$ , "servers.beta" , "defaultValue")
Set $TOMLString$ = ModifyTOML($TOMLString$, 'ADD', 'title', '"newADDvalueInRootTable"')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'ADD', 'newADDkeyInRootTable', '"newADDvalueInRootTable"')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'ADD', 'servers.alpha.a.newADDkeyInAlphaA', '"newADDvalueInAlphaA"')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'ADD', 'newTable.newADDtableKey', '"newADDtableValue"')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'ADD', 'newTable.newStringKey', '"newStringValue"')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'ADD', 'newTable.newIntegerKey', '1')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'ADD', 'newTable.newFloatKey', '10.1')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'ADD', 'newTable.newDateKey', '2022-02-02T16:16:00Z-16:16')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'ADD', 'newTable.newArray', '[ "a", "b", "c" ]')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'SET',' newADDkeyInRootTable', '"newSETValueInRootTable"')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'SET', 'newSETkeyInRootTable', '"newSETValueInRootTable"')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'SET', 'servers.alpha.a.newADDkeyInAlphaA', '"newSETValueInAlphaA"')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'SET', 'newTable.newADDtableKey', '"newSETtableValue"'
Set $TOMLString$ = ModifyTOML($TOMLString$, 'CHANGE', 'newCHANGEkeyInRootTable', ' "newCHANGEValueInRootTable" ')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'CHANGE', 'newSETkeyInRootTable', '"newCHANGEValueInRootTable"')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'CHANGE', 'servers.alpha.a.newADDkeyInAlphaA', '"newCHANGEValueInAlphaA"')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'CHANGE', 'newCHANGETable.newCHANGEtableKey', ' "newCHANGEtableValue" '
Set $TOMLString$ = ModifyTOML($TOMLString$, 'DEL', 'newSETkeyInRootTable', '')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'DEL', 'DELkeyInRootTable', '')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'DEL', 'servers.alpha.a.newADDkeyInAlphaA', '')
Set $TOMLString$ = ModifyTOML($TOMLString$, 'DEL', 'DELTable.DELtableKey', '')
Set $TOMLString$ = DeleteTableFromTOML($TOMLString$, "newTable")
Set $newTOMLFile$ = $HomeTestFiles$ + "TOMLempty.toml"
Set $TestString$ = booltostring(SaveToTOMLFile($TOMLString$,$newTOMLFile$))
Set $newJSONFile$ = $HomeTestFiles$ + "myJSONfromTOMLdata.json"
set $TestString$ = booltostring(ConvertTOMLfileToJSONfile($newTOMLFile$,$newJSONFile$))
Nach ausführen des Skriptes sieht die TOML-Datei folgendermaßen aus:
# This is a TOML document. title = "TOML Example" newADDkeyInRootTable = "newSETValueInRootTable" [owner] name = "Tom Preston-Werner" dob = 1979-05-27T07:32:00Z-07:32 [database] server = "192.168.1.1" ports = [ 8000, 8001, 8002 ] connection_max = 5000 enabled = true [servers] [servers.alpha] ip = "10.0.0.1" dc = "eqdc10" [servers.alpha.a] [servers.beta] ip = "10.0.0.2" dc = "eqdc10" [clients] data = [ [ "gamma", "delta" ], [ 1, 2 ] ] hosts = [ "alpha", "omega" ]
Regular expression related functions [W/L/M]
Das Arbeiten mit 'regular expressions' hat einige Nachteile: Das herausfinden der richtigen 'regular expression' kann eine schwierige Aufgabe sein. Also verwenden Sie Werkzeuge zum Testen Ihrer 'regular expressions'. Die Verwendung von 'regular expressions' führt schnell zu unverständlichen Code, da einer 'regular expression' nicht auf dem aller ersten Blick anzusehen ist was sie macht. Also erläutern Sie in Kommentaren in Ihrem Code was die 'regular expressions' tun sollen. |
Es gibt unterschiedliche Varianten von 'regular expressions': Perl, Javascript, Java, …
Die hier implementierte Variante ist eine Variante von perl style
or PCRE
.
Eine Dokumentation der hier implementierten Variante finden Sie hier:
https://regex.sorokin.engineer/de/latest/regular_expressions.html
Verwenden Sie ein Werkzeug zum Testen Ihrer 'regular expressions'. Wir empfehlen Ihnen die 'opsi-regexpr-tester.exe' Anwendung, welche Sie hier herunterladen können: https://download.uib.de/opsi4.2/misc/helper/opsiRegExprTest.exe |
-
opsi-regexpr-tester.exe
Diese Anwendung (opsi-regexpr-tester.exe) hilft Ihnen Ihre Regular Expression zu testen.
Das Anwendungsfenster von 'opsi-regexpr-tester' bietet Ihnen zwei Felder:
Im ersten Feld ('Regular Expression :') tragen Sie Ihre Regular Expression ein.
Im zweiten Feld ('Text :') Tragen Sie den Text ein, gegen den die Regular Expression getestet werden soll.
Darüberhinaus können Sie noch 'Pattern Modifiers Flags' angeben,
welche die Auswertung der Regular Expression beeinflussen.
Details dazu finden Sie in der erwähnten Dokumentation:
https://regex.sorokin.engineer/en/latest/regular_expressions.html
Angeboten werden 6 Flags :
-
i, case-insensitive (Groß- / Kleinschreibung ignorieren)
-
m, multi-line strings
-
s, single line strings
-
g, greediness (Gierigkeit)
-
x, eXtended syntax
-
r, Russian ranges
Sie können durch anklicken der entsprechenden Checkboxen diese Flags aktivieren.
Die Flags werden dann am Anfang der Regular Expression hinzugefügt.
Die Flags müssen vor dem Abschnitt stehen für den sie gelten sollen.
Durch drücken des Buttons 'Examine' können Sie nun Ihre Regular Expression testen.
Wenn die Regular Expression zu dem Text (oder teilen davon) passt, so werden die passenden Teile grün markiert und 'successful' angezeigt.
Wenn die Regular Expression zu keinem Textteil passt, so wird ein Fehler angezeigt.
Über den Button 'clear' können die Eingabefelder gelöscht werden.
-
isRegexMatch(
<string>, <pattern>`) : boolean`
Hierbei ist <pattern> eine 'regular expression' und <string> der zu prüfende String. Die Funktion liefert 'true' zurück wenn <pattern> zu dem <string> passt ('matched') und 'false' wenn es kein 'match' gibt.
Beispiel:
comment "Testing with matching string"
set $ConstTest$ = "true"
set $CompValue$ = booltostring(isRegexMatch('abc efg', '.*abc.*'))
if ($ConstTest$ = $CompValue$)
comment "isRegexMatch passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing isRegexMatch failed"
endif
comment "Testing with non matching string"
set $ConstTest$ = "false"
set $CompValue$ = booltostring(isRegexMatch('abc efg', '.*xyz.*'))
if ($ConstTest$ = $CompValue$)
comment "isRegexMatch passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing isRegexMatch failed"
endif
-
getSubListByContainingRegex(
<pattern>, <target list>`) : stringlist`
Liefert eine Stringliste zurück welche die Strings aus <target list> enthalten bei denen zumindest ein Teil mit <pattern> matched. -
getSubListByContainingRegex('<pattern list>, <target list>') : stringlist
Liefert eine Stringliste zurück welche die Strings aus <target list> enthalten bei denen zumindest ein Teil mit einem pattern aus <pattern list> matched.
Beispiel:
comment "Testing with a single pattern"
set $string1$ = "\w+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,6}"
set $list1$ = createStringList('uib gmbh','example@xyz.com and example2@xyz.com', 'client')
set $ConstTest$ = "example@xyz.com and example2@xyz.com"
set $list2$ = getSubListByContainingRegex($string1$, $list1$)
set $CompValue$ = composeString ($list2$, " | ")
if ($ConstTest$ = $CompValue$)
comment "getSubListByContainingRegex passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing getSubListByContainingRegex failed"
endif
comment "Testing with a list of patterns"
set $list3$ = createStringList('\w+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,6}','.*uib')
set $ConstTest$ = "uib gmbh | example@xyz.com and example2@xyz.com"
set $list2$ = getSubListByContainingRegex($list3$, $list1$)
set $CompValue$ = composeString ($list2$, " | ")
if ($ConstTest$ = $CompValue$)
comment "getSubListByContainingRegex passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing getSubListByContainingRegex failed"
endif
-
getRegexMatchList(
<pattern>, <target list>`) : stringlist`
Liefert eine Stringliste zurück welche die Strings aus <target list> enthalten welche vollständig mit <pattern> matchen. -
getRegexMatchList(<pattern list>, <target list>) : stringlist
Liefert eine Stringliste zurück welche die Strings aus <target list> enthalten welche vollständig mit einem pattern aus <pattern list> matchen.
Beispiel:
comment "Testing with a single pattern"
set $string1$ = "\w+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,6}"
set $list1$ = createStringList('uib gmbh','client','example@xyz.com and example2@xyz.com')
set $ConstTest$ = "example@xyz.com | example2@xyz.com"
set $list2$ = getRegexMatchList($string1$, $list1$)
set $CompValue$ = composeString ($list2$, " | ")
if ($ConstTest$ = $CompValue$)
comment "getRegexMatchList passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing getRegexMatchList failed"
endif
comment "Testing with a list of patterns"
set $list3$ = createStringList('\w+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,6}','.*uib')
set $ConstTest$ = "uib | example@xyz.com | example2@xyz.com"
set $list2$ = getRegexMatchList($list3$, $list1$)
set $CompValue$ = composeString ($list2$, " | ")
if ($ConstTest$ = $CompValue$)
comment "getRegexMatchList passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing getRegexMatchList failed"
endif
-
removeFromListByContainingRegex(
<pattern>, <target list>`) : stringlist`
Liefert eine Stringliste bei der die Strings aus <target list> entfernt worden sind, welche ganz oder zum Teil mit <pattern> matchen. -
removeFromListByContainingRegex(
<pattern list>, <target list>`) : stringlist`
Liefert eine Stringliste bei der die Strings aus <target list> entfernt worden sind, welche ganz oder zum Teil mit pattern aus <pattern list> matchen.
Beispiel:
comment "Searching with a single expression"
set $string1$ = "\w+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,6}"
set $list1$ = createStringList('uib gmbh','client','example@xyz.com and example2@xyz.com')
set $ConstTest$ = "uib gmbh | client"
set $list2$ = removeFromListByContainingRegex($string1$, $list1$)
set $CompValue$ = composeString ($list2$, " | ")
if ($ConstTest$ = $CompValue$)
comment "removeFromListByContainingRegex passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing removeFromListByContainingRegex failed"
endif
comment "Searching with a list of expressions"
set $list3$ = createStringList('\w+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,6}','.*uib')
set $ConstTest$ = "client"
set $list2$ = removeFromListByContainingRegex($list3$, $list1$)
set $CompValue$ = composeString ($list2$, " | ")
if ($ConstTest$ = $CompValue$)
comment "removeFromListByContainingRegex passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing removeFromListByContainingRegex failed"
endif
-
stringReplaceRegex(
<string>, <pattern>, <replacement string>`) : string`
Liefert einen String bei dem die matches von <pattern> in <string> durch <replacement string> ersetzt worden sind.
Example:
set $ConstTest$ = "xyz abc gmbh"
set $CompValue$ = stringReplaceRegex('uib gmbh','.*uib', 'xyz abc')
if ($ConstTest$ = $CompValue$)
comment "stringReplaceRegex passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing stringReplaceRegex failed"
endif
-
stringReplaceRegexInList
<target list>, <pattern>, <replacement string>`) : stringlist`
Liefert eine Stringliste bei dem die matches von <pattern> in einem String von <target list> durch <replacement string> ersetzt worden sind.
Example:
set $string1$ = "\w+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,6}"
set $string2$ = "MATCH REMOVED"
set $list1$ = createStringList('uib gmbh','client','example@xyz.com and example2@xyz.com')
set $ConstTest$ = 'uib gmbh | client | MATCH REMOVED and MATCH REMOVED'
set $list2$ = stringReplaceRegexInList($list1$, $string1$, $string2$)
set $CompValue$ = composeString ($list2$, " | ")
if ($ConstTest$ = $CompValue$)
comment "stringReplaceRegexInList passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing stringReplaceRegexInList failed"
endif
Für weiter Beispiele schauen Sie im Produkt 'opsi-script-test' und dort speziell in der Datei sub-scripts/regex.opsiscript
.
URL Functionen [W/L/M]
Diese Funktionen dienen zur analyse und zur Erzeugung von URL’s.
Sie zerlegen eine Url in eine Stringliste mit den URL Komponeten:
Beispiel:
'Protocol=proto' 'Username=usr' 'Password=pwd' 'Host=host' 'Port=8080' 'Path=/path/' 'Document=doc' 'Params=param' 'Bookmark=bookmark'
-
parseUrl(
<url string>`) : stringlist`
Liefert die aus der Zerlegung der URL <url string> entstandene Stringliste.
Beispiel:
comment "Testing parseUrl with all fields"
set $string1$ = "proto://usr:pwd@host:8080/path/doc?param#bookmark"
set $list1$ = createStringList('Protocol=proto','Username=usr','Password=pwd', 'Host=host', 'Port=8080', 'Path=/path/', 'Document=doc', 'Params=param', 'Bookmark=bookmark')
set $ConstTest$ = composeString ($list1$, " | ")
set $list2$ = parseUrl($string1$)
set $CompValue$ = composeString ($list2$, " | ")
if ($ConstTest$ = $CompValue$)
comment "parseUrl passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing parseUrl failed"
endif
comment "Testing parseUrl with some fields"
set $string1$ = "ftp://example.abc.edu/"
set $list1$ = createStringList('Protocol=ftp','Username=','Password=', 'Host=example.abc.edu', 'Port=0', 'Path=/', 'Document=', 'Params=', 'Bookmark=')
set $ConstTest$ = composeString ($list1$, " | ")
set $list2$ = parseUrl($string1$)
set $CompValue$ = composeString ($list2$, " | ")
if ($ConstTest$ = $CompValue$)
comment "parseUrl passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing parseUrl failed"
endif
-
createUrl(
<urlcomponents list>`) : string`
Liefert eine URL aus den Komponenten der übergebenen <urlcomponents list>. Dabei muss <urlcomponents list> nicht vollständig sein: leere Teile können weggelassen werden.
Beispiel:
comment "Testing createUrl with all fields"
set $list1$ = createStringList('Protocol=proto','Username=usr','Password=pwd', 'Host=host', 'Port=8080', 'Path=/path/', 'Document=doc', 'Params=param', 'Bookmark=bookmark')
set $ConstTest$ = "proto://usr:pwd@host:8080/path/doc?param#bookmark"
set $CompValue$ = createUrl($list1$)
if ($ConstTest$ = $CompValue$)
comment "createUrl passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing createUrl failed"
endif
comment "Testing createUrl with some fields"
set $list1$ = createStringList('Protocol=https','Host=www.example.com', 'Path=/b-c-d-330002341216/')
set $ConstTest$ = "https://www.example.com/b-c-d-330002341216/"
set $CompValue$ = createUrl($list1$)
if ($ConstTest$ = $CompValue$)
comment "createUrl passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing createUrl failed"
endif
Für weiter Beispiele schauen Sie im Produkt 'opsi-script-test' und dort speziell in der Datei sub-scripts/urlparser.opsiscript
.
Netzwerknummern Funktionen [W/L/M]
-
isValidIP4 (
<ip4adr>`) : boolean`
Liefert 'true' wenn <ip4adr> eine gültige IPv4 Adresse ist (Host,Netz, Maske).
Beispiel:
comment "Testing with valid IPv4 address"
set $ConstTest$ = "true"
set $CompValue$ = booltostring(isValidIP4("255.255.0.0"))
if ($ConstTest$ = $CompValue$)
comment "isValidIP4 passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing isValidIP4 failed"
endif
comment "Testing with invalid IPv4 address"
set $ConstTest$ = "false"
set $CompValue$ = booltostring(isValidIP4("255.256.0.0"))
if ($ConstTest$ = $CompValue$)
comment "isValidIP4 passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing isValidIP4 failed"
endif
-
isValidIP4Network (
<ip4adr>, <netmask>`) : boolean`
Liefert 'true' wenn <ip4adr> zusammen mit <netmask> eine gültige IPv4 Netzwerkadresse ist.
Dabei kann <netmask> in der CIDR oder der punktseparierten Dezimal Notation angegeben werden.
Beispiel:
comment "Testing with valid network address, where netmask is in cidr notation"
set $ConstTest$ = "true"
set $CompValue$ = booltostring(isValidIP4Network('192.168.0.0','24'))
if ($ConstTest$ = $CompValue$)
comment "isValidIP4Network passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing isValidIP4Network failed"
endif
comment "Testing with valid network address, where netmask is in dotted-decimal notation"
set $ConstTest$ = "true"
set $CompValue$ = booltostring(isValidIP4Network('192.168.0.0','255.255.255.0'))
if ($ConstTest$ = $CompValue$)
comment "isValidIP4Network passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing isValidIP4Network failed"
endif
comment "Testing with invalid network address"
set $ConstTest$ = "false"
set $CompValue$ = booltostring(isValidIP4Network('198.51.100.223','21'))
if ($ConstTest$ = $CompValue$)
comment "isValidIP4Network passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing isValidIP4Network failed"
endif
-
isValidIP4Host (
<ip4adr>, <netmask>`) : boolean`
Liefert 'true' wenn <ip4adr> eine gültige Hostadresse ist, welche in dem per <netmask> angegebenen Subnetz liegt. Dabei kann <netmask> in der CIDR oder der punktseparierten Dezimal Notation angegeben werden.
Beispiel:
comment "Testing with valid host address, where netmask is in dotted-decimal notation"
set $ConstTest$ = "true"
set $CompValue$ = booltostring(isValidIP4Host('198.51.104.254', '255.255.248.0'))
if ($ConstTest$ = $CompValue$)
comment "isValidIP4Host passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing isValidIP4Host failed"
endif
comment "Testing with valid host address, where netmask is in cidr notation"
set $ConstTest$ = "true"
set $CompValue$ = booltostring(isValidIP4Host('198.51.104.254', '21'))
if ($ConstTest$ = $CompValue$)
comment "isValidIP4Host passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing isValidIP4Host failed"
endif
comment "Testing with invalid host address"
set $ConstTest$ = "false"
set $CompValue$ = booltostring(isValidIP4Host('198.51.104.0', '21'))
if ($ConstTest$ = $CompValue$)
comment "isValidIP4Host passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing isValidIP4Host failed"
endif
-
getIP4NetworkByAdrAndMask (<ip4adr>, <netmask>) : string
Liefert einen String mit der Netzwerkadresse basierend auf der Hostadresse <ip4adr> und der Netzmaske <netmask>. Dabei kann <netmask> in der CIDR oder der punktseparierten Dezimal Notation angegeben werden.
Beispiel:
comment "Testing with netmask in cidr notation "
set $ConstTest$ = "198.48.0.0"
set $CompValue$ = getIP4NetworkByAdrAndMask('198.51.100.223', '12')
if ($ConstTest$ = $CompValue$)
comment "getIP4NetworkByAdrAndMask passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing getIP4NetworkByAdrAndMask failed"
endif
comment "Testing with netmask in dotted decimal notation "
set $ConstTest$ = "198.48.0.0"
set $CompValue$ = getIP4NetworkByAdrAndMask('198.51.100.223', '255.240.0.0')
if ($ConstTest$ = $CompValue$)
comment "getIP4NetworkByAdrAndMask passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing getIP4NetworkByAdrAndMask failed"
endif
-
getDefaultNetmaskByIP4adr (<ip4adr>) : string
Liefert die Defaultnetzmaske zu IP-Adresse <ip4adr>. Die Defaultnetzmaske steht für ein Netz der Klassen A,B,C.
Beispiel:
set $ConstTest$ = "255.255.0.0"
set $CompValue$ = getDefaultNetmaskByIP4adr("128.42.5.4")
if ($ConstTest$ = $CompValue$)
comment "getDefaultNetmaskByIP4adr passed"
else
set $TestResult$ = "not o.k."
LogWarning "testing getDefaultNetmaskByIP4adr failed"
endif
-
cidrToNetmask (<string>) : string
//since 4.12.4.37
Liefert die Netzmaske (dotted decimal notation) zum gegebene IPv4 CIDR-Suffix.
cidr ⇐ 0 ergibt "0.0.0.0"
cidr >= 32 ergibt "255.255.255.255"
Leere oder üngültige Eingabe ergibt Leerstring
siehe auch : [netmaskToCidr]
siehe auch : [getDefaultNetmaskByIP4adr]
siehe auch : [getIP4NetworkByAdrAndMask]
Beispiel:
set $netmask$ = cidrToNetmask("24")
comment "expected: 255.255.255.0"
set $netmask$ = cidrToNetmask("16")
comment "expected: 255.255.0.0"
set $netmask$ = cidrToNetmask("-1")
comment "expected: 0.0.0.0"
set $netmask$ = cidrToNetmask("55")
comment "expected: 255.255.255.255"
set $netmask$ = cidrToNetmask("")
comment "expected: "
-
netmaskToCidr (<string>) : string
//since 4.12.4.37
Liefert das IPv4 CIDR-Suffix zur gegebenen Netzmaske (dotted decimal notation).
Leere oder üngültige Eingabe ergibt Leerstring.
siehe auch : [cidrToNetmask]
siehe auch : [getDefaultNetmaskByIP4adr]
siehe auch : [getIP4NetworkByAdrAndMask]
Beispiel:
set $cidr$ = netmaskToCidr("255.255.255.0")
comment "expected: 24"
set $cidr$ = netmaskToCidr("255.255.0.0")
comment "expected: 16"
set $cidr$ = netmaskToCidr("255.255.10.0")
comment "(invalid input) expected: "
set $cidr$ = netmaskToCidr("")
comment "(empty input) expected: "
-
isValidFQDN (<domainName>) : boolean
Gibt true (wahr) zurück wenn die Zeichenkette einem Fully Qualified Domain Name (FQDN, deutsch etwa "vollständig qualifizierter Domainname") entspricht und false (falsch) wenn nicht. Ein Fully Qualified Domain Name (FQDN) hat die folgenden Eigenschaften:-
Die komplette Zeichenkette besteht insgesamt aus nicht mehr als 254 Zeichen
-
Sie muss aus mindestens drei, durch Punkte getrennte, Zeichenketten bestehen
-
Jede dieser Zeichenketten darf 63 Zeichen nicht überschreiten
-
Die Zeichenketten, bis auf die Letzte, dürfen Buchstaben, ganze Zahlen und Minuszeichen enthalten. Das Minuszeichen darf nicht am Anfang stehen
-
Die letzte Zeichenkette (TLD, Top-Level-Domain) darf nur Buchstaben enthalten und muss mindestens 2 Zeichen lang sein
-
Beispiel:
Message "Testing of isValidFQDN"
SetLogLevel=7
DefVar $TestResult$
DefVar $CompValue$
DefStringList $CorrectFQDNs$
DefStringList $IncorrectFQDNs$
Set $CorrectFQDNs$ = CreateStringList("www.uib.de", "opsi-script.uib.de", "m.opsi.org", "a-a.b-b.cc", "a1b2.c3d4.e5f6.g7h8.i9j0.zz", "1a-2b.3c_4d.5e-6f.zzz","123.123.com")
Set $IncorrectFQDNs$ = CreateStringList("abcde", "uib.de", "www.uib", "www.uib.d", "-script.uib.de", "_script.uib.de", "www.uib.00", "a1b2.c3d4.e5f6", "aaa.-bbb.zz", "#aaa.bbb.zz", "a+a.bbb.zz", "a?a.bbb.zz")
DefFunc myFQDNTester($expected$ : string, $fqdn$ : string, ref $TestResult$ : string) : void
DefVar $CompValue$
set $CompValue$ = booltostring(isValidFQDN($fqdn$))
if $CompValue$ = $expected$
comment "Testing isValidFQDN succeeded"
else
set $TestResult$ = "not o.k."
LogWarning "Testing isValidFQDN failed"
endif
endfunc
for %s% in $CorrectFQDNs$ do myFQDNTester("true","%s%",$TestResult$)
for %s% in $IncorrectFQDNs$ do myFQDNTester("false","%s%",$TestResult$)
Für weiter Beispiele schauen Sie im Produkt 'opsi-script-test' und dort speziell in der Datei sub-scripts/networkcalc.opsiscript
Prozess- und Skript-Funktionen [W/L/M]
-
waitForPackageLock(
<seconds timeout string>,<bool should we kill>`) : bool` //since 4.11.6.1 [L]
Liefert 'true' zurück, wenn das Linux-Packagesystem nicht gesperrt ist. Ist es gesperrt, so wird <seconds timeout string> Sekunden auf die Freigabe gewartet. Ist der Timeout erreicht, so wird der Prozess, welcher den Lock erzeugt hat, abgeschossen, wenn <bool should we kill> gleich 'true' ist. Dieses Vorgehen ist aber nicht empfohlen.
-
processIsRunning(
<process name>`) : boolean` //since 4.11.6.1 [W/L/M]
Liefert 'true', wenn der Prozess <process name> in der aktuellen Prozessliste ist.
-
isProcessChildOf(<searchprocstr>, <parentprocstr>): bool
//since 4.12.4.35 [W/L/M]
Liefert 'true', wenn der Prozess <searchprocstr> ein Kindprozess von <parentprocstr> ist.
Beispiel:if isProcessChildOf('%opsiscriptprocname%', 'opsiclientd.exe') comment "running in opsi service context" endif
-
shellCall (
<command string>`) : stringlist (output)` //since 4.11.4.2 [W/L/M]
Führt <command string> mit der Standard-Shell (cmd.exe / bash) aus.set $list$ = shellCall('net start')
ist eine Abkürzung für den Ausdruck:
set $list$ = getOutStreamFromSection ('ShellScript_netstart winst /sysnative') [ShellScript_netstart] net start
-
shellCall (
<command string>`) : noresult` //since 4.11.6.1 [W/L/M]shellCall('net start')
ist eine Abkürzung für den Ausdruck:
ShellScript_netstart winst /sysnative [ShellScript_netstart] net start
-
shellCall (
<command string>`) : string (exitcode)` //since 4.11.6.1 [W/L/M]set $exitcode$ = shellCall('net start')
ist eine Abkürzung für den Ausdruck:
ShellScript_netstart winst /sysnative set $exitcode$ = getLastExitcode [ShellScript_netstart] net start
-
powershellCall(
<commandstr> [,<access str>='sysnative' [,<policy bool str>='true']]) : stringlist (output)
//since 4.12.0.16 [W]
powershellCall(
<commandstr> [,<access str>='sysnative' [,<policy bool str>='true'][, <optionstr> = '']]) : stringlist (output)
//since 4.12.4.28 [W]
Führt <command string> mit der PowerShell aus.
Genauer gesagt wird ein Skript ausgeführt, das wie folgt aussieht:trap { write-output $_ ; exit 1 } <commandstr> exit $LASTEXITCODE
Die erste Zeile dient dazu, dass bei Exceptions kein exitcode=0 zurückgeliefert wird, und die letzte Zeile dient dazu, den letzten produzierten Exitcode zurückzuliefern.
Die Architektur derpowershell.exe
ist per defaultsysnative
. Die Architektur kann aber auch über den optionalen zweiten Parameter <access str> angegeben werden. Dabei muss der übergebene <access str> einer der folgenden Werte sein:32bit
,sysnative
,64bit
.
(siehe auch: Kapitel 64 Bit-Unterstützung)
Da per Windows-Default die ExecutionPolicy der PowerShell aufRestricted
steht, können Skripte nicht ohne weiteres ausgeführt werden. Daher hat der BefehlpowershellCall
per default folgendes Verhalten: Die aktuelle ExecutionPolicy wird gesichert und die ExecutionPolicy aufRemoteSigned
gesetzt. Dann wird das Skript ausgeführt und abschließend die ExecutionPolicy wieder zurück gesetzt. Dieses Default-Verhalten kann über den optionalen dritten Parameter <policy bool str> geändert werden: Hat <policy bool str> den Wert "false", so wird die ExecutionPolicy nicht modifiziert.
Wird die FunktionpowershellCall
dort aufgerufen, wo eine Stringliste erwartet wird, so enthält die Stringliste die Ausgabe von <commandstr>.
Seit 4.12.4.35:
Wird als aktuelle ExecutionPolicyAllSigned
detektiert, so wird der PowerShell-Aufruf automatisch so umgebaut, dass das temporäre PowerShell-Skript nicht per-File
aufgerufen wird, sondern per-Command Get-Content -Path <tempfilename> | Out-String | Invoke-Expression
. Dadurch wird das Skript ohne Berücksichtigung der ExecutionPolicy ausgeführt. In einem solchen Fall werden aber evtl. angegebenePASSPARAS
nicht mehr berücksichtigt.
Seit 4.12.4.28:
Der optionale <optionstr> kann genutzt werden, um dem Befehl zusätzliche Optionen mitzugeben. Da der powershellcall intern letztendlich ein ExceWith Aufruf ist, können die dort dokumentierten Optionen auch hier angegeben werden, siehe sec-section.adoc#opsi-script-execwith-params
Beispiel:set $list$= powershellCall('Get-Process -ProcessName "opsi*"')
ist eine Abkürzung für den Ausdruck:
set $policy$ = takeString(0,shellCall('powershell.exe get-executionpolicy')) shellCall('powershell.exe set-executionpolicy RemoteSigned') set $list$ = getOutStreamFromSection ('Execwith_ps powershell.exe winst /sysnative') shellCall('powershell.exe set-executionpolicy '+$policy$) [Execwith_ps] trap { write-output $_ ; exit 1 } Get-Process -ProcessName "opsi*" exit $LASTEXITCODE
Hinweis zum PowerShell-Befehl 'Get-Partition'
Die Ausgabe des PowerShell-BefehlsGet-Partition
enthält NULL-Characters\u0000
in der SpalteDriveLetter
überall dort, wo kein Laufwerksbuchstabe steht. Das führt in opsi-script zu Problemen beim direkten Einlesen der Ausgabe vonGet-Partition
. Möchte man die Ausgabe vonGet-Partition
in einem Skript weiterverarbeiten, dann empfehlen wir als Lösung:DefStringlist $ResultList$ PowershellCall('Get-Partition > "%opsiUserTmpDir%\Get-Partition.txt"') Set $ResultList$ = LoadTextFile("%opsiUserTmpDir%\Get-Partition.txt")
Dabei wird die Ausgabe von
Get-Partition
zuerst in eine Datei gespeichert und dadurch wird das Problem mit den NULL-Characters umgangen.
-
powershellCall(
<commandstr> [,<access str>='sysnative' [,<policy bool str>='true']]) : noresult
//since 4.12.0.16 [W]
powershellCall(
<commandstr> [,<access str>='sysnative' [,<policy bool str>='true'][, <optionstr> = '']]) : noresult
//since 4.12.4.28 [W]
siehe [powershellCall_list]
Die FunktionpowershellCall
kann auch dort aufgerufen werden, wo kein Rückgabe-Wert erwartet wird.
Beispiel:powershellCall('Get-Process -ProcessName "opsi*"')
-
powershellCall(
<commandstr> [,<access str>='sysnative' [,<policy bool str>='true']]) : string (exitcode)
//since 4.12.0.16 [W]
powershellCall(
<commandstr> [,<access str>='sysnative' [,<policy bool str>='true'][, <optionstr> = '']]) : string (exitcode)
//since 4.12.4.28 [W]
siehe [powershellCall_list]
Wird die FunktionpowershellCall
dort aufgerufen wo, ein String erwartet wird, so enthält der String den Exitcode des ausgeführten Skriptes.
Beispiel:set $exitcode$ = powershellCall('Get-Process -ProcessName "opsi*"')
-
processCall(
<string>`) : string (exitcode)` //since 4.11.6.1 [W/L/M]
Startet das Programm <string> als Prozess und liefert den Exitcode zurück.set $exitcode$ = processCall('setup.exe /S')
ist eine Abkürzung für den Ausdruck:
Winbatch_setup set $exitcode$ = getLastExitcode [Winbatch_setup] setup.exe /S
Tatsächlich basiert
processCall
intern auf den selben Routinen wiewinbatch
und verarbeitet daher auch die selben Modifier:-
/LetThemGo
Verschiebt den aufgerufenen Prozess in den Hintergrund und wartet nicht auf dessen Beendigung; d.h. dass sofort die nächsten Zeilen der WinBatch-Sektion bzw. die nächsten Zeilen des übergeordneten Programms abgearbeitet werden. -
/TimeOutSeconds
<seconds>
Bricht das Warten auf das Prozessende oder eine Wartebedingung (/WaitForProcessEnding
) nach Ablauf von <seconds> ab, auch wenn das Prozessende oder die Wartebedingung noch nicht erfüllt ist.
Der Prozess, auf dessen Ende gewartet werden sollte, wird nicht gestoppt.
Kann seit Version 4.11.3 auch alleine (z.B. ohne/WaitForProcessEnding
) verwendet werden, aber nicht zusammen mit/WaitSeconds
.
Seit 4.11.4.6 wird der Zeitablauf bis zum Timeout über den Fortschrittsbalken angegeben. -
/WaitSeconds
[number of seconds]
Die Parametrisierung /WaitSeconds [AnzahlSekunden] modifiziert das Verhalten dahingehend, dass opsi-script jeweils erst nach [AnzahlSekunden] die Skriptbearbeitung fortsetzt. Die angegebene Zeit stoppt opsi-script auf jeden Fall. In der Default-Einstellung wird zusätzlich auf das Ende der angestoßenen Prozesse gewartet. Ist letzteres nicht gewünscht, so kann der Parameter mit dem Parameter /LetThemGo kombiniert werden. -
/WaitForProcessEnding
<program name>
Wartet darauf, dass sich der Prozess mit dem Namen <program name> beendet.
Kann und sollte mit/TimeOutSeconds
kombiniert werden. -
/32Bit
//seit 4.11.3.5 [W]
Das ist der Default. Die in der Sektion angegebenen Pfade werden als 32 Bit Pfade interpretiert.
Beispiel:c:\windows\system32\regedit.exe
ruft (auch auf einem 64bit System) die 32 Bit 'regedit.exe' auf. -
/64Bit
//seit 4.11.3.5 [W]
Die in der Sektion angegebenen Pfade werden als 64 Bit Pfade interpretiert.
Beispiel:c:\windows\system32\regedit.exe
ruft (auf einem 64bit System) die 64 Bit 'regedit.exe' auf. -
/SysNative
//seit 4.11.3.5 [W]
Die in der Sektion angegebenen Pfade werden gemäß der OS-Architektur interpretiert.
Beispiel:c:\windows\system32\regedit.exe
ruft auf einem 64bit System die 64 Bit 'regedit.exe' und auf einem 32bit System die 32 Bit 'regedit.exe’auf.
-
Spezielle Kommandos [W/L/M]
-
Killtask
<process> [W/L/M]
stoppt alle Prozesse, in denen das durch <process> bezeichnete Programm ausgeführt wird. Beispiel :
killtask "winword.exe"
-
ChangeDirectory
<directory> //since 4.11.2.6 [W/L/M]
Setzt das angegebene Directory als Arbeitsverzeichnis des opsi-script. Wirkt auf alle nachfolgenden Aktionen (z.B. winbatch Sektionen) und wird am Ende einese Scriptes automatisch zurückgesetzt. Beispiel :
ChangeDirectory "%SCRIPTPATH%\programm"
-
UpdateEnvironment
//since 4.11.5.1 [W]
Sendet Windows das Signal das Environment aus der Registry neu einzulesen. Anzuwenden nachdem Umgebungsvariablen wie z.B. PATH verändert, gesetzt oder gelöscht wurden. ABER: Normale ShellScript oder Winbatch Aufrufe erben trotzdem das 'alte' Environment. Daher danachwinbatch
mit dem Parameter/RunElevated
verwenden.
Example:
comment "Set Environment Variables and check for it ...."
Registry_add_environment /sysnative
UpdateEnvironment
comment "This will not work because the environment is inherited from the running process"
set $list$ = shellCall('set opsi-script-test')
comment "This will work because this new started process will get a new environment"
winbatch_check_environment /RunElevated
if ("42" = getlastExitCode)
comment "passed"
else
comment "failed"
endif
[Registry_add_environment]
openkey [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment]
set "opsi-script-test"="deleteme"
[winbatch_check_environment]
"%system%\cmd.exe" /c "if %opsi-script-test%==deleteme exit 42"
-
sleepSeconds
<string> [W/L/M]
unterbricht die Programmausführung für <string> Sekunden. Dabei muß <string> ein Stringausdruck sein welcher eine Integerzahl repräsentiert.
-
markTime
[W/L/M]
Setzt einen Zeitstempel für die Systemlaufzeit und zeichnet diese auf.
-
diffTime
[W/L/M]
Zeichnet die vergangene Zeit seit der letzten aufgezeichneten Zeit (marktime
) auf.
-
runningInWanMode
//since 4.12.4.17 [W/L/M]
Gibttrue
zurück, wenn das Script im 'WAN mode' läuft. Dies ist der Fall wenn die Konstante%opsiserviceurl%
nicht den opsi-server angibet sondern localhost adressiert.
siehe auch: opsi-Erweiterung WAN/VPN
-
isCertInstalledInSystem(
<label>`) : boolstring` [W/L/M] //since 4.12.4.37
Gibttrue
zurück, wenn ein CA certificate mit der Bezeichnung <label> im certificatsstore des Betriebssystems gefunden wurde.
siehe auch: [importCertToSystem]
siehe auch: [removeCertFromSystem]
siehe auch: [listCertificatesFromSystem]
Beispiel siehe [listCertificatesFromSystem]
-
importCertToSystem(
<filename>`) : noresult` [W/L/M] //since 4.12.4.37
Importiert das in <filename> enthaltene CA certificat in den certificatsstore des Betriebssystems.
siehe auch: [isCertInstalledInSystem]
siehe auch: [removeCertFromSystem]
siehe auch: [listCertificatesFromSystem]
Beispiel siehe [listCertificatesFromSystem]
-
removeCertFromSystem(
<label>`) : noresult` [W/L/M] //since 4.12.4.37
Entfernt das CA certificate mit der Bezeichnung <label> aus dem certificatsstore des Betriebssystems.
siehe auch: [isCertInstalledInSystem]
siehe auch: [importCertToSystem]
siehe auch: [listCertificatesFromSystem]
Beispiel siehe [listCertificatesFromSystem]
-
listCertificatesFromSystem
: stringlist` [W/L/M] //since 4.12.4.37
Gibt eine List aller CA certificate aus dem certificatsstore des Betriebssystems zurück.
see also : [isCertInstalledInSystem]
see also : [importCertToSystem]
see also : [removeCertFromSystem]
Beispiel:
set $list$ = listCertificatesFromSystem
if "" = takeFirstStringContaining($list$,"opsi-script-test test CA")
comment "not found"
endif
ImportCertToSystem('opsi-script-test-CA.pem')
if isCertInstalledInSystem("opsi-script-test test CA")
comment "found"
removeCertFromSystem("opsi-script-test test CA")
if not(isCertInstalledInSystem("opsi-script-test test CA"))
comment "CA succesful removed"
endif
endif
-
reloadProductList
[W/L/M] //since 4.12.6.1
Lädt die Produktliste vom opsi-server nach Durchführung des Skriptes in opsi-script neu ein. Ist die Produktliste nicht leer, wird sie erneut von opsi-script abgearbeitet. loadProductList kann überall in der Actions-Sektion des Skriptes stehen. Die Empfehlung ist aber ,der Logik entsprechend, den Befehl ans Ende der Sektion zu setzen.
Steuerung des Logging [W/L/M]
-
comment
<STRINGAUSDRUCK> [W/L/M]
bzw.
comment
= <Zeichensequenz>
wird einfach der Wert des String-Ausdrucks (bzw. Zeichensequenz) als Kommentar in die Protokolldatei eingefügt.
-
LogError
<STRINGAUSDRUCK> [W/L/M]
oder
LogError
= <Zeichensequenz>
Fügt eine zusätzlich Fehlermeldungen in der Protokolldatei ein und erhöht den Fehlerzähler um eins.
-
LogWarning
<STRINGAUSDRUCK> [W/L/M]
oder
LogWarning
= <Zeichensequenz>
Fügt eine zusätzlich Warnmeldungen in der Protokolldatei ein und erhöht den Warnungszähler um eins.
-
includelog
<file name> <tail size> //since 4.11.2.1 [W/L/M] -
includelog
<file name> <tail size> [<encoding>] //since 4.11.4.1 [W/L/M]
Fügt die Datei <file name> in den aktuellen ein. Dabei werden nur die letzten <tail size> Zeilen und nicht die komplette Logdatei eingfügt. Wenn Sie ein anderes Programm (z.B. ein setup programm) starten das eine Logdatei produziert, können Sie mit diesem Begfehl die Informationen aus dieser Logdatei in den Log des opsi-script übernehmen.
Seit Version 4.11.3.2 kann auch eine negative <tail size> angegeben werden. Dann arbeitetincludelog
im 'Head' Modus, d.h. ist <tail size> = -5, so werden die ersten 5 Zeilen von <file name> in den Log übernommen. Seit Version 4.11.4.1 kann als dritter Parameter ein encoding angegeben werden. Bekannte encodings sind beim Befehlencoding
angegeben. Wird als encodingauto
angegeben, so wird versucht das passende Encoding zu eraten. Beispiel:
includelog "%Scriptpath%\test-files\10lines.txt" "5" includelog "%Scriptpath%\test-files\10lines_utf16.txt" "5" "ucs2be"
siehe: opsi-script encoding
-
SetConfidential
<secret string> [W/L/M]
Dient dazu vertrauliche Informationen (z.B. Passwörter) aus den Logdateien fernzuhalten. Diese werden dort durch '(confidential)' ersetzt.
Wird der Loglevel auf '9' gesetzt, so werden die 'confidential’s im Klartext gelogt.
Seit Version 4.11.3.5
Beispiel:
message "SetConfidential"
SetConfidential "forbidden"
comment "This is a forbidden string"
comment "should be in the log file: This is a ***(confidential)*** string"
Log:
message SetConfidential
comment: This is a ***(secret)*** string
comment: should be in the log file: This is a ***(confidential)*** string
-
asConfidential(
<secret string expression>)
: string //since 4.12.0.16 [W/L/M]
Diese Funktion dient dazu vertrauliche Informationen von einer Funktion zu erlangen, ohne das die Werte in der Logdatei landen. Dabei kommt es zu folgenden Ablauf:-
Aktuellen Loglevel sichern
-
Loglevel auf Warning (4) setzen+
-
Auswerten der übergeben Stringexpression (z.B. einer Funktion welche einen String liefert)
-
Setzen dieses ermittelten Strings als Confidential d.h. dieser String wird ab jetzt nicht mehr geloggt.
-
Ursprünglichen Loglevel wiederherstellen
-
Rückgabe des ermittelten Stringwertes.
-
Beispiel:
set $ConstTest$ = asConfidential(stringReplace("this is my old secret", "old", "new"))
comment "this is my new secret"
comment "should be in the log file: ***(confidential)*** "
Log:
Set $ConstTest$ = asConfidential(stringReplace("this is my old secret", "old", "new"))
The value of the variable "$ConstTest$" is now: "***(confidential)***"
comment: This is a ***(confidential)*** string
comment: should be in the log file: This is a ***(confidential)*** string----
siehe auch : [SetConfidential] siehe auch : [GetConfidentialProductProperty] siehe auch : [asConfidential_list]
-
asConfidential(
<secret stringlist expression>) : stringlist
//since 4.12.4.15 [W/L/M]
This function should be used to get confidential stringlist from an other stringlist function without without logging the secret strings. The Function work like the string functionasconfidential
, but for stringlists.
Information und Interaktion [W/L/M]
-
Message
<STRINGAUSDRUCK> [W/L/M]
bzw.
Message
= <Buchstabenfolge>
bewirkt, dass in der Batch-Oberfläche des opsi-script der Wert von STRINGAUSDRUCK bzw. dass die Buchstabenfolge als Hinweis-Zeile zum gerade laufenden Installationsvorgang angezeigt wird (solange bis die Installation beendet ist oder eine anderemessage
angefordert wird).
Empfohlen ist die erste Variante, da nur hier auch Variablen für den Messagetext verwendet werden können. Beispiel:
Message "Installation von "+$productid$
-
ShowMessageFile
<file name> [W/L/M]
zeigt den Inhalt der Datei <file name> in einem gesonderten Fenster an und wartet auf Bestätigung durch den Anwender. Z.B. könnte so eine "Nachricht des Tages" angezeigt werden:
ShowMessageFile "p:\login\day.msg"
-
ShowBitMap
[<DATEINAME>] [<Beschriftung>] [W/L/M]
wird die Bilddatei <DATEINAME> (BMP-, JPEG- oder PNG-Format, 160x160 Pixel) in der Batch-Oberfläche angezeigt. Eine Beschriftung kann ebenfalls hinzugefügt werden. <DATEINAME> und <Beschriftung> sind String-Ausdrücke. Wenn der Namensparameter fehlt, wird das Bild gelöscht. Beispiel:
ShowBitmap "%scriptpath%\" + $ProduktName$ + ".bmp" "$ProduktName$"
-
Pause
<STRINGAUSDRUCK> [W/L/M]
bzw.
Pause
= <Zeichensequenz>
Die beiden Anweisungen zeigen in einem Textfenster den in STRINGAUSDRUCK gegebenen Text (bzw. Zeichensequenz) an. Auf Anklicken eines Knopfes setzt sich der Programmlauf fort.
-
Stop
<STRINGAUSDRUCK> [W/L/M]
bzw.
stop
= <Zeichensequenz> [W/L/M]
der STRINGAUSDRUCK (bzw. Zeichensequenz, die möglicherweise auch leer ist) wird angezeigt und um Bestätigung gebeten, dass der Programmablauf abgebrochen werden soll.
-
setActionProgress <string>
: noresult //since 4.11.3 [W/L/M]
Übermittelt <string> als ActionProgress für das laufende Produkt an den Server. Der Default von ActionProgress ist 'installing' während ein Script ausgeführt wird. Der ActionProgress wird im configed angezeigt.
Kommandos für userLoginScripts / User Profile Management [W]
-
GetScriptMode
//since 4.11.2.1
liefert eines der beiden Werte 'Machine','Login':-
'Machine' - das Script läuft nicht als 'userLoginScript'
-
'Login' - das Script läuft als 'userLoginScript'
-
-
GetUserSID(
<Windows Username>`)`
siehe auch [GetUserSID]
-
GetLoggedInUser
//since 4.11.1.2
-
GetUsercontext
//since 4.11.1.2
liefert den Namen des Users in dessen Kontext der opsi-script gerade läuft.
siehe auch: [GetUsercontext]
-
saveVersionToProfile
//since 4.11.2.1
speichert productversion-packageversion die im lokalen Profil
Diese Funktion ist gedacht für userLoginScripts.
Diese Funktion kann in Kombination mitreadVersionFromProfile
verwendet werden um festzustellen ob ein Script schonmal gelaufen ist. Es speichert im Lokalen Profil (in der Datei "%CurrentAppdataDir%\.opsi.org\userLoginScripts.ini"), dass das 'userLoginScript' für dieses opsi product in dieser product version und package version für den aktuellen user ausgefürt wurde. Sieh auchscriptWasExecutedBefore
-
readVersionFromProfile
//since 4.11.2.1
liefert einen string mit productversion-packageversion für das aktuelle opsi produkt der aus dem lokalen Profil ausgelesen wird. Siehe auch:saveVersionToProfile
Diese Funktion ist gedacht für userLoginScripts.
-
scriptWasExecutedBefore
//since 4.11.2.1
Mit dieser boolschen Funktion kann überprüft werden, ob das 'userLoginScript' zu diesem Produkt in dieser Version schon mal zuvor gelaufen ist und eine erneute Ausführung unnötig ist. Dazu liest diese Funktion zunächst einen evtl. vorhandenen Versionsstempel vom Profil ein (wie das mitreadVersionFromProfile
möglich ist) und vergleicht diesen mit der aktuell laufenden Version. Aus dem Vergleich ergibt sich der Rückgabewert (wahr/falsch). Danach werden noch die aktuellen Werte in das Profil zurückgeschrieben (wie das mitsaveVersionToProfile
möglich ist). Somit benötigen Sie nur diese eine Funktion in einerif
Anweisung, um zu prüfen ob das Script schon mal gelaufen ist.
-
isLoginScript
//since 4.11.2.1
Diese boolsche Funktion liefert 'true' wenn das aktuelle Script als 'userLoginScript' läuft. Siehe auch:GetScriptMode
For-To Schleife [W/L/M]
Zum mehrfachen Ausführen eines Befehls oder einer Subsektion.
Syntax:
for
%<temporary string variable>% =
<start string> to
<end string> do
<one statement> //since 4.11.5 [W/L/M]
Die temporäre Variable %<temporary string variable>% muss nicht und darf nicht deklariert werden und ist in der aufgerufenen Subsektion als Konstante verfügbar.
Example:
Code from opsi-script-test:
message "for to loop"
set $ConstTest$ = "12345"
set $CompValue$ = ""
for %s% = "1" to "5" do sub_iteration_test
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
[sub_iteration_test]
set $CompValue$ = $CompValue$ + '%s%'
ergibt den Log:
message for to loop
Set $ConstTest$ = "12345"
The value of the variable "$ConstTest$" is now: "12345"
Set $CompValue$ = ""
The value of the variable "$CompValue$" is now: ""
~~~~~~ Looping through: '1', '2', '3', '4', '5'
~~~~~~~ Start Sub ~~~~~~~ sub_iteration_test
Set $CompValue$ = $CompValue$ + '1'
The value of the variable "$CompValue$" is now: "1"
~~~~~~~ End Sub ~~~~~~~ sub_iteration_test
~~~~~~~ Start Sub ~~~~~~~ sub_iteration_test
Set $CompValue$ = $CompValue$ + '2'
The value of the variable "$CompValue$" is now: "12"
~~~~~~~ End Sub ~~~~~~~ sub_iteration_test
~~~~~~~ Start Sub ~~~~~~~ sub_iteration_test
Set $CompValue$ = $CompValue$ + '3'
The value of the variable "$CompValue$" is now: "123"
~~~~~~~ End Sub ~~~~~~~ sub_iteration_test
~~~~~~~ Start Sub ~~~~~~~ sub_iteration_test
Set $CompValue$ = $CompValue$ + '4'
The value of the variable "$CompValue$" is now: "1234"
~~~~~~~ End Sub ~~~~~~~ sub_iteration_test
~~~~~~~ Start Sub ~~~~~~~ sub_iteration_test
Set $CompValue$ = $CompValue$ + '5'
The value of the variable "$CompValue$" is now: "12345"
~~~~~~~ End Sub ~~~~~~~ sub_iteration_test
~~~~~~ End Loop
If
$ConstTest$ = $CompValue$ <<< result true
($ConstTest$ = $CompValue$) <<< result true
Then
comment: passed
Else
EndIf
Switch / Case Statement [W/L/M]
Syntax:
Switch <string expression> Case <string const> <statement(s)> EndCase [DefaultCase <statement(s)> EndCase] EndSwitch
Switch / Case Ausdrücke können nicht geschachtelt werden (innerhalb eines Case darf es kein weiteres Switch geben).
Eine Möglichkeit etwa das selbe wie Switch / Case zu erreichen, sind die seit 4.12.4.37 verfügbaren if-elseif-else
Ausdrücke, welche auch schachtelbar sind.
siehe: IfElseEndif
Examples:
Code from opsi-script-test:
set $ConstTest$ = "5"
Switch $ConstTest$
Case "1"
set $CompValue$ = "1"
EndCase
Case "2"
set $CompValue$ = "2"
EndCase
Case "3"
set $CompValue$ = "3"
EndCase
Case "4"
set $CompValue$ = "4"
EndCase
Case "5"
set $CompValue$ = "5"
EndCase
Case "6"
set $CompValue$ = "6"
EndCase
Case "7"
set $CompValue$ = "7"
EndCase
DefaultCase
set $CompValue$ = "notexisting"
EndCase
EndSwitch
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
.
[Sub_check_exitcode]
comment "Test for installation success via exit code"
set $ExitCode$ = getLastExitCode
; informations to exit codes see
; http://msdn.microsoft.com/en-us/library/aa372835(VS.85).aspx
; http://msdn.microsoft.com/en-us/library/aa368542.aspx
Switch $ExitCode$
Case "0"
comment "Looks good: setup program gives exitcode zero"
EndCase
Case "1605"
comment "ERROR_UNKNOWN_PRODUCT 1605"
comment "This action is only valid for products that are currently installed."
comment "Uninstall of a not installed product failed - no problem"
EndCase
Case "1641"
comment "looks good: setup program gives exitcode 1641"
comment "ERROR_SUCCESS_REBOOT_INITIATED 164"
comment "The installer has initiated a restart."
comment "This message is indicative of a success."
ExitWindows /Reboot
EndCase
Case "3010"
comment "looks good: setup program gives exitcode 3010"
comment "ERROR_SUCCESS_REBOOT_REQUIRED 3010"
comment "A restart is required to complete the install."
comment "This message is indicative of a success."
ExitWindows /Reboot
EndCase
DefaultCase
logError "Fatal: Setup program gives an unknown exitcode unequal zero: " + $ExitCode$
isFatalError "Exit Code: "+ $ExitCode$
EndCase
EndSwitch
Bedingungsanweisungen (if-Anweisungen) [W/L/M]
Die Ausführung einer oder mehrere Anweisungen kann in den primären Sektionen von der Erfüllung bzw. Nichterfüllung einer Bedingung abhängig gemacht werden.
Beispiel:
;Welche Windows-Version?
DefVar $MSVersion$
Set $MSVersion$ = GetMsVersionInfo
if CompareDotSeparatedNumbers($MSVersion$,">=","6")
sub_install_win7
else
if ( $MSVersion$ = "5.1" )
sub_install_winXP
else
stop "not a supported OS-Version"
endif
endif
Ab Version 4.12.4.37 kennt opsi-script auch eine elseif
Anweisung.
Beispiel:
Defvar $OS$
set $OS$ = GetOS
if $OS$ = "Windows_NT"
comment "We are on Windows"
elseif $OS$ = "Linux"
comment "We are on Linux"
elseif $OS$ = "macos"
comment "We are on macOS"
else
LogWarning "Unsupported OS"
endif
Allgemeine Syntaxregeln [W/L/M]
Folgendes Schema der if-Anweisung ist ersichtlich:
if
<Bedingung>
;eine oder mehrere Anweisungszeilen
elseif
<Bedingung>
;eine oder mehrere Anweisungszeilen
else
;eine oder mehrere Anweisungszeilen
endif
Der else
-Teil der Anweisung darf fehlen.
Der elseif
-Teil der Anweisung darf fehlen.
if-Anweisungen können geschachtelt werden. Das bedeutet, dass in der Anweisung nach einem if
Satz (sowohl in dem if
als auch im else
oder elseif
Teil) eine weitere if-Anweisung folgen darf.
<Bedingungen> sind boolesche Ausdrücke, das heißt logische Ausdrücke, die entweder den Wert 'wahr' oder den Wert 'falsch' tragen können.
Boolesche Ausdrücke [W/L/M]
Ein Vergleichsausdruck, welcher ein boolscher Ausdruck ist, sieht folgendermaßen aus:
<STRINGAUSDRUCK> <Vergleichszeichen> <STRINGAUSDRUCK>
An der Stelle <Vergleichszeichen> kann eins der folgenden Zeichen stehen:
<
⇐
=
>=
>
Bei String-Vergleichen im opsi-script wird Groß-/Kleinschreibung nicht unterschieden.
Ungleich muss mit einem NOT()
Ausdruck umgesetzt werden, was weiter unten gezeigt wird.
Es gibt einen Vergleichsausdruck um zwei Strings wie (integer) Zahlen zu vergleichen. Wenn einer der Werte nicht in eine Zahl übertragen werden kann, wird ein Fehler ausgegeben.
Diese Zahlenvergleichsausdrücke haben die gleich Form wie die String-Vergleichsausdrücke, allerdings wird dem dem Vergleichszeichen ein INT vorangestellt:
<STRINGAUSDRUCK> INT
<Vergleichszeichen> <STRINGAUSDRUCK>
So können Ausdrücke wie
if $Name1$ INT<= $Name2$
oder
if $Number1$ INT>= $Number2$
gebildet werden.
Boolesche Operator sind AND
, OR
und NOT()
(Groß-/Kleinschreibung nicht unterschieden).
b1, b2 und b3 sind boolesche Ausdrücke, die sich zu kombinierten Ausdrücken verbinden lassen.
b1 AND
b2
b1 OR
b2
NOT(
b3 )
Diese booleschen Ausdrücke zeigen dabei eine Konjunktion (AND), ein Disjunktion (OR) und eine Negation (NOT).
Ein boolescher Ausdruck kann in runden Klammer eingeschlossen werden (diese produziert dann einen neuen booleschen Ausdruck mit dem selben Wert).
Die allgemeinen Regel für boolesche Operatorenprioritäten ("and" vor "or") sind im Moment nicht implementiert. Ein Ausdruck mit mehr als einem Operator wird von links nach rechts interpretiert. Wenn also eine boolescher Ausdruck einen AND und OR Operator enthalten soll, müssen runde Klammern eingesetzt werden. So muss zum Beispiel explizit geschrieben werden
b1 OR
(b2 AND
b3)
oder
(b1 OR
b2) AND
b3
Das zweite Beispiel beschreibt, was ausgeführt werden würde, wenn keine runden Klammern gesetzt wäre – wohingegen die übliche Operatorenprioritäten so laufen würde wie in der ersten Zeile angezeigt.
Boolesche Operatoren können als spezielle boolesche Wertefunktionen eingesetzt werden (die Negation-Operatoren demonstrieren das sehr deutlich).
Es sind noch weitere boolesche Funktionen implementiert. Jeder Aufruf einer solchen Funktion begründet sich in einen booleschen Ausdruck:
-
FileExists
(<datei name>) [W/L/M]
Die Funktion gibt wahr zurück, wenn die genannte Datei oder das Verzeichnis existiert, ansonsten kommt die Antwort falsch. -
FileExists32
(<datei name>) [W] siehe Kapitel 64 Bit-Unterstützung -
FileExists64
(<datei name>) [W] siehe Kapitel 64 Bit-Unterstützung -
FileExistsSysNative
(<datei name>) [W] siehe Kapitel 64 Bit-Unterstützung
-
FileOrFolderExists
(<Dateiname oder Verzeichnispfad> [,<access str>]) : boolean [W/L/M] (ab Version 4.12.4.14)
Die Funktion gibt wahr (true) zurück wenn der angegebene Dateiname oder das Verzeichnis existiert, andererseits falsch (false).
Der optionale Parameter <access str> ist nur unter Windows gültig. Gültige Werte sind 32bit, 64bit oder sysnative; sysnative ist der default Wert. Siehe hierzu Kapitel 64 Bit-Unterstützung
see also: [DirectoryExists]
see also: [FileExists]
-
DirectoryExists (
<path>) : bool
//since 4.12.1 [W/L/M]
Tests if <path> points to a directory.
<access str> = one of 32bit, 64bit, sysnative ; default sysnative ; ignored at non windows
see also: [FileOrFolderExists]
see also: [FileExists]
Examples:
if ($INST_SystemType$ = "64 Bit System")
set $ConstTest$ = "true"
Set $tmp$ = "C:\Windows\system32\Boot"
set $tmp1$ = "64bit"
set $CompValue$ = boolToString(DirectoryExists($tmp$,$tmp1$))
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $ConstTest$ = "true"
Set $tmp$ = "C:\Windows\system32\Boot"
set $tmp1$ = "sysnative"
set $CompValue$ = boolToString(DirectoryExists($tmp$,$tmp1$))
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $ConstTest$ = "true"
Set $tmp$ = "C:\Windows\system32\Boot"
; fall back to sysnative
set $CompValue$ = boolToString(DirectoryExists($tmp$))
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
set $ConstTest$ = "false"
Set $tmp$ = "C:\Windows\system32\Boot"
set $tmp1$ = "32bit"
set $CompValue$ = boolToString(DirectoryExists($tmp$,$tmp1$))
if ($ConstTest$ = $CompValue$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
endif
-
fileIsSymlink
(<file name>) // seit 4.12.4.21 [W/L/M]
Die Funktion gibt wahr zurück, wenn die genannte Datei oder das Verzeichnis existiert und ein symbolischer Link ist, ansonsten kommt die Antwort falsch.
-
LineExistsIn
(<Zeile>, <Dateiname>) [W/L/M]
Die Funktion gibt wahr zurück, wenn die Textdatei <Dateiname> eine Zeile beinhaltet, die im ersten Parameter beschrieben ist. Anderenfalls (oder falls die Datei garnicht existiert) wird falsch zurückgegeben.
Jeder Parameter ist ein String-Ausdruck.
-
LineBeginning_ExistsIn
(<string>, <Dateiname>) [W/L/M]
Die Funktion gibt wahr zurück, wenn in der Textdatei <Dateiname> eine Zeile vorhanden ist, welche mit dem Parameter <string> beginnt. Anderenfalls (oder falls die Datei garnicht existiert) wird falsch zurückgegeben.
Jeder Parameter ist ein String-Ausdruck.
-
LineContaining_ExistsIn(
<string>, <Dateiname>)
//since 4.11.4.10 [W/L/M]
Die Funktion gibt wahr zurück, wenn in der Textdatei <Dateiname> eine Zeile vorhanden ist, welche den Parameter <string> enthält. Anderenfalls (oder falls die Datei garnicht existiert) wird falsch zurückgegeben.
Jeder Parameter ist ein String-Ausdruck.
-
XMLAddNamespace
(<XMLfilename>, <XMLelementname>, <XMLnamespace>) [W]
Mit dieser Funktion wird eine XML Namensraum im ersten XML-Element-Tag mit dem vergebenen Namen definiert (falls noch nicht vorhanden). Er wird ausgegeben, wenn ein Name eingefügt wurde. Die opsi-script XML-Patch-Sektion benötigt diese Namensraumdefinition. Der File muss so formatiert werden, dass das Element-Tag keine Zeilenumbrüche beinhaltet. Für ein Anwendungsbeispiel siehe im Kochbuch Kapitel "Einfügen einer Namensraumdefinition in eine XML-Datei".
-
XMLRemoveNamespace
(<XMLfilename>, <XMLelementname>, <XMLnamespace>) [W]
Mit dieser Funktion wird die Definition des XML Namensraum wieder entfernt. Es wird wahr ausgegeben, wenn eine Entfernung erfolgt ist. (Beispiel im Kochbuch siehe Kapitel "Einfügen einer Namensraumdefinition in eine XML-Datei").
-
HasMinimumSpace
(<Laufwerksname>, <Kapazität>) [W]
gibt true zurück, wenn mehr Platz als die geforderte <Kapazität> auf dem Laufwerk <Laufwerksname> vorhanden ist. <Kapazität> ist syntaktisch ebenso wie <Laufwerksname> ein String-Ausdruck. Die <Kapazität> kann als Nummer ohne genauere Bezeichnung (dann interpretiert als Bytes) oder mit einer näheren Bezeichnung wie "kB", "MB" oder "GB" ausgegeben werden (case sensitive).
Anwendungsbeispiel:
if not (HasMinimumSpace ("%SYSTEMDRIVE%", "500 MB")) LogError "Es ist nicht genug Platz auf dem Laufwerk %SYSTEMDRIVE%, erforderlich sind 500 MB" isFatalError endif
-
opsiLicenseManagementEnabled
[W/L/M]
gibt true zurück wenn das opsi System über ein anwendbares (freigeschaltetes) Lizenzmanagement verfügt.
if opsiLicenseManagementEnabled set $mykey$ = DemandLicenseKey ("pool_office2007") else set $mykey$ = GetProductProperty("productkey","") endif
-
runningAsAdmin
[W]
Boolsche Funktion welche 'true' liefert wenn das laufende Script mit Administrativen Rechten ausgeführt wird.
Seit 4.11.1.1
-
isLoginScript
[W]
Boolsche Funktion welche 'true' liefert wenn das laufende Script über die opsi Erweiterung User Profile Management als userLoginScript läuft.
Seit 4.11.2.1
siehe auch : [isLoginScript]
-
contains(
<str>, <substr>`)` [W/L/M]
Boolsche Funktion welche 'true' liefert wenn <substr> in <str> enthalten ist. Die Funktion arbeitet case sensitive.
Seit 4.11.3
siehe auch : [contains]
-
isNumber(
<str>`)` [W/L/M]
Boolsche Funktion welche 'true' liefert wenn <str> einen ganzahligen Wert (integer) representiert.
Seit 4.11.3
siehe auch : [isNumber]
-
runningOnUefi
[W]+ Boolsche Funktion welche 'true' liefert wenn das laufende Betriebssystem im UEFI mode gebootet wurde.
Seit 4.11.4.3
-
runningInPE
//since 4.12.0.13: [W/L/M]
Boolsche Funktion welche 'true' liefert wenn das laufende Betriebssystem ein Windows PE ist.
-
runningInWAnMode
//since 4.12.4.16: [W/L/M]
Boolsche Funktion welche 'true' liefert wenn beim laufenden opsi-service Kontext der opsiserver = localhost ist.
-
isDriveReady(
<drive letter>`)` //since 4.11.4.4: [W]
Boolsche Funktion welche 'true' liefert auf das angebene Laufwerk zugegriffen werden kann (z.B. In Wechsellaufwerk ist ein Medium ist eingelegt)
-
saveTextFile(
<list>, < filename>`)` //since 4.11.4.4: [W/L/M]
Boolsche Funktion welche 'true' liefert wenn die Liste <list> erfolgreich in < filename> gespeichert wurde.
-
saveTextFileWithEncoding(
<list>, < filename>, <encoding>`) : bool` //since 4.11.6.4 [W/L/M]
Boolsche Funktion welche 'true' liefert wenn die Liste <list> erfolgreich in dem dem Zeichensatz <encoding> nach <filename> gespeichert wurde.
-
saveUnicodeTextFile(
<list>, < filename>, <encoding>`) : bool` //since 4.12.4.14 [W/L/M]
Boolsche Funktion welche 'true' liefert wenn die Liste <list> erfolgreich in dem dem Unicode Zeichensatz <encoding> nach <filename> gespeichert wurde.
-
CompareDotSeparatedNumbers(
<str1>,<relation str>,<str2>`)` //since 4.11.5.2: [W/L/M]
vergleicht zwei Strings vom Typ <zahl>[.<zahl>[.<zahl>[.<zahl>]]] unter Verwendung des <relation str>, welcher einen der folgenden Werte haben darf: [<,⇐,=,>=,>].
Seit Version 4.12.4.28: -
Wenn in einem Vergleichspaar mindestens eine <zahl> führende Nullen hat, dann werden beide Zahlwerte als Nachkommastellen verglichen, d.h.
17 > 018
denn0.17 > 0.018
. -
Wenn in einem Vergleichspaar mindestens eine <zahl> als letztes Zeichen keine Ziffer hat, dann wird zunächst nur der Zahlteil zum Vergleich herangezogen und bei Gleichheit auch der anhängende Buchstabe, d.h.
1.23a < 1.23b
und1.24a > 1.23b
.
siehe auch: Stringfunktion`CompareDotSeparatedNumbers(<string1>, <string2>
)>> : [CompareDotSeparatedNumbers_str]
<string1>, <string2>`)` : [CompareDotSeparatedStrings_str]
siehe auch: Stringfunktion `CompareDotSeparatedStrings(
siehe auch : [CompareDotSeparatedStrings_bool]
Example:
The code:
set $string1$ = "1.2.30.4.5"
set $string2$ = "1.20.30.4.5"
if CompareDotSeparatedNumbers($string1$, "<", $string2$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
if CompareDotSeparatedNumbers($string1$, "<=", $string2$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
if CompareDotSeparatedNumbers($string1$, "=<", $string2$)
comment "passed"
else
set $TestResult$ = "not o.k."
LogWarning "failed"
endif
if CompareDotSeparatedNumbers($string1$, "=", $string2$)
set $TestResult$ = "not o.k."
LogWarning "failed"
else
comment "passed"
endif
if CompareDotSeparatedNumbers($string1$, ">=", $string2$)
set $TestResult$ = "not o.k."
LogWarning "failed"
else
comment "passed"
endif
if CompareDotSeparatedNumbers($string1$, "=>", $string2$)
set $TestResult$ = "not o.k."
LogWarning "failed"
else
comment "passed"
endif
if CompareDotSeparatedNumbers($string1$, ">", $string2$)
set $TestResult$ = "not o.k."
LogWarning "failed"
else
comment "passed"
endif
produce the log:
Set $string1$ = "1.2.30.4.5"
The value of the variable "$string1$" is now: "1.2.30.4.5"
Set $string2$ = "1.20.30.4.5"
The value of the variable "$string2$" is now: "1.20.30.4.5"
If
Checking if "1.2.30.4.5" is "<" than / as "1.20.30.4.5"
CompareDotSeparatedNumbers($string1$, "<", $string2$) <<< result true
Then
comment: passed
Else
EndIf
If
Checking if "1.2.30.4.5" is "<=" than / as "1.20.30.4.5"
CompareDotSeparatedNumbers($string1$, "<=", $string2$) <<< result true
Then
comment: passed
Else
EndIf
If
Checking if "1.2.30.4.5" is "=<" than / as "1.20.30.4.5"
CompareDotSeparatedNumbers($string1$, "=<", $string2$) <<< result true
Then
comment: passed
Else
EndIf
If
Checking if "1.2.30.4.5" is "=" than / as "1.20.30.4.5"
CompareDotSeparatedNumbers($string1$, "=", $string2$) <<< result false
Then
Else
comment: passed
EndIf
If
Checking if "1.2.30.4.5" is ">=" than / as "1.20.30.4.5"
CompareDotSeparatedNumbers($string1$, ">=", $string2$) <<< result false
Then
Else
comment: passed
EndIf
If
Checking if "1.2.30.4.5" is "=>" than / as "1.20.30.4.5"
CompareDotSeparatedNumbers($string1$, "=>", $string2$) <<< result false
Then
Else
comment: passed
EndIf
If
Checking if "1.2.30.4.5" is ">" than / as "1.20.30.4.5"
CompareDotSeparatedNumbers($string1$, ">", $string2$) <<< result false
Then
Else
comment: passed
EndIf
Und seit 4.12.4.28:
if CompareDotSeparatedNumbers("4.2.2", ">", "4.2.00079") comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif if CompareDotSeparatedNumbers("0.9.8h", ">", "0.9.8e") comment "passed" else set $TestResult$ = "not o.k." LogWarning "failed" endif
-
CompareDotSeparatedStrings(
<str1>,<relation str>,<str2>`)` //since 4.11.5.2: [W/L/M]
vergleicht zwei Strings vom Typ <str>[.<str>[.<str>[.<str>]]] unter Verwendung des <relation str> der eins von den folgenden Werten haben darf: [<,⇐,=,>=,>].
siehe auch: StringfunktionCompareDotSeparatedStrings(
<string1>, <string2>`)` : [CompareDotSeparatedStrings_str]
siehe auch : [CompareDotSeparatedNumbers_bool]
siehe auch : [CompareDotSeparatedNumbers_str]
-
boolToString(
<boolean expression>`)` : bool string (true/false) // since 4.12.0.0 [W/L/M]
-
stringToBool(
<string expression: true/false>`)` : boolean // since 4.12.0.0 [W/L/M]
-
RegKeyExists(
<regkey>[,<access str>]) : bool
//since 4.12.0.16 [W]
Prüft ob der als <regkey> übergeben String als Rgistrykey existiert. Wird der Registrykey gefunden so wirdtrue
zurückgegeben, ansonsten false.
Die Zugriffsart ist per Defaultsysnative
. Über den optionalen zweiten Parameter kann die Zugriffsart auch explizit angegeben werden. Dabei muss der übergebene <access str> einer der folgenden Werte sein:32bit
,sysnative
,64bit
.
(siehe auch: Kapitel 64 Bit-Unterstützung)
Beispiele:
RegKeyExists("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon")
RegKeyExists("HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\general","32bit")
-
RegVarExists(
<regkey>, <var str>[,<access str>]) : bool
//since 4.12.0.16 [W]
Prüft ob der als <regkey> übergeben String als Registrykey existiert und ob dort eine Variable mit dem Namen <var str> existiert. Wird beides gefunden so wirdtrue
zurückgegeben, ansonsten false.
Die Zugriffsart ist per Defaultsysnative
. Über den optionalen dritten Parameter kann die Zugriffsart auch explizit angegeben werden. Dabei muss der übergebene <access str> einer der folgenden Werte sein:32bit
,sysnative
,64bit
.
(siehe auch: Kapitel 64 Bit-Unterstützung)
Beispiele:
RegVarExists("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","Shell")
RegVarExists("HKEY_LOCAL_MACHINE\SOFTWARE\opsi.org\general","bootmode","32bit")
-
runningWithGui : bool`
//since 4.12.3.6 [W/L/M] Liefert true wenn das ausgeführte Betriebsystem eine GUI hat (bei Win+Mac immer true)
isPingReachable(<host>) : boolean
//since 4.12.3.6 [W/L/M]
Liefert true wenn wenn die mit <host> angegebene Adresse per Ping erreichbar ist. Dabei kann <host> sowohl ein IP-Name als auch eine IP-Nummer sein.
Include Kommandos [W/L/M]
Die Verwendung von Include Kommandos führt schnell zu unübersichtlichen Code. Lassen Sie die Finger davon wenn Sie Anfänger sind. |
Include Kommandos: Syntax
Mit Include Kommandos kann der Inhalt einer externen Datei dem laufende Script hinzugefügt werden. Dies kann entweder einfügend oder anhängend erfolgen. Die Include Kommandos sind normale Kommandos der primären Sektionen. Die eingefügten Dateien können weitere Include Kommandos enthalten.
Diese Kommandos gibt es seit Version 4.11.3
-
include_insert
<file name> [W/L/M]
Fügt den Inhalt von <file name> nach der aktuellen Zeile im laufenden Script ein. Somit ist die erste Zeile der eingefügten Datei die nächste Zeile welche der opsi-script interpretiert.
-
include_append
<file name> [W/L/M]
Fügt den Inhalt von <file name> am Ende des laufenden Scriptes ein. Diese Anweisung dient vor allem dazu Sektionen aus z.B. einer Bibliothek hinzu zufügen.
Für beide Funktionen gilt:
<file name> ist:
-
Ein kompletter Pfad zu einer Datei. [W/L/M]
-
Eine Datei in
%ScriptPath%
[W/L/M] -
Eine Datei in
%opsiScriptHelperPath%\lib
[W]
Entspricht: '%ProgramFiles32Dir%\opsi.org\opsiScriptHelper\lib' -
Eine Datei in
%ScriptPath%/../lib
//since 4.11.5.2 [W/L/M] -
Eine Datei in
%OpsiScriptDir%\lib
[W]
Die Prüfung erfolgt in dieser Reihenfolge. Die erste Datei die gefunden wird, wird genommen.
Beispiel:
Wir haben folgendes Script:
[Actions]
include_append "section_Files_del_tmp_dummy.opsiinc"
include_insert "include-test1.opsiinc"
Dabei hat die Datei include-test1.opsiinc
folgenden Inhalt:
DefVar $inctestvar$
set $inctestvar$ = "inctest"
Files_del_tmp_dummy
include_append "section_Files_copy_inctest.opsiinc"
Files_copy_inctest
if fileExists("c:\opsi.org\tmp\dummy.txt")
comment "passed"
else
comment "failed"
set $TestResult$ = "not o.k."
LogWarning "include test failed"
endif
if fileExists("%scriptpath%\test-files\dummy.txt")
comment "passed"
else
comment "failed"
set $TestResult$ = "not o.k."
LogWarning "include test failed"
endif
Files_del_tmp_dummy
Dabei hat die Datei section_Files_copy_inctest.opsiinc
folgenden Inhalt:
[Files_copy_inctest]
copy "%scriptpath%\test-files\dummy.txt" "c:\opsi.org\tmp"
Dabei hat die Datei section_Files_del_tmp_dummy.opsiinc
folgenden Inhalt:
[Files_del_tmp_dummy]
del -f "c:\opsi.org\tmp\dummyt.txt"
Include Kommandos: Library
Mit der Version 4.11.3 werden folgende Includefiles in %OpsiScriptDir%\lib
ausgeliefert:
insert_check_exit_code.opsiinc
:
; opsi include file
DefVar $ExitCode$
include_append "section_sub_check_exitcode.opsiinc"
insert_get_licensekey.opsiinc
:
; opsi include file
DefVar $LicenseRequired$
DefVar $LicenseKey$
DefVar $LicensePool$
include_append "section_sub_get_licensekey.opsiinc"
section_sub_check_exit_code.opsiinc
:
;opsi include file
[Sub_check_exitcode]
comment "Test for installation success via exit code"
set $ExitCode$ = getLastExitCode
; informations to exit codes see
; http://msdn.microsoft.com/en-us/library/aa372835(VS.85).aspx
; http://msdn.microsoft.com/en-us/library/aa368542.aspx
if ($ExitCode$ = "0")
comment "Looks good: setup program gives exitcode zero"
else
comment "Setup program gives a exitcode unequal zero: " + $ExitCode$
if ($ExitCode$ = "1605")
comment "ERROR_UNKNOWN_PRODUCT 1605 This action is only valid for products that are currently installed."
comment "Uninstall of a not installed product failed - no problem"
else
if ($ExitCode$ = "1641")
comment "looks good: setup program gives exitcode 1641"
comment "ERROR_SUCCESS_REBOOT_INITIATED 1641 The installer has initiated a restart. This message is indicative of a success."
ExitWindows /Reboot
else
if ($ExitCode$ = "3010")
comment "looks good: setup program gives exitcode 3010"
comment "ERROR_SUCCESS_REBOOT_REQUIRED 3010 A restart is required to complete the install. This message is indicative of a success."
ExitWindows /Reboot
else
logError "Fatal: Setup program gives an unknown exitcode unequal zero: " + $ExitCode$
isFatalError "Exit Code: "+ $ExitCode$
endif
endif
endif
endif
section_sub_get_licensekey.opsiinc
:
; opsi include file
[Sub_get_licensekey]
if opsiLicenseManagementEnabled
comment "License management is enabled and will be used"
comment "Trying to get a license key"
Set $LicenseKey$ = demandLicenseKey ($LicensePool$)
; If there is an assignment of exactly one licensepool to the product the following call is possible:
; Set $LicenseKey$ = demandLicenseKey ("", $ProductId$)
;
; If there is an assignment of a license pool to a windows software id, it is possible to use:
; DefVar $WindowsSoftwareId$
; $WindowsSoftwareId$ = "..."
; Set $LicenseKey$ = demandLicenseKey ("", "", $WindowsSoftwareId$)
DefVar $ServiceErrorClass$
set $ServiceErrorClass$ = getLastServiceErrorClass
comment "Error class: " + $ServiceErrorClass$
if $ServiceErrorClass$ = "None"
comment "Everything fine, we got the license key '" + $LicenseKey$ + "'"
else
if $ServiceErrorClass$ = "LicenseConfigurationError"
LogError "Fatal: license configuration must be corrected"
LogError getLastServiceErrorMessage
isFatalError $ServiceErrorClass$
else
if $ServiceErrorClass$ = "LicenseMissingError"
LogError "Fatal: required license is not supplied"
isFatalError $ServiceErrorClass$
endif
endif
endif
else
LogError "Fatal: license required, but license management not enabled"
isFatalError "No Licensemanagement"
endif
Aufrufe von Unterprogrammen [W/L/M]
Anweisungen in primären Sektionen, die auf einen Programmtext an anderer Stelle verweisen, sollen hier Unterprogramm- oder Prozeduraufrufe heißen.
if ($MSVersion$>="6")
sub_install_win7
else
if ( $MSVersion$ = "5.1" )
sub_install_winXP
else
stop "not a supported OS-Version"
endif
endif
So "ruft" in obigem Beispiel die Anweisung in der Actions
-Sektion
sub_install_winXP
die Sektion '[sub_install_winXP]', welche dann im Skript an anderer Stelle nachzulesen ist als
[sub_install_winXP]
Files_Kopieren_XP
WinBatch_SetupXP
Weil es sich in diesem Beispiel um eine Sub
-Sektion handelt, also immer noch um eine primäre Sektion, kann in ihr wiederum auf weitere Sektionen verwiesen werden, in diesem Fall auf die Sektionen '[Files_Kopieren_XP]' und '[WinBatch_Setup_XP]'.
Generell gibt es drei Wege um die genannten Anweisungen zu platzieren:
-
Der gebräuchlichste Ort für den Aufruf eines
Sub
-Sektion ist eine weitere interne Sektion im Skript, wo die aufgerufene Befehle platziert werden (wie in dem Beispiel). -
Die bezeichneten Befehle können auch in einer andere Datei untergebracht werden, welche als externe Sektion läuft.
-
Jede String-Liste kann als eine Befehlsliste für einen Sub-Programm Aufruf benutzt werden.
Zur Syntax der Sub-Programm Aufrufe im einzelnen:
Komponenten eines Unterprogrammaufrufs
Formal kann die Syntax wie folgt aufgerufen werden
'<proc. type>(<proc. name> | <External proc. file> | <Stringlisten Funktion> )'
Diese Ausdrücke können durch einen oder mehrere Parameter ergänzt werden (ist vom Ablauftyp abhängig).
Das bedeutet: Ein Ablauf besteht aus drei Hauptbereichen.
Der erste Teil ist der Unterprogramm Typnamen.
Beispiele für Typennamen sind Sub
(Aufruf einer primären Sektion bzw. eines Unterprogramms des primären Typs) sowie Files
und WinBatch
(diese Aufrufe sind speziell für die zweite Sektion).
Den kompletten Überblick über die existierenden Sub
-Programmtypen sind am Anfang von Kapitel "Aufrufe von Unterprogrammen" genauer beschrieben.
Der zweite Teil bestimmt, wo und wie die Zeilen des Subprogramms gefunden werden. Dazu gibt es zwei Möglichkeiten:
-
Das Sub-Programm ist eine Zeilenabfolge, die im sich ausführbaren Bereich des opsi-script Skriptes als interne Sektion befindet. Es wird ein eindeutiger Sektionsname (bestehend aus Buchstaben, Zahlen und einigen Sonderzeichen) hinzugefügt, um den Programmtyp näher zu beschreiben (ohne Leerzeichen).
z.B.
'sub_install_winXP'
oder
'files_copy_winXP'
Sektionsnamen sind case insensitive wie jeder andere String. -
Wenn der Programmtyp alleine steht, wird eine String-Liste oder ein String-Ausdruck erwartet. Wenn der folgende Ausdruck nicht als String-Listenausdruck aufgelöst werden kann (vgl. 3.) wird ein String-Ausdruck erwartet. Der String wird dann als Dateiname interpretiert. Der opsi-script versucht die Datei als Textdatei zu öffnen und interpretiert die Zeilen als eine externe Sektion des beschriebenen Typs.
Bsp.:
sub
'"p:\install\opsiutils\mainroutine.opsiscript"'
Es wird versucht die Zeile mainroutine.opsiscript als Anweisung der Subsektion auszulesen.
Der String wird als Dateiname interpretiert und kann dabei folgendes sein:-
Ein kompletter Pfad zu einer Datei. [W/L/M]
-
Eine Datei in
%ScriptPath%
[W/L/M] -
Eine Datei in
%opsiScriptHelperPath%\lib
[W]
Entspricht: '%ProgramFiles32Dir%\opsi.org\opsiScriptHelper\lib' -
Eine Datei in
%ScriptPath%/../lib
[W/L/M] -
Eine Datei in
%OpsiScriptDir%\lib
[W]
-
Die Prüfung erfolgt in dieser Reihenfolge. Die erste Datei die gefunden wird, wird genommen.
-
Wenn der Ausdruck auf eine alleinstehenden spezifizierten Sektionstyp folgt, kann dieser als ein String-Listenausdruck aufgelöst werden. Die String-Listenkomponenten werden dann als ein Sektionsausdruck interpretiert.
Dieser Mechanismus kann bspw. dazu verwendet werden, um eine Datei mit Unicode-Format zu laden und dann mit den üblichen Mechanismen zu bearbeiten:
registry loadUnicodeTextFile("%scriptpath%/opsiorgkey.reg") /regedit
Syntaktisch hat diese Zeile die drei Bestandteile:
* registry
, die eigentliche Anweisung, die den Sektionstyp spezifiziert.
* loadUnicodeTextFile (..)
, ein String-Listenausdruck, in dem näher beschrieben ist, wie man eine Zeile der registry
Sektion bekommt.
* /regedit
, Option als 2. Parameter (typspezifisch, s. das Folgende).
In diesem Beispiel gibt der Aufrufparameter ein Beispiel an für den dritten Teil eines Subsektionsaufrufs:
Der dritte Part eine Aufrufs umfasst spezielle Aufrufsoptionen. Referenzen für die Aufrufsoptionen beziehungsweise für eine genauere Beschreibung der Sektionsaufrufe finden sich in siehe Kapitel "Sekundäre Sektionen".
Reboot-Steueranweisungen
Die Anweisung ExitWindows
dient zur Steuerung von Reboot, Shutdowns, u.ä. Vorgängen welche erst nach Beendigung des opsi-script selbst durchgeführt werden. Die Benennung des Befehls und die Tatsache, das es ExitWindows
nicht ohne Modifier gibt, ist historisch bedingt: Unter Windows 3.1 konnte man Windows beenden und zur DOS-Ebene zurück wechseln.
-
ExitWindows /RebootWanted
Abgekündigt: vermerkt eine Rebootanfrage eines Skriptes in der Registry, lässt aber das opsi-script Skript weiterlaufen und weitere Skripte abarbeiten und rebootet erst, wenn alle Skripte durchgelaufen sind. Eigentlich wird dieses Kommando jetzt alsExitWindows /Reboot
behandelt (da ansonsten eine Installation fehlschlagen könnte, weil ein benötigtes Produkt nicht komplett installiert wurde).
-
ExitWindows /Reboot
[W/L/M]
unterbricht eine Skriptfolge durch die Auslösung des Reboots nachdem der opsi-script die Bearbeitung des laufenden Skriptes beendet hat.
-
ExitWindows /ImmediateReboot
[W/L/M]
unterbricht die normale Ausführung eines Skriptes, an der Stelle, an der er aufgerufen wird. Nach dem der Befehl aufgerufen wurde, werden (außer if-Anweisungen) keine Anweisungen mehr ausgeführt und der Rechner rebootet. Dabei bleibt in der opsi-Umgebung der Actionrequest der das Skript aufgerufen hat bestehen.Dadurch wird gewährleistet, dass nach dem Neustart der opsi-script wieder das Skript, dass abgebrochen wurde, startet. Das Skript sollte daher so konzipiert sein, dass die Ausführung nach dem Punkt der Unterbrechung fortgesetzt wird (andernfalls erhalten wir möglicherweise eine Endlosschleife…) vgl. das Beispiel in diesem Abschnitt.
-
ExitWindows /ImmediateLogout
[W]
funktioniert ähnlich wie der Aufruf /ImmediateReboot, aber beinhaltet ein Beenden des opsi-script (Beenden des Skriptes) statt einen Reboot. Dies ist dann sinnvoll, wenn nachfolgend ein automatisches Login (eines anderen Users) folgen soll. Beachten Sie hierzu Kapitel "Skript für Installationen im Kontext eines lokalen Administrators".
-
ExitWindows /ShutdownWanted
[W]
sorgt dafür, dass der PC nach Abschluss der Installation aller angefragten Produkte heruntergefahren wird.
Wie man eine Markierung setzt, um sicherzustellen, dass das Skript nicht in eine Endlosschleife läuft, wenn ExitWindows /ImmediateReboot
aufgerufen wird, demonstriert folgendes Codebeispiel:
DefVar $Flag$
DefVar $WinstRegKey$
Set $WinstRegKey$ = "HKLM\SOFTWARE\opsi.org\winst"
Set $Flag$ = GetRegistryStringValue32("["+$WinstRegKey$+"] "+"RebootFlag")
if not ($Flag$ = "1")
;=========================
; Anweisungen vor Reboot
Files_doSomething
; Reboot initialisieren ...
Set $Flag$ = "1"
Registry_SaveRebootFlag
ExitWindows /ImmediateReboot
else
;=========================
; Anweisungen nach Reboot
; Rebootflag zurücksetzen
Set $Flag$ = "0"
Registry_SaveRebootFlag
; die eigentlichen Anweisungen
Files_doMore
endif
[Registry_SaveRebootFlag]
openKey [$WinstRegKey$]
set "RebootFlag" = "$Flag$"
[Files_doSomething]
; eine Sektion, die vor dem Reboot ausgeführt wird
[Files_doMore]
; eine Sektion, die nach dem Reboot ausgeführt wird
Scriptabbruch und fehlgeschlagene Installation anzeigen [W/L/M]
Passieren bei einer Installation Fehler, die zum Fehlschlagen der Installation führen, so sollte dies an den Server zurückgemeldet werden.
Um in einem opsi-script Skript, eine Installation als gescheitert zu erklären, gibt es eine Ausdruck namens
isFatalError
[W/L/M]
unterbricht die normale Ausführung eines Skriptes, an der Stelle, an der er aufgerufen wird. Nach dem der Befehl aufgerufen wurde, werden keine Anweisungen mehr ausgeführt und als Skriptergebnis wird 'failed' zurückgeliefert. Wird dieser Befehl nicht aufgerufen, so ist das Skriptergebnis 'success'.
Seit 4.11.3.2 ist auch die folgende Variante erlaubt:
-
isFatalError
<string> [W/L/M]
wobei <string> als kurze Fehlerbeschreibung an den opsi-server als 'actionProgress' weitergegeben wird und im opsi-configed angezeigt wird.
Es gibt keinen Automatismus innerhalb eines Winst-Skriptes, um zu einen 'failed' Ergebnis zu kommen. Sie müssen skriptgesteuert den Fehler selbst feststellen. Hierzu gibt Ihnen der opsi-script einige Hilfsmittel.
Ein „fataler Fehler“ sollte zum Beispiel ausgelöst werden, wenn der Plattenplatz für die Installation nicht ausreicht:
DefVar $SpaceNeeded$"
Set $SpaceNeeded$" = "200 MB"
if not(HasMinimumSpace ("%SYSTEMDRIVE%", $SpaceNeeded$"))
LogError "Nicht genügend Platz. Erforderlich sind "+$SpaceNeeded$
isFatalError
; beendet die Skriptausführung und setzt den Produktstatus auf failed
else
; die Installation wird gestartet
; ...
endif
Fehler die von Funktionen des opsi-script zurückgeliefert werden, werden in die Logdatei geschrieben und erhöhen den Fehlerzähler des opsi-script. Dieser Fehlerzähler kann ausgewertet werden. So besteht auch die Möglichkeit, in einem kritischen Abschnitt eines Skriptes festzustellen, ob Fehler bzw. wie viele Fehler aufgetreten sind (und abhängig hiervon ggf. isFatalError aufzurufen).
-
markErrorNumber
[W/L/M]
startet die Fehlerzählung für einen Abschnitt.
Die Zahl der Fehler, die ab dieser Stelle aufgetreten sind, kann dann abgerufen werden mit dem Ausdruck:errorsOccurredSinceMark
-
errorsOccurredSinceMark
[W/L/M]
wird verwendet um das Auftreten von Fehlern seit dem Aufruf vonmarkErrorNumber
zu ermitteln. Dieser Ausdruck dient dann zum Vergleich mit einer Zahl.
Z.B. kann man die Bedingung „es kam in diesem Abschnitt mindestens ein Fehler vor“ so formulieren:
if errorsOccurredSinceMark > 0
Sofern die Skriptanweisungen nicht direkt einen Fehler produzieren, jedoch aufgrund bestimmter Umstände eine Situation trotzdem als Fehlersituation gewertet werden soll, kann auch mittels der Anweisung logError
eine Fehlermeldung generiert werden.
markErrorNumber
; Fehler, die nach dieser Marke auftreten werden gezählt
; und werden als fatale Fehler gewertet
logError "test error"
; wir schreiben einen Kommentar "test error" in die Logdatei
; und die Fehleranzahl wird um eins erhöht
; für Testzwecke kann man diese Zeile auskommentieren
if errorsOccurredSinceMark > 0
; die Skriptausführung wird so bald wie möglich beendet
; und setzt den Produktstatus auf "failed"
isFatalError
; Kommentare können noch geschrieben werden
comment "error occured"
else
; kein Fehler aufgetreten, gibt folgendes aus:
comment "no error occured"
endif
-
isSuccess
//since 4.11.3.7 [W/L/M]
Bricht das Script ab ohne einen Fehler zu melden.
-
noUpdateScript
//since 4.11.3.7 [W/L/M]
Führt nach einem Setup kein Updatescript aus auch wenn eines vorhanden ist.
-
isSuspended
//since 4.11.4.1 [W/L/M] Bricht die Scriptabarbeitung ab ohne das ein Erfolg oder Fehler gemeldet werden. Der ActionRequest (z.B. 'setup') bleibt unverändert.
Lokale Funktionen [W/L/M]
Seit Version 4.12 kennt opsi-script auch lokale Funktionen.
Ein Beispiel:
DefFunc myFunc(val $str1$ : string, $str2$ : string) : string
set $result$ = $str1$ + $str2$
endfunc
Konzept
Ziel dieser Erweiterung ist die Umsetzung folgender Konzepte:
-
Funktionen mit Rückgabewert:
Die Funktionen haben einen Rückgabewert, welcher vom Typstring
oderstringlist
ist. Der Aufruf einer solchen Funktion kann überall da erfolgen, wo ein Stringausdruck bzw. eine Stringliste erwartet wird.
Funktionen ohne Rückgabewert sind ab 4.12.0.16 auch erlaubt und müssen alsvoid
deklariert werden. -
Frei definierbare Aufrufparameter: Einer Funktion können Parameter übergeben werden. Diese Parameter werden bei der Deklaration der Funktion definiert. Die Aufrufparameter können vom Typ
string
oderstringlist
sein.
Die Aufrufparameter können als 'CallByValue' oder per 'CallByReference' übergeben werden. 'CallByValue' ist der Default, das bedeutet: Wird keine Aufrufmethode explizit angegeben, so wird 'CallByValue' verwendet. Soll 'CallByValue' explizit angegeben werden, so erfolgt dies über das Schlüsselwortval
. 'CallByValue' bedeutet, dass beim Aufruf der Funktion der Inhalt des Ausdrucks für einen Aufrufparameters auf die lokale Variable des Aufrufparameters kopiert wird.
'CallByReference' muss über das Schlüsselwortref
explizit angegeben werden. 'CallByReference' bedeutet, dass beim Aufruf eine Verbindung zwischen der aufrufenden Variable und dem lokalen Aufrufparameter erstellt wird. Eine Änderung der lokalen Variable des Aufrufparameters wirkt sich direkt auf die beim Aufruf verwendete Variable aus.
Die Übergabeparameter stehen innerhalb der Funktion als lokale Variablen zur Verfügung. -
Lokale Variablen:
Eine Funktion enthält lokale Variablen. Implizit gibt es die Aufrufparameter als lokale Variablen und die Variable$result$
, welche vom Typ des Rückgabewertes ist. Darüberhinaus können weitere Variablen innerhalb der Funktion definiert werden.
All dies Variablen sind lokal, d.h. sie sind nur innerhalb dieser Funktion sichtbar. Eine lokale Variable mit dem selben Namen einer globalen Variable verdeckt innerhalb der Funktion die entsprechende globale Variable. -
Geschachtelte Funktionen:
Eine lokale Funktion kann wiederum eine oder mehrere Definitionen von lokalen Funktionen enthalten. Diese Funktionen sind nur innerhalb der Funktion sichtbar, in der sie definiert sind. -
Rekursive Aufrufe:
Eine Funktion kann sich selbst rekursiv aufrufen. -
Primäre und sekundäre Sektionen innerhalb von Funktionen:
Der Funktionskörper kann eigene Sektionen enthalten. Diese sind lokal zu dieser Funktion, also nur innerhalb der Funktion sichtbar.
Syntax
Definition
DefFunc <func name>([calltype parameter ptype][,[calltype parameter ptype]]) : ftype <function body> endfunc
Dabei ist:
-
DefFunc
das Schlüsselwort zur Beginn der Definition einer lokalen Funktion. -
'<func name>' der frei gewählte Name der Funktion.
-
'calltype' der Aufruftyp [
val
|ref
]. Wird kein Aufruftyp angegeben, so giltval
als gesetzt. -
'parameter' der freigewählte Name des Aufrufparameters, welcher unter diesem Namen innerhalb der Funktion als lokale Variable zur Verfügung steht.
-
'ptype' der Datentyp des Parameters und entweder
string
oderstringlist
. -
'ftype' der Datentyp der Funktion und entweder
string
,stringlist
odervoid
. Dievoid
-Deklaration bedeutet, dass es keine Rückabe gibt. -
'<function body>' der Körper der Funktion, welcher dem opsi-script Syntax genügen muss.
In diesem Teil gibt es die automatisch erzeugte lokale Variable$result$
, welche den Datentyp der Funktion hat (String/Stringliste) und dazu dient, den Rückgabewert aufzunehmen. -
endfunc
das Schlüsselwort am Ende einer Funktionsdefinition.
Eine Funktion muss definiert werden bevor sie aufgerufen werden kann.
Beispiele
Einfache Funktion welche zwei Strings miteinander verbindet:
[actions]
DefVar $mystr$
DefVar $str1$
set $str1$ = 'ha'
DefFunc myFunc(val $str1$ : string, $str2$ : string) : string
set $result$ = $str1$ + $str2$
endfunc
set $mystr$ = myFunc("he","ho")
set $mystr$ = myFunc("he",timeStampAsFloatStr)
set $mystr$ = myFunc("he",$str1$)
Erwartete Ergebnisse:
-
'heho'
-
'he42921.809'
-
'heha'
Funktion vom Type stringlist
welcher ein string
und eine stringlist
übergeben werden:
[actions]
DefVar $mystr$
DefVar $str1$
DefStringlist $list1$
DefStringlist $list2$
set $str1$ = 'ha'
DefFunc myFunc1(val $str1$ : string, $list1$ : stringlist) : stringlist
set $result$ = createStringlist($str1$ , takeString(2,$list1$))
endfunc
set $list2$ = splitstring("/etc/opsi/huhu","/")
set $list1$ = myFunc1("hi",$list2$)
Erwartete Ergebnisse:
-
$list1$ = [hi,opsi]
Funktion vom Type string
welcher ein boolscher string
übergeben wird:
[actions]
DefFunc myFunc2($str1$ : string) : string
set $result$ = booltostring($str1$)
endfunc
if stringtobool(myfunc2('1 > 0'))
comment "true"
else
comment "false"
endif
Erwartete Ergebnisse:
-
'true'
Funktion vom Type string
welcher ein string
übergeben wird
mit lokaler Variable:
[actions]
DefVar $mystr$
DefFunc myFunc3($str1$ : string) : string
DefVar $locstr1$
set $locstr1$ = '123'
set $result$ = $locstr1$ + $str1$
endfunc
set $mystr$ = myFunc3("he")
Erwartete Ergenisse:
-
'123he'
Funktion vom Type string
welcher ein string
übergeben wird
mit lokaler Variable und geschachtelter Funktion:
[actions]
DefVar $mystr$
DefFunc myFunc4($str1$ : string) : string
DefVar $locstr1$
DefFunc myFunc5($str1$ : string) : string
set $result$ = 'inner' + $str1$
endfunc
set $locstr1$ = '123'
set $result$ = $str1$ + myFunc5($locstr1$)
endfunc
set $mystr$ = myFunc4("outer")
Erwartete Ergebnisse:
-
'outerinner123'
Einfache Funktion vom Type string
welcher ein string
by reference übergeben wird mit lokaler Variable:
[actions]
DefVar $mystr$
DefVar $str1$
DefVar $str2$
set $str1$ = 'ha'
set $str2$ = 'hi'
DefFunc myFunc6(ref $str1$ : string) : string
DefVar $locstr1$
set $locstr1$ = '123'
set $str1$ = 'setinlocal'
set $result$ = $locstr1$ + $str1$
endfunc
set $mystr$ = myFunc6($str2$)
set $mystr$ = $str1$ + $str2$
Erwartete Ergebnisse:
-
'123setinlocal'
-
'hasetinlocal'
Funktion vom Type stringlist
welcher eine Variable vom Type stringlist
mit 'call by reference' übergeben wird mit lokalen stringlist
Variable:
[actions]
DefVar $mystr$
DefStringlist $list1$
DefStringlist $list2$
et $list2$ = splitstring("/etc/opsi/huhu","/")
DefFunc myFunc7(ref $list1$ : stringlist) : stringlist
DefStringlist $loclist1$
set $loclist1$ = splitstring("/a/b/c","/")
set $list1$ = createStringList('setinlocal')
set $loclist1$ = addListToList($loclist1$,$list1$)
set $result$ = $loclist1$
endfunc
set $list1$ = myFunc7($list2$)
comment "$list2$ index 0: " + takestring(0,$list2$)
Erwartete Ergenisse:
-
$list1$ = [,a,b,c,setinlocal]
-
'setinlocal'
Funktion vom Type stringlist
welcher ein string
übergeben wird
mit lokaler Variable und lokaler sekundärer Sektion:
[actions]
DefStringlist $list1$
DefFunc myFunc8($str1$ : string) : stringlist
DefStringlist $loclist1$
set $loclist1$ = getoutstreamfromsection("shellInAnIcon_test")
set $result$ = $loclist1$
[shellinanicon_test]
set -x
$str1$
endfunc
set $list1$ = myFunc8('pwd')
Erwartete Ergebnisse:
-
$list1$ = [+ pwd, /home/uib/gitwork/lazarus/opsi-script]
Funktion vom Type void
(also ohne Rückgabe) welcher ein string
übergeben wird:
[actions]
ScriptErrorMessages = false
DefVar $str1$
set $str1$ = 'haha'
DefFunc myNoResultFunc(ref $str1$ : string) : void
set $str1$ = "huhu"
endfunc
myNoResultFunc($str1$)
comment "$str1$ is: "+$str1$
Erwartete Ergebnisse:
-
$str1$ is: huhu
Funktion vom Type string
welcher kein Parameter übergeben wird:
[actions]
ScriptErrorMessages = false
DefVar $str1$
DefFunc myNoParamFunc() : string
set $result$ = "huhu"
endfunc
set $str1$ = myNoParamFunc()
Erwartete Ergebnisse:
-
$str1$ is: huhu
Import von Library Funktionen [W/L/M]
importLib
<string expr> ; import library // since 4.12.0.0
<string expr> : <file name>[.<file extension>][::
<function name>]
Wenn keine '.<file extension>' (Dateierweiterung übergeben wird, so wird .opsiscript
als Default verwendet.
Wenn kein '::<function name>' über geben wird, so werden alle Funktionen der angegebenen Datei importiert.
<file name> ist:
-
Ein kompletter Pfad zu einer Datei. [W/L/M]
-
Eine Datei in
%ScriptPath%
[W/L/M] -
Eine Datei in
%opsiScriptHelperPath%\lib
[W]
Entspricht: '%ProgramFiles32Dir%\opsi.org\opsiScriptHelper\lib' -
Eine Datei in
%ScriptPath%/../lib
//since 4.11.5.2 [W/L/M] -
Eine Datei in
%OpsiScriptDir%\lib
[W] oder/usr/share/opsi-script/lib
[L]
Die Prüfung erfolgt in dieser Reihenfolge. Die erste Datei die gefunden wird, wird genommen.
User Profile Management [W/L/M]
Diese Erweiterung funktioniert nicht zusammen mit der WAN-Erweiterung! Schalten Sie auf WAN-Clients bitte das Login-Event nicht an. |
Einführung
Der opsi-script verfügt über eine Reihe von speziellen Befehlen um Modifikationen in Profilen vorzunehmen. Diese Arbeiten aber auf den lokalen Profilen und sind beim Einsatz von Roaming Profiles (Servergespeicherte Profile) weitgehend nutzlos. Mit der opsi Erweiterung User Profile Management wird eine Möglichkeit geschaffen auch hier Veränderungen an den Profilen vorzunehmen. Dies geschieht in dem beim User Login der opsi-script gestartet wird um spezielle userLoginScripte auszuführen.
Konzept
Wenn die Profile nicht bei der Installation der Software gleich mit gepatcht werden können, muss zwischen dem Maschinen Teil und dem Profil Teil der Installation deutlicher unterschieden werden. Die kann sowohl innerhalb eines Scriptes geschehen, als auch durch die Auslagerung des Profil Teils in ein eigenes Script.
Die Kernkonzepte dieser opsi Erweiterung sind:
-
Ausführen spezieller userLoginScripte beim Login des users
Im Rahmen des User Logins wird der opsi-script gestartet aber in einem speziellem Modus ausgeführt in dem nur bei den Produkten hinterlegte 'userLoginScripte' ausgeführt werden. -
Ausführen der Scripte mit administrativen Rechten aber im Userkontext
Domain Login Scripte werden vom User mit user Rechten ausgeführt. Die opsi 'userLoginScripte' werden vom opsi-script ausgeführt, welcher mit administrativen Rechten läuft. Gleichzeitig begibt sich der opsi-script aber in den Kontext des Users der sich eingelogged hat, so dass die Manipulation der Profile mit den selben Befehlen durchgeführt werden kann, wie in einem Domain Loginscript. -
Ausführen der Scripte innerhalb des opsi-service Kontext
Die opsi userLoginScripts laufen innerhalb des opsi-service Kontextes und haben so über Scriptkonstanten die Informationen zu Produktnamen, Version und Packageversion die gerade bearbeitet wird. Weiterhin sind die Werte der Produktproperties im Zugriff sowie alle sonstigen Informationen welche eventuell über opsiservicalls abgerufen werden sollen.
Spezielle opsi-script Funktionen
-
Aufrufparameter
/allloginscripts
oder/loginscripts
Wird der opsi-script im opsi-service Kontext mit dem zusätzlichen Parameter/allloginscripts
oder/loginscripts
aufgerufen, so hat das im wesentlichen folgende Auswirkungen:-
Es werden die Produkte ermittelt, welche ein 'userLoginScript' haben.
Bei/allloginscripts
werden für alle diese Produkte die 'userLoginScripte' ausgeführt.
Bei/loginscripts
werden nur die Loginscripts auf einem Client ausgeführt, bei denen das entsprechende Produkt dem Client bekannt ist, also installiert ist oder war.
Siehe auch: Konfiguration -
Es wird der user der sich eingelogt hat ermittelt und dafür gesorgt, dass die Konstanten zum aktuellen User wie z.B. %CurrentAppdataDir% auf die entsprechenden Verzeichnisse des eingelogten users zeigen. Ebenso werden Registry Operationen (
Registry
Sektionen undGetRegistryString
) welche sich auf HKCU beziehen, so ausgeführt, dass die Daten aus dem Registryzweig des Users kommen.
-
-
Aufrufparameter
/silent
Der Aufrufparameter/silent
sorgt dafür, dass während der Scriptabarbeitung das Fenster des opsi-script nicht angezeigt wird. -
Funktion
GetScriptMode
Um innerhalb eines Scriptes zu unterscheiden in welchem Modus das Script gerade ausgeführt wird, liefert die FunktionGetScriptMode
zwei mögliche Werte zurück:-
'Machine'
Das Script wird nicht als 'userLoginScript' ausgeführt (sondern z.B. als setup oder uninstall Script). -
'Login'
Das Script wird als 'userLoginScript' ausgeführt.
-
-
Primäre Sektion ProfileActions
diese Sektion kann dazu dienen, Aktionen auf Userprofilen zusammenzufassen. Dabei kann eine Syntax verwendet werden, die es ermöglicht, diese Sektion sowohl als Bestandteil eines normalen Loginscripts, als auch als 'userLoginScript' zu nutzen. Dazu wird diese primäre Sektion auf unterschiedliche Art ausgewertet, je nachdem ob das script im Machine mode oder Login mode (also als userLoginScript) läuft.-
'Login'
Läuft ein Script als 'userLoginScript' und enthält eine Sektion ProfileActions, so wird die Scriptabarbeitung bei dieser Sektion gestartet (und nicht bei Actions). -
'Machine'
Läuft ein Script als normales Installationsscript, so kann die Sektion ProfileActions ähnlich einer 'Sub'-Sektion als Untersektion aufgerufen werden. Für die Abarbeitung dieser Sektion gilt: Für alle 'Registry'-Sektions Aufrufe ist implizit '/AllNtUserDats' gesetzt. Für alle 'Files'-Sektions Aufrufe ist implizit '/AllNtUserProfiles' gesetzt.
Seit Version 4.11.3.2 gilt auch: Für alle 'Patches'-Sektions Aufrufe ist implizit '/AllNtUserProfiles' gesetzt.
-
-
Registry Sektionen
-
Registry Sektionen welche auf 'HKCU' bzw. 'HKEY_CURRENT_USER' arbeiten, werden im Loginscript Mode so ausgeführt, dass die Änderungen im Zweig des eingeloggten users landen. Entsprechendes gilt für die Funktionen
GetRegistryStringValue*
. -
Registry Sektionen welche im Normalen Modus ('Machine') mit dem Modifier '/AllNtUserDats' aufgerufen werden, dürfen jetzt in der
openkey
Anweisung den Root 'HKCU' bzw. 'HKEY_CURRENT_USER' enthalten. Dies ermöglicht es, dieselbe Registry Sektion in den unterschiedlichen Modi auszuführen.
-
-
Winbatch Sektionen mit
/RunAsLoggedOnUser
der opsi-script läuft auch wenn er über das Loginevent gestartet wird im SYSTEM Kontext und nicht im Kontext des users, der sich gerade eingeloggt hat. Um einen Prozess im Kontext dieses users zu starten, kann eine winbatch Sektion mit der Option/RunAsLoggedOnUser
verwendet werden. -
Vermeidung unnötiger Läufe:
Mit den BefehlsaveVersionToProfile
kann im aktuelle Profil hinterlegt werden, dass das userLoginscript zu diesem Produkt in dieser Version gelaufen ist. Mit der StringfunktionreadVersionFromProfile
bzw. der boolschen FunktionscriptWasExecutedBefore
kann überprüft werden, ob das userLoginScript zu diesem Produkt in dieser Version zuvor schon einmal gelaufen ist und eine erneute Ausführung unnötig ist. Dazu liest diese Funktion zunächst einen evtl. vorhandenen Versionsstempel vom Profil ein (wie das mitreadVersionFromProfile
möglich ist) und vergleicht diesen mit der aktuell laufenden Version. Aus dem Vergleich ergibt sich der Rückgabewert (wahr/falsch). Danach werden noch die aktuellen Werte in das Profil zurückgeschrieben (wie das mitsaveVersionToProfile
möglich ist). Somit benötigen Sie nur diesescriptWasExecutedBefore
Funktion in einerif
Anweisung, um zu prüfen ob das Script schon mal gelaufen ist.
Weiterhin liefert die StringlistenfunktiongetProductMap
eine Infomap, aus der entnommen werden kann, ob das aktuelle Produkt installiert oder deinstalliert usw. ist. -
Jede Art von
ExitWindows
Kommando wird ignoriert. -
Logging
Die Logs von userLoginScripten werden geschrieben nach:
c:\opsi.org\log\<login user name>_login.log
Diese Logdateien werden auch an den opsi-server übertragen. Dabei wird eine neue Logdatei an eine existierende angehängt. Der opsi-server sorgt dafür, dass diese Dateien in der Größe beschränkt bleiben (max. 5 MB). Auf dem opsi server liegen diese logs unter /var/log/opsi/userlogin/<clientid>.log
Im opsi Managementinterface (opsi-configed) werden diese Logs in einem zusätzliche Untertab 'userlogin' in dem Tab 'Logdateien' angezeigt.
Beispiele von userLoginScripten
Zunächst zwei Beispiele die so aufgebaut sind, wie sie auch in Domain Loginscripten eingesetzt werden könnten.
Ein sehr einfaches allgemeines Beispiel:
[Actions]
requiredWinstVersion >= "4.11.3.2"
Message "Example Profile Patch ...."
Files_profile_copy
Registry_currentuser_set
Patches_profile_ini "%userprofiledir%\opsi-script-test.ini"
[Files_profile_copy]
copy "%Scriptpath%\profiles\*.*" "%CurrentAppdataDir%\ACME"
[Registry_currentuser_set]
openkey [HKCU\Software\ACME]
set "show_greeting_window" = "no"
[Patches_profile_ini]
add [secdummy] dummy1=add1
Ein Beispiel zur Firefoxkonfiguration:
[Actions]
requiredWinstVersion >= "4.11.3.2"
Message "Firefox Profile Patch ...."
DefVar $akt_profile_ini$
DefVar $rel_prefs_path$
comment "check for existing profile ..."
Set $akt_profile_ini$ = "%CurrentAppdataDir%\Mozilla\Firefox\profiles.ini"
if FileExists($akt_profile_ini$)
Set $rel_prefs_path$ = GetValueFromInifile($akt_profile_ini$,"Profile0","Path","")
if FileExists("%CurrentAppdataDir%\Mozilla\Firefox\\"+$rel_prefs_path$)
comment "We found the profile and will now patch it ....."
endif
else
comment "no firefox profile found for user"
endif
Als nächstes zeigen wir ein Beispiel welches das erste erweitert um die Möglichkeit Dinge aus dem Profil auch wieder zu entfernen. Je nachdem ob das Produkt auf dem Rechner installiert oder deinstalliert wird, wird ein anderer Scriptteil ausgeführt:
[Actions]
requiredWinstVersion >= "4.11.3.2"
Message "Example Profile Patch ...."
if getValue("installationstate", getProductMap) = "installed"
comment "Product is installed"
Files_profile_copy
Registry_currentuser_set
Patches_profile_ini "%userprofiledir%\opsi-script-test.ini"
endif
if getValue("lastactionrequest", getProductMap) = "uninstall"
comment "Product was uninstalled"
Files_profile_del
Registry_currentuser_del
endif
[Files_profile_copy]
copy "%Scriptpath%\profiles\*.*" "%CurrentAppdataDir%\ACME"
[Registry_currentuser_set]
openkey [HKCU\Software\ACME]
set "show_greeting_window" = "no"
[Files_profile_del]
del -s -f "%CurrentAppdataDir%\ACME"
del "%userprofiledir%\opsi-script-test.ini"
[Patches_profile_ini]
add [secdummy] dummy1=add1
[Registry_currentuser_del]
deletekey [HKCU\Software\ACME]
Nun ein Beispiel, welches das Setup Skript (setup32.opsiscript und delsub32.opsiscript) nutzt, um unnötige Verdopplung des Codes zu vermeiden:
setup32.opsiscript:
[Actions]
requiredWinstVersion >= "4.11.3.2"
DefVar $MsiId$
DefVar $UninstallProgram$
DefVar $ProductId$
DefVar $InstallDir$
; ----------------------------------------------------------------
; - Please edit the following values -
; ----------------------------------------------------------------
Set $ProductId$ = "ACME"
Set $InstallDir$ = "%ProgramFiles32Dir%\ACME"
; ----------------------------------------------------------------
if GetScriptMode = "Machine"
comment "Show product picture"
ShowBitmap "%ScriptPath%\\" + $ProductId$ + ".png" $ProductId$
if FileExists("%ScriptPath%\delsub32.opsiscript")
comment "Start uninstall sub section"
Sub "%ScriptPath%\delsub32.opsiscript"
endif
Message "Installing " + $ProductId$ + " ..."
comment "Start setup program"
Winbatch_install
comment "Patch the local Profiles ..."
Registry_currentuser_set /AllNtUserDats
Files_profile_copy /AllNtUserProfiles
Patches_profile_ini "%userprofiledir%\opsi-script-test.ini" /AllNtUserProfiles
endif
if GetScriptMode = "Login"
comment "login part"
Files_profile_copy
Registry_currentuser_set
Patches_profile_ini "%userprofiledir%\opsi-script-test.ini"
endif
[Winbatch_install]
"%ScriptPath%\setup.exe" /sp- /silent /norestart
[Files_profile_copy]
copy "%Scriptpath%\profiles\*.*" "%CurrentProfileDir%\Appdata\ACME"
[Registry_currentuser_set]
openkey [HKCU\Software\ACME]
set "show_greeting_window" = "no"
[Patches_profile_ini]
add [secdummy] dummy1=add1
delsub32.opsiscript:
Message "Uninstalling " + $ProductId$ + " ..."
if GetScriptMode = "Machine"
comment "The machine part ..."
Set $UninstallProgram$ = $InstallDir$ + "\uninstall.exe"
if FileExists($UninstallProgram$)
comment "Uninstall program found, starting uninstall"
Winbatch_uninstall
endif
; does also work since 4.11.2.1
Registry_currentuser_del /AllNtUserDats
Files_profile_del /AllNtUserProfiles
endif
if GetScriptMode = "Login"
comment "The profile part ..."
Files_profile_del
Registry_currentuser_del
endif
[Winbatch_uninstall]
"$UninstallProgram$" /silent /norestart
[Files_profile_del]
del -s -f "%CurrentAppdataDir%\ACME"
del "%userprofiledir%\opsi-script-test.ini"
[Registry_currentuser_del]
deletekey [HKCU\Software\ACME]
Nun ein Beispiel, welches eine Variante des vorherigen Beispiels ist. Dabei wird der code durch die Verwendung der neuen primären Sektion ProfileActions vereinfacht und das Script ist sowohl als Installationsscript als auch als 'userLoginScript' verwendbar.
[Actions]
requiredWinstVersion >= "4.11.3.2"
DefVar $ProductId$
DefVar $InstallDir$
Set $ProductId$ = "ACME"
Set $InstallDir$ = "%ProgramFiles32Dir%\ACME"
comment "Show product picture"
ShowBitmap "%ScriptPath%\\" + $ProductId$ + ".png" $ProductId$
Message "Installing " + $ProductId$ + " ..."
comment "Start setup program"
Winbatch_install
comment "Patch the local Profiles ..."
ProfileActions
[ProfileActions]
comment "login part"
Files_profile_copy
Registry_currentuser_set
Patches_profile_ini "%userprofiledir%\opsi-script-test.ini"
[Winbatch_install]
"%ScriptPath%\setup.exe" /sp- /silent /norestart
[Files_profile_copy]
copy "%Scriptpath%\profiles\*.*" "%CurrentProfileDir%\Appdata\ACME"
[Registry_currentuser_set]
openkey [HKCU\Software\ACME]
set "show_greeting_window" = "no"
[Patches_profile_ini]
add [secdummy] dummy1=add1
Nun eine Variante, welche sich im Profil merkt, ob das Skript für dieses Produkt in dieser Version und diesen User schon mal ausgeführt wurde.
Eine Zeile mit den Produkt-Informationen wird in die Datei %AppData%\.opsi.org\userLoginScripts.ini
geschrieben.
[Actions]
requiredWinstVersion >= "4.11.3.2"
Message "Example Profile Patch ...."
comment "Did we run this script before ? - and set version stamp in profile"
if not (scriptWasExecutedBefore)
comment "loginscript was not run yet "
Files_profile_copy
Registry_currentuser_set
Patches_profile_ini "%userprofiledir%\opsi-script-test.ini"
endif
[Files_profile_copy]
copy "%Scriptpath%\profiles\*.*" "%CurrentAppdataDir%\ACME"
[Registry_currentuser_set]
openkey [HKCU\Software\ACME]
set "show_greeting_window" = "no"
[Patches_profile_ini]
add [secdummy] dummy1=add1
Konfiguration
Um die 'User Profile Management' Erweiterung zu nutzen, muss in der Konfiguration des opsiclientd das Loginevent aktiviert werden. Für dieses Event wird (wenn der entsprechend aktuelle opsi-client-agent auf dem Client installiert ist) der opsi-script mit dem ergänzenden Parameter '/allloginscripts' oder '/loginscripts' gestartet.
-
/allloginscripts
bedeutet, dass bei einem Login alle Loginscripts die dem Server bekannt sind ausgeführt werden, unabhängig ob das entsprechende Produkt dem Client bekannt ist (also installiert ist oder war) oder nicht. -
/loginscripts
bedeutet, das bei einem Login nur die Loginscripts auf einem Client ausgeführt werden, bei denen das entsprechende Produkt dem Client bekannt ist, also installiert ist oder war. (Technisch: bei denen es für diesen Client ein productOnClient Objekt gibt mit:
(installationStatus
=installed
)
oractionResult
=successful
) and (lastAction
=uninstall
).
Loginscripts von Produkten, die der Client noch nie gesehen hat, werden nicht ausgeführt.
Dies ist der Default.
Einen Schalter zur Aktivierung des Loginevents können Sie auf der Kommandozeile wie folgt einrichten: (meist will man zum Test nur einzelne Clients aktivieren, daher serverseitig hier der Wert 'false')
opsi-admin -d method config_createBool opsiclientd.event_user_login.active "user_login active" false
Als weiterer opsi-script Parameter kann zusätzlich auch noch der Parameter '/silent' verwendet werden, welcher die Anzeige des opsi-script Fensters unterbindet.
Dies ist der Default.
opsi-admin -d method config_createUnicode opsiclientd.event_user_login.action_processor_command "user_login action_processor" "%action_processor.command% /sessionid %service_session% /loginscripts /silent" "%action_processor.command% /sessionid %service_session% /loginscripts /silent"
Die so eingerichteten Einstellungen können Sie im opsi Managementinterface im Tab 'Hostparameter' Server- oder Client-spezifisch modifizieren.