Definition und Verwendung von Variablen und Konstanten im opsi-script Skript

Allgemeines

Variable und Konstanten erscheinen im Skript als "Wörter", die vom opsi-script interpretiert werden und Werte "tragen". "Wörter" sind dabei Zeichenfolgen, die Buchstaben, Ziffern und die meisten Sonderzeichen (insbesondere ".", "-", "_", "$", "%"), aber keine Leerzeichen, Klammern oder Operatorzeichen ("+") enthalten dürfen.

Groß- und Kleinbuchstaben gelten als gleichbedeutend.

Es existieren folgende Arten von Werteträgern:

  • Globale Text-Konstanten
    enthalten Werte, die opsi-script automatisch ermittelt und die nicht geändert werden können. Vor der Abarbeitung eines Skripts werden ihre Bezeichnungen im gesamten Skript gegen ihren Wert ausgetauscht. Die Konstante %ScriptPath% ist die definierte Pfad-Variable, die den Pfad angibt in dem der opsi-script das Skript findet und ausführt. Dies könnte beispielsweise 'p:\product' sein. Man müsste dann
    "%ScriptPath%"
    in das Skript schreiben, wenn man den Wert
    'p:\product'
    bekommen möchte.
    Zu beachten sind die Anführungszeichen um die Konstantenbezeichnung.

  • Text-Variable oder String-Variable
    entsprechen den gebräuchlichen Variablen in anderen Programmiersprachen. Die Variablen müssen vor ihrer Verwendung mit DefVar deklariert werden. In einer primären Sektion kann einer Variable mehrfach ein Wert zugewiesen werden und mit den Werten in der üblichen Weise gearbeitet werden („Addieren“ von Strings, spezielle String-Funktionen).
    In sekundären Sektionen erscheinen sie dagegen als statische Größen. Ihr jeweils aktueller Wert wird bei der Abarbeitung der Sektion für ihre Bezeichnung eingesetzt (so wie es bei Textkonstanten im ganzen Skript geschieht).

  • Variablen für String-Listen
    werden mit DefStringList deklariert. Eine String-Listenvariable kann ihren Inhalt, also eine Liste von Strings, auf unterschiedlichste Weisen erhalten. Mit String-Listenfunktionen können die Listen in andere Listen überführt oder als Quelle für Einzelstrings verwendet werden.

Details in den folgenden Kapiteln.

Globale Textkonstanten

Damit Skripte ohne manuelle Änderungen in verschiedenen Umgebungen eingesetzt werden können, ist es erforderlich, sie durch gewisse Systemeigenschaften zu parametrisieren. opsi-script kennt einige System-Größen, die innerhalb des Skriptes als Text-Konstanten anzusehen sind.

Verwendung

Wichtigste Eigenschaft der Text- oder String-Konstanten ist die spezifische Art, wie die von ihnen repräsentierten Werte eingesetzt werden:

Vor Abarbeitung des Skripts werden die Namen der Konstanten in der gesamten Skriptdatei gegen die Zeichenfolge ihrer vom opsi-script bestimmten Werte ausgetauscht.

Diese Ersetzung vollzieht sich – in der gleichen Weise wie bei den Text-Variablen in den sekundären Sektionen – als ein einfaches Suchen- und Ersetzen-Verfahren (Search und Replace), ohne Rücksicht auf den jeweiligen Ort, an dem die Konstante steht.

Beispiel

opsi-script kennt z.B. die Konstanten %ScriptPath% für den Ort im Verzeichnisbaum, an dem das interpretierte Skript steht und %System% für den Namen des Windows-Systemverzeichnisses. In einer Files-Sektion könnten daher auf folgende Weise alle Dateien eines Verzeichnissystems, das im gleichen Verzeichnis wie das Skript liegt, in das Windows-Systemverzeichnis kopiert werden:

[files_do_my_copying]
copy "%ScriptPath%\system\*.*" "%System%"

Gegenwärtig sind folgende Konstanten definiert:

Systemverzeichnis

Basissystemverzeichnis [W]

%ProgramFilesDir%: 'c:\program files'

%ProgramFiles32Dir%: 'c:\Program Files (x86)'

%ProgramFiles64Dir%: 'c:\program files'

%ProgramFilesSysnativeDir% : 'c:\program files'

%Systemroot% : 'c:\windows'

%System% : 'c:\windows\system32'

%Systemdrive% : 'c:'

%ProfileDir% : 'c:\Users'

Gemeinsames (AllUsers) Verzeichnis [W]

%AllUsersProfileDir% or %CommonProfileDir% : 'C:\Users\Public'

%CommonStartMenuPath% or %CommonStartmenuDir% : 'C:\ProgramData\Microsoft\Windows\Start Menu'

%CommonAppdataDir% : 'C:\ProgramData'

%CommonDesktopDir%

%CommonStartupDir%

%CommonProgramsDir%

Contstant

Win7 - Win10 (NT6)

%AllUsersProfileDir%

C:\Users\Public

%CommonProfileDir%

C:\Users\Public

%CommonStartMenuPath%

C:\ProgramData\Microsoft\Windows\Start Menu

%CommonAppDataDir%

C:\ProgramData

%CommonDesktopDir%

C:\Users\Public\Desktop

%CommonStartupDir%

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

%CommonProgramsDir%

C:\ProgramData\Microsoft\Windows\Start Menu\Programs

%AllUsersProfileDir%

C:\Users\Public

%DefaultUserProfileDir%

C:\Users\Default

%ProfileDir%

C:\Users

%Systemroot%

C:\Windows

%System%

C:\Windows\system32

Default User Verzeichnis [W]

%DefaultUserProfileDir%

Aktuelles (logged in oder usercontext) User Verzeichnis [W]

%AppdataDir% or %CurrentAppdataDir% : //since 4.10.8.13
NT6: 'c:\users\%USERNAME%\Appdata\Roaming'

%CurrentStartmenuDir%

%CurrentDesktopDir%

%CurrentStartupDir%

%CurrentProgramsDir%

%CurrentSendToDir%

%CurrentProfileDir% //since 4.11.2.1

/AllUserProfiles (/AllNTUserProfiles) Verzeichnis Konstanten [W]

%UserProfileDir%

Diese Konstante wird nur innerhalb von 'Files'-Sektionen, die mit der Option /AllUserProfiles aufgerufen werden, interpretiert. Sie wird dann der Reihe nach belegt mit dem Namen des Profil-Verzeichnisses der verschiedenen auf dem System existierenden Nutzer.
Der Parameter /AllUserProfiles existiert seit 4.12.4.27. Noch gültig aber nicht mehr empfohlen ist das alte sysnonym /AllNTUserProfiles.

%CurrentProfileDir% // since 4.11.2.1
kann statt %UserProfileDir% verwendet werden um Files-Sektionen zu erzeugen, die sich genauso auch in 'userLoginScripten' verwenden lassen.

%UserProfileDir% or %CurrentProfileDir%
NT6: 'c:\users\%USERNAME%'

opsi-script Pfad und Verzeichnisse [W/L/M]

%ScriptPath% or %ScriptDir% : Pfad des opsi-script Skripts (ohne schließenden Backslash); mithilfe dieser Variable können die Dateien in Skripten relativ bezeichnet werden. Zum Testen können sie z.B. auch lokal gehalten werden.

%RealScriptPath% : Wenn das laufende Skript über einen symbolischen Link aufgerufen wurde, so liefert %RealScriptPath% den Pfad, auf den der symbolische Link letztendlich zeigt. In allen anderen Fällen ist der wert indentisch mit %ScriptPath%. (seit 4.12.4.21)

%ScriptDrive% : Laufwerk, auf dem das ausgeführt opsi-script Skript liegt (inklusive Doppelpunkt).

%OpsiscriptDir% (since 4.12.3.6)
Pfad (ohne schließenden Backslash), in dem der aktive opsi-script liegt.
Identisch mit veraltet %WinstDir%

%OpsiscriptVersion% (since 4.12.3.6)
Versionsstring des laufenden opsi-script.
Identisch mit veraltet %WinstVersion% (since 4.10.8.3)

%opsiscriptProcname% (since 4.12.4.35)
Name des laufenden opsi-script Prozesses.
Zu verwenden z.b. mit isProcessChildOf

%Logfile% : Der Name der Log-Datei, die der opsi-script benutzt.

%opsiTmpDir% // since 4.11.4.3
Pfad zum Verzeichnis, das für temporäre Dateien verwendet werden sollte. (Unter Windows: c:\opsi.org\tmp)

%opsiUserTmpDir% // since 4.12.4.37
Pfad zum Verzeichnis, das für temporäre Dateien verwendet werden sollte und für das man keine Administrator-Rechte benötigt. (Unter Windows: c:\opsi.org\usertmp)

%opsiLogDir% // since 4.11.4.3
Pfad zum Verzeichnis, das für Log Dateien verwendet werden sollte. (Unter Windows: c:\opsi.org\log)

%opsiScriptHelperPath%
Entspricht: %ProgramFiles32Dir%\opsi.org\opsiScriptHelper
Pfad in dem Hilfsprogramme, Libraries und ähnliches zur Scriptausführung installiert sein können.
Seit 4.11.3.2

%opsidata% // since 4.12.0.12
Pfad zum Verzeichnis, das für opsi Daten Dateien verwendet werden sollte. (Unter Windows: c:\opsi.org\data)

%opsiapplog% // since 4.12.0.12
Pfad zum Verzeichnis, das für Log Dateien von Programmen welche mit Benutzerrechten laufen verwendet wird. (Unter Windows: c:\opsi.org\applog)

Beispiel:
Der Code:

message "Testing constants: "+"%"+"OpsiscriptVersion" +"%"
set $ConstTest$ = "%OpsiscriptVersion%"
if $OS$ = "Windows_NT"
	set $InterestingFile$ = "%Opsiscriptdir%\opsi-script.exe"
	if not (FileExists($InterestingFile$))
		set $InterestingFile$ = "%Opsiscriptdir%\winst32.exe"
	endif
	set $INST_Resultlist$ = getFileInfoMap($InterestingFile$)
	set $CompValue$ = getValue("file version with dots", $INST_Resultlist$ )
	if ($ConstTest$ = $CompValue$)
		comment "passed"
	else
		set $TestResult$ = "not o.k."
		LogWarning "failed"
	endif
endif

liefert folgenden Log:

message Testing constants: %OpsiscriptVersion%
Set  $ConstTest$ = "4.12.4.27"
  The value of the variable "$ConstTest$" is now: "4.12.4.27"
If
  $OS$ = "Windows_NT"   <<< result true
Then
  Set  $InterestingFile$ = "C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-script\opsi-script.exe"
    The value of the variable "$InterestingFile$" is now: "C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-script\opsi-script.exe"
  If
      Starting query if file exists ...
    FileExists($InterestingFile$)   <<< result true
    not (FileExists($InterestingFile$))   <<< result false
  Then
  EndIf
  Set  $INST_Resultlist$ = getFileInfoMap($InterestingFile$)
    The value of the variable "$INST_Resultlist$" is now:
    (string   0)Language name 0=Englisch (Vereinigte Staaten)
    (string   1)Language ID 0=1033
    (string   2)file version=1125951446712347
    (string   3)file version with dots=4.12.4.27
    (string   4)product version=1125908496777216
    (string   5)Comments=Compiled with Lazarus 2.2.0 / FPC 3.2.2
    (string   6)CompanyName=uib gmbh
    (string   7)FileDescription=opsi-script
    (string   8)FileVersion=4.12.4.27
    (string   9)InternalName=opsi-script
    (string  10)LegalCopyright=AGPL v3
    (string  11)LegalTrademarks=opsi, opsi.org, open pc server integration
    (string  12)OriginalFilename=opsi-script
    (string  13)PrivateBuild=
    (string  14)ProductName=opsi
    (string  15)ProductVersion=4.2
    (string  16)SpecialBuild=
  Set  $CompValue$ = getValue("file version with dots", $INST_Resultlist$ )
    The value of the variable "$CompValue$" is now: "4.12.4.27"
  If
    $ConstTest$ = $CompValue$   <<< result true
    ($ConstTest$ = $CompValue$)   <<< result true
  Then
    comment: passed
  Else
  EndIf
EndIf

Netzwerk-Informationen [W/L/M]

%Host% : (nicht mehr empfohlen) Wert der Umgebungsvariable HOST. (Nicht mit %HostId% verwechseln)

%PCName%: Wert der Umgebungsvariable PCNAME oder wenn nicht vorhanden COMPUTERNAME. (Dies ist üblicherweise der Netbios Name)

%IPName% : Der DNS Name eines Computers. In vielen Fällen (aber nicht zwingend) ist dieser identisch mit dem netbios-Namen und damit auch identisch mit %PCName%. (Nur das der netbios-Namen üblicherweise in Großbuchstaben geschrieben wird.)

%IPAddress% : (nicht mehr empfohlen) Liefert eine IP-Adresse eines Interface dieses Rechners. Verwenden Sie besser dir Funktion GetMyIpByTarget().
siehe auch : GetMyIpByTarget

%Username% : Name des aktuellen Benutzers.

Service Daten [W/L/M]

%HostID% : FQDN des Clients im opsi-service Kontext, andernfalls der Computername.
Im opsi-Service-Kontext besser %opsiserviceUser% verwenden.

%FQDN% : FQDN des Computers im Netzwerk-Kontext (nicht im opsi-service Kontext)

%opsiserviceURL%: Die opsi-Service URL des opsi config Servers (https://<opsiserver>:4447)

%opsiServer% : Name des opsi Config Servers abgeleitet von %opsiserviceURL%

%opsiDepotId% : Depot Server (FQDN) //since 4.11.4

%opsiserviceUser% : Die Benutzer ID für die es eine Verbindung zum opsi Service gibt. Im opsi-Service-Kontext der von opsi verwendete FQDN des Clients.

%opsiserviceClientId% : Wird bei Aufruf von opsi-script im opsi-Service-Kontext auf den Aufrufparameter /clientid gesetzt. Entspricht also im opsi-Service-Kontext dem FQDN des Clients und ist ohne opsi-Service-Kontext leer.

%opsiservicePassword% : Das für die Kommunikation mit dem Server verwendete Passwort. Das Passwort wird üblicherweise nicht geloggt.

%installingProdName%: Der Produktname (productId) für das der Service das laufende Skript aufruft. In dem Fall, dass das Skript nicht über den Service läuft, bleibt der String-Eintrag leer.

%installingProdVersion%: Ein String aus <Produktversion>-<Packageversion> für das der Service das laufende Skript aufruft. In dem Fall dass das Skript nicht über den Service läuft bleibt der String-Eintrag leer.

%installingProduct% : Product ID (nicht mehr empfohlen).

String- (oder Text-) Variable [W/L/M]

Deklaration

String-Variable müssen vor ihrer Verwendung deklariert werden. Die Deklarationssyntax lautet

DefVar <variable name>

Beispielsweise

DefVar $MsVersion$
; since 4.12.4.32 also possible:
DefVar $MsVersion$ = '10.0'

Erklärung:

  • Die Variablennamen müssen nicht mit "$" beginnen oder enden, diese Konvention erleichtert aber ihre Verwendung und vermeidet Probleme bei der Ersetzung der Variablen durch ihre Inhalte und ist daher dringend empfohlen.

  • Die Deklaration von Variablen ist nur in den primären Sektionstypen (Actions-Sektion, sub-Sektionen sowie ProfileActions) möglich.

  • Die Deklaration sollte nicht abhängig sein. Daher sollte die Deklaration auch nicht in Klammern in einer if – else - Konstruktion erfolgen. Da es sonst es passieren kann, dass ein DefVar-Anweisung nicht für eine Variable ausgeführt wird, aber die Variable in der if-Schleife ausgelesen wird und dann einen Syntax-Fehler produziert.

  • Bei der Deklaration werden die Variablen mit dem leeren String ("") als Wert initialisiert.

Empfehlung:

  • Alle Varablennamen sollten mit dem Zeichen '$' beginnen und enden.

  • Alle Variablen sollten am Anfang des Skripts deklariert werden.

Wertzuweisung

In den primären Sektionstypen kann einer Variablen ein- oder mehrfach ein Wert zugewiesen werden. Die Syntax lautet:

Set <Variablenname> = <Value>

<Value> kann jeder String basierte Ausdruck sein (Beispiele dazu im Abschnitt String-Werte, String-Ausdrücke und String-Funktionen).

Set $OS$ = GetOS
Set $NTVersion$ = "unknown"

if $OS$ = "Windows_NT"
  Set $WinVersion$ = GetMsVersionInfo
endif
DefVar $Home$
Set $Home$ = "n:\home\user name"
DefVar $MailLocation$
Set $MailLocation$ = $Home$ + "\mail"

Verwendung von Variablen in String-Ausdrücken

Eine Variable fungiert in den primären Sektionen als "Träger" eines Wertes. Zunächst wird sie deklariert und automatisch mit dem leeren String - also "" - initialisiert. Nach der Zuweisung eines Wertes mit dem Set-Befehl steht sie dann für diesen Wert.

In primären Sektionen, wie in der letzten Zeile des Beispiel-Codes zu sehen, kann die Variable selbst Teil von opsi-script String-Ausdrücken werden.

Set $MailLocation$ = $Home$ + "\mail"

In der primären Sektion bezeichnet der Variablenname ein Objekt, dass für einen String steht. Wenn die Variable hinzugefügt wird, steht diese für den ursprünglichen String.

In den sekundären Sektionen spielt dagegen ihr Name Platzhalter für die Zeichenfolge des von ihr repräsentierten Wertes:

Sekundäre und Primäre Sektion im Vergleich

Wenn eine sekundäre Sektion von opsi-script geladen wird, werden sämtliche Vorkommen von bekannten Variablennamen durch den Wert der entsprechenden Variable ersetzt.

Beispiel:
Mit einer Kopieraktion in einer Files-Sektion soll eine Datei nach '"n:\home\user name\mail\backup"' kopiert werden.

Zuerst müsste das Verzeichnis $MailLocation$ gesetzt werden:

DefVar $Home$
DevVar $MailLocation$
Set $Home$ = "n:\home\user name"
Set $MailLocation$ = $Home$ + "\mail"

$MailLocation$ wäre dann
'"n:\home\user name\mail"'

In der primären Sektion würde man das Verzeichnis
'"n:\home\user name\mail\backup"'
durch die Variablen
'$MailLocation$ + "\backup"'
setzen.

Das gleiche Verzeichnis würde in der sekundären Sektion folgendermaßen aussehen:
'"$MailLocation$\backup"'

Ein grundsätzlicher Unterschied zwischen dem Variablenverständnis in der primären und sekundären Sektion ist, dass man in der primären Sektion einen verknüpften Ausdruck wie folgt formulieren kann:
'$MailLocation$ = $MailLocation$ + "\backup"'

Das bedeutet, dass '$MailLocation$' zuerst einen initialen Wert und dann einen neuen Wert annimmt, in dem ein String zu dem initialen Wert addiert wird. D.h. der Inhalt der Variable verändert sich dynamisch.

In der sekundären Sektion ist eine solcher Ausdruck ohne Wert und würde eventuell einen Fehler verursachen, sobald '$MailLocation$' durch den Wert der Variable ersetzt wird (und zwar bei allen Vorkommen gleichzeitig).

Variable für String-Listen [W/L/M]

Variablen für String-Listen müssen vor ihrer anderweitigen Verwendung mit dem Befehl DefStringList deklariert werden. Seit 4.12.4.32 können auch optional initiale Werte mitgegeben werden. Die Deklarationssyntax lautet

DefStringList <variable name> [= <inital value>]

Beispielsweise

DefStringList $MsVersionList$
; since 4.12.4.32 also possible:
DefStringList $MsVersionList$ = '["6.1","10.0"]'

String-Listen können z.B. die Ausgabe eines Shell-Programms einfangen und dann in vielfältiger Weise weiterverarbeitet und verwendet werden. Genauere Details dazu findet sich in dem Abschnitt String-Listenverarbeitung.