Das Copyright an diesem Handbuch liegt bei der uib gmbh in Mainz.

Dieses Handbuch ist veröffentlicht unter der creative commons Lizenz
'Namensnennung - Weitergabe unter gleichen Bedingungen' (by-sa).

CC by sa

Eine Beschreibung der Lizenz finden Sie hier:
https://creativecommons.org/licenses/by-sa/3.0/de/

Der rechtsverbindliche Text der Lizenz ist hier:
https://creativecommons.org/licenses/by-sa/3.0/de/legalcode

Die Software von opsi ist in weiten Teilen Open Source.
Nicht Open Source sind die Teile des Quellcodes, die neue Erweiterungen enthalten, welche noch unter Kofinanzierung stehen, also noch nicht bezahlt sind.
siehe auch: opsi-Erweiterungen als Kofinanzierungsprojekte

Der restliche Quellcode ist veröffentlicht unter der AGPLv3:

agplv3

Der rechtsverbindliche Text der AGPLv3 Lizenz ist hier:
http://www.gnu.org/licenses/agpl-3.0-standalone.html

Für Lizenzen zur Nutzung von opsi im Zusammenhang mit Closed Source Software kontaktieren Sie bitte die uib gmbh.

Die Namen 'opsi', 'opsi.org', 'open pc server integration' und das opsi-logo sind eingetragene Marken der uib gmbh.

2. Einführung

Das Open-Source-Programm opsi-script (bzw. früher unter Windows opsi-winst) fungiert im Kontext des Systems opsi – Open PC Server Integration (www.opsi.org) – als zentrale Instanz zur Abwicklung der automatischen Softwareinstallation und -Konfiguration. Es kann aber auch stand alone als Setup-Rahmen-Programm verwendet werden.

opsi-script ist im Kern ein Interpreter für eine eigene, einfache Skriptsprache mit der alle, für die Software-Installation relevanten, Schritte ausgedrückt werden können.

Eine Software Installation, die auf einem opsi-script Skript basiert, bietet verschiedene Vorteile im Vergleich zu Verfahren, die auf Kommando-Zeilen-Aufrufen beruhen (z.B. Kopieren etc.):

  • opsi-script bietet die Möglichkeit eines sehr detaillierten Protokolls der Installation. So lassen sich Fehler bei der Installation und beim Einsatz oder andere Problemsituationen frühzeitig erkennen.

  • Kopieraktionen können sehr differenziert konfiguriert werden, in wie weit vorhandene Dateien überschrieben werden sollen. Dateien (z.B. DLLs) können beim Kopieren auf ihre interne Version überprüft werden.

  • Ein Zugriff auf die Windows-Registry ist in unterschiedlichen Modi (z.B. vorhandene Werte überschreiben/nur neue Werte eintragen/Werte ergänzen) möglich.

  • Eintragungen z.B. in die Windows-Registry können auch für alle User (einschließlich dem Default-User, der als Vorlage für die künftig angelegten User dient) vorgenommen werden.

  • Es existiert eine ausgearbeitete und gut verständliche Syntax zum Patchen von XML-Konfigurationsdateien, das in die sonstigen Konfigurationsaufgaben integriert ist.

3. opsi-script reference card (4.12.7)

For Windows [W], Linux [L] and MacOS [M]

3.1. Global text constants

3.1.1. System directories

System directories [W]:

%ProgramFilesDir%: 'c:\program files'

%ProgramFiles32Dir%: 'c:\Program Files (x86)' //since 4.10.8

%ProgramFiles64Dir%: 'c:\program files' //since 4.10.8

%ProgramFilesSysnativeDir% : 'c:\program files' //since 4.10.8

%Systemroot% : 'c:\windows'

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

%Systemdrive% : 'c:'

%ProfileDir% :
NT5: 'c:\Documents and Settings'
NT6: 'C:\users\'

3.1.2. Common (AllUsers) directories [W]:

%AllUsersProfileDir% or %CommonProfileDir% :
NT5: 'c:\Documents and Settings\All Users'
NT6: 'C:\Users\Public'

%CommonStartMenuPath% or %CommonStartmenuDir% :
NT5: 'c:\Documents and Settings\All Users\Startmenu'
NT6: 'C:\ProgramData\Microsoft\Windows\Start Menu'

%CommonAppdataDir% :
NT5: 'c:\Documents and Settings\All Users\Application Data'
NT6: 'C:\ProgramData'

%CommonDesktopDir%
NT5: 'c:\Documents and Settings\All Users\Desktop'
NT6: 'C:\Users\Public\Desktop'

%CommonStartupDir%
NT5: 'c:\Documents and Settings\All Users\Autostart'
NT6: 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp'

%CommonProgramsDir%

3.1.3. Default User directories [W]:

%DefaultUserProfileDir% //since 4.11.1.1

3.1.4. Current user directories [W]:

User is the logged in user or given by /usercontext.

%AppdataDir% or %CurrentAppdataDir% : //since 4.10.8.13
NT5: 'c:\Documents and Settings\%USERNAME%\Application Data' NT6: 'c:\users\%USERNAME%\Appdata\Roaming'

%CurrentStartmenuDir% //since 4.10.8.13

%CurrentDesktopDir% //since 4.10.8.13

%CurrentStartupDir% //since 4.10.8.13

%CurrentProgramsDir% //since 4.10.8.13

%CurrentSendToDir% //since 4.10.8.13

%CurrentProfileDir% //since 4.11.2.1

3.1.5. /AllUserProfiles directory constants [W/L/M]:

%UserProfileDir%
or
%CurrentProfileDir% // since 4.11.2.1
NT5: 'c:\Documents and Settings\%USERNAME%'
NT6: 'c:\users\%USERNAME%'

3.1.6. opsi-script Path and Directories [W/L/M]:

%ScriptPath% or %ScriptDir%

%RealScriptPath% (since 4.12.4.21)

%ScriptDrive%

%OpsiscriptDir% (since 4.12.3.6), %WinstDir%

%OpsiscriptVersion% (since 4.12.3.6), %WinstVersion% (since 4.10.8.3)

%opsiscriptProcname% (since 4.12.4.35)

%Logfile%

%opsiScriptHelperPath% %ProgramFiles32Dir%\opsi.org\opsiScriptHelper\lib // since 4.11.3.2

%opsiTmpDir% : c:\opsi.org\tmp // since 4.11.4.3

%opsiUserTmpDir% : c:\opsi.org\usertmp // since 4.12.4.37

%opsiLogDir% : c:\opsi.org\log // since 4.11.4.3

%opsidata% : c:\opsi.org\data // since 4.12.0.12

%opsiapplog% : c:\opsi.org\applog // since 4.12.0.12

3.1.7. Network informations [W/L/M]:

%Host% : value of environment variable HOST.

%PCName%: value of environment variable PCNAME, or if absent of COMPUTERNAME.

%Username% : Name of actual user.

%IPName% : The dns name of the pc. Usually identical with the netbios name and therefore with %PCName% besides that the netbios names uses to be uppercase.

%IPAddress% : may be the IP-Address of the machine. Use funktion GetMyIpByTarget() instead.
see also : GetMyIpByTarget

3.1.8. Service Data [W/L/M]

%HostID% : FQDN of the client in opsi service context, otherwise the computer name

%FQDN% : FQDN in network context

%opsiserviceURL%

%opsiServer%

%opsiDepotId% //since 4.11.4

%opsiserviceUser% FQDN used for the connection to the opsi-config-server

%opsiserviceClientId% : command line option /clientid

%opsiservicePassword%

%installingProdName%: productid //since 4.10.8

%installingProdVersion%: product version //since 4.10.8

%installingProduct% : productid (deprecated)

3.1.9. Functions to handle constants [W/L/M]

replaceOpsiConstants(<string list>`) : stringlist` //since 4.12.3.6 [W/L/M] see also : replaceOpsiConstants_list

replaceOpsiConstants(<string>`) : string` //since 4.12.3.6 [W/L/M] see also : replaceOpsiConstants_string

3.2. In Primary Sections

3.2.1. Kinds of Primary Sections [W/L/M]:

[Initial]

[Actions]

[sub<identifier>`]`

sub <file name>

[ProfileActions] [W]

3.2.2. opsi-script control [W/L/M]:

encoding=<encoding> // (default is system encoding) since 4.11.4.2 see also : encoding

LogLevel (deprecated) see also : Specification of Logging Level [W/L/M]

SetLogLevel = <number> or SetLogLevel = <string> // (default=6) see also : SetLogLevel

SetLogLevel = 7
SetLogLevel = "7"

SetDebug_Lib = <boolean value> // (default=false) see also : SetDebugLib

ExitOnError = <boolean value> // (default=false) see also : ExitOnError

ScriptErrorMessages = <boolean value> // (default=true) see also : ScriptErrorMessages

FatalOnSyntaxError = <boolean value> // (default=true) since 4.11.3.2 see also : FatalOnSyntaxError

FatalOnRuntimeError = <boolean value> // (default=false) since 4.11.3.2 see also : FatalOnRuntimeError

AutoActivityDisplay = <boolean value> // (default=false); if true shows a marquee (endless) progressbar while winbatch/dosbatch sections are . //since 4.11.4.7 see also : AutoActivityDisplay see also : Central configuration via opsi Configs

forceLogInAppendMode = <boolean value> // (default=false); if true, log will be send in append mode . //since 4.12.3.6 see also : forceLogInAppendMode

Message <string> or Message = <const string> see also : Message

ShowMessageFile <string> see also : ShowMessageFile

ShowBitMap [<file name>] [<sub title>] see also : ShowBitMap

comment <string> or comment = <const string> see also : comment

LogError <string> or LogError = <const string> see also : LogError

LogWarning <string> or LogWarning = <const string> see also : LogWarning

includelog <file name> <tail size> //since 4.11.2.1 [W/L/M] see also : includelog

includelog <file name> <tail size> [<encoding>] //since 4.11.4.1 [W/L/M] see also : includelog

includelog "%Scriptpath%\test-files\10lines.txt" "5"

SetConfidential <secret string> //since 4.11.3.5 [W/L/M] see also : SetConfidential

asConfidential( <secret string expression> ) : string //since 4.12.0.16 [W/L/M] see also : asConfidential_str

asConfidential( <secret stringlist expression> ) : stringlist //since 4.12.4.15 [W/L/M] see also : asConfidential_list

Pause <string> or Pause = <const string> see also : Pause

Stop <string> or stop = <const string> see also : Stop

include_insert <file name> // since 4.11.3 see also : include_insert

include_append <file name> // since 4.11.3 see also : include_append

NormalizeWinst // (set normal window state) since 4.11.3 see also : NormalizeWinst

IconizeWinst // (set minimized window state) see also : IconizeWinst

MaximizeWinst // (set maximized window state) // since 4.11.5.1 see also : MaximizeWinst

RestoreWinst // (restore last window state) see also : RestoreWinst

SetSkinDirectory <path to skin.ini> // since 4.11.3.5 see also : SetSkinDirectory

runningInWanMode : boolean //since 4.12.4.17 [W/L/M] see also : runningInWanMode

reloadProductList //since 4.12.6.1 [W/L/M] see also : reloadProductList

3.2.3. Variables [W/L/M]:

Strings

DefVar <variable name>
; since 4.12.4.32 also possible:
DefVar <variable name> [= <inital value>]

Set <variable name> = <value>

Stringlists

DefstringList <variable name> ; since 4.12.4.32 also possible:
DefstringList <variable name> [= <inital value>]

3.2.4. Functions

String functions
Important

GetOS // 'Linux' or 'Windows_NT' [W/L/M] see also : GetOS

getLinuxDistroType // 'debian' or 'redhat' or 'suse' (see getLinuxVersionMap) [L] see also : getLinuxDistroType

GetMsVersionInfo //Windows Version Information [W] see also : GetMsVersionInfo

GetSystemType //OS Architecture ("64 Bit System" or "x86 System") [W/L/M]
see also : GetSystemType

getOSArchitecture // OS Architecture (x86_32 / x86_64/ arm_64) //since 4.12.4.17 [W/L/M]
see also : getOSArchitecture

getRegistryValue(<keystr>, <varstr> ) : string //since 4.12.0.16 [W]
<access str> = one of 32bit, 64bit, sysnative ; default sysnative see also : getRegistryValue

GetRegistrystringvalue (`"[key] var")` [W] see also : GetRegistrystringvalue

GetRegistryStringValue32 (`"[key] var")` //since 4.10.8 [W] see also : GetRegistryStringValue32

GetRegistryStringValue64 (`"[key] var")` //since 4.10.8 [W] see also : GetRegistryStringValue64

GetRegistryStringValueSysNative (`"[key] var")` //since 4.10.8 [W] see also : GetRegistryStringValueSysNative

GetValueFromInifile (<file path>, <section>, <key>, <default value>, OPTIONAL <encoding>`) : string` [W/L/M] see also : GetValueFromInifile

GetProductProperty (<PropertyName>, <DefaultValue> ) [W/L/M] see also : GetProductProperty

GetConfidentialProductProperty (<PropertyName>, <DefaultValue>`)` //since 4.11.5.2 [W/L/M] see also : GetConfidentialProductProperty

trim(<string>`)` [W/L/M] see also : trim

lower(<string>`)` [W/L/M] see also : lower

upper(<string>`)` [W/L/M] see also : upper

unquote(<string>,<quote-string>`)` //since 4.11.2.1 [W/L/M] see also : unquote

unquote2(<string>,<quote-string>`)` //since 4.11.5.2 [W/L/M] see also : unquote2

stringReplace(<string>, <oldPattern>, <newPattern>`)` //since 4.11.3 [W/L/M] see also : stringReplace

strLength(<string>`)` //since 4.11.3 [W/L/M] see also : strLength

strPos(<string>, <sub string>`)` //since 4.11.3 [W/L/M] see also : strPos

strPart(<string>, <start pos>, <number of chars>`)` //since 4.11.3 [W/L/M] see also : strPart

getValue(<key string>, <hash string list> ) [W/L/M] see also : getValue

getValueBySeparator(<key string>,<separator string>,<hash string list> ) //since 4.11.2.1 [W/L/M] see also : getValueBySeparator

setValueByKey(<key>, <value>, <targetlist> ) [W/L/M] see also : [setValueByKey]

getValueFromFile(<key string>, <file name>`)` //since 4.11.4.4 [W/L/M] see also : getValueFromFile

getValueFromFileBySeparator(<key string>,<separator string>,<file name>`)` //since 4.11.4.4 [W/L/M] see also : getValueFromFileBySeparator

getLastExitCode : string (exitcode) [W/L/M] see also : getLastExitCode

Special: License Management

DemandLicenseKey( poolId [, productId [,windowsSoftwareId]] )

set $mykey$ = DemandLicenseKey ("", "office2007")

see also : DemandLicenseKey

FreeLicense (`poolId [, productId [,windowsSoftwareId]])`

set $result$ = FreeLicense("", "office2007")

see also : FreeLicense

Special: Usercontext / loginscripts [W]:

GetUserSID(<Windows Username>`)` see also : GetUserSID

GetLoggedInUser //since 4.11.1.2 see also : GetLoggedInUser

GetUsercontext //since 4.11.1.2 see also : getLastExitCode

GetScriptMode possible values 'Machine','Login' //since 4.11.2.1 see also : GetUsercontext

saveVersionToProfile - save productversion-packageversion to local profile //since 4.11.2.1 see also : saveVersionToProfile

readVersionFromProfile : string - read productversion-packageversion from local profile //since 4.11.2.1 see also : readVersionFromProfile

scriptWasExecutedBefore : boolean - is true if saved and running productversion-packageversion are identical //since 4.11.2.1 see also : scriptWasExecutedBefore

Other

GetHostsName (<hostaddress> ) [W/L/M] see also : GetHostsName

GetHostsAddr (<hostname> ) [W/L/M] see also : GetHostsAddr

ExtractFilePath (<path>`)` [W/L/M] see also : ExtractFilePath

calculate(<arithmetic string expression>`)` // since 4.11.3.5 : knows: +-*/() [W/L/M] see also : calculate

DecStrToHexStr ( <decstring>, <hexlength>`)` [W/L/M] see also : DecStrToHexStr

HexStrToDecStr (<hexstring>`)` [W/L/M] see also : HexStrToDecStr

base64EncodeStr(<string>`)` [W/L/M] see also : base64EncodeStr

base64DecodeStr(<string>`)` [W/L/M] see also : base64DecodeStr

convert2Jsonstr(<string>`)` //since 4.10.8.3

RandomStr [W/L/M] see also : RandomStr

RandomStrWithParameters [W/L/M] see also : RandomStrWithParameters

RandomIntStr(<number str>`) : string` [W/L/M] see also : RandomIntStr

CompareDotSeparatedStrings(<string1>, <string2>`) : string` [W/L/M] see also : CompareDotSeparatedStrings_str

CompareDotSeparatedNumbers(<string1>, <string2>`) : string` [W/L/M] see also : CompareDotSeparatedNumbers_str

EnvVar (<environment variable>`)` [W/L/M] see also : EnvVar

ParamStr [W/L/M] see also : ParamStr

getDiffTimeSec (Time in seconds since last marktime) //since 4.11.3 [W/L/M] see also : getDiffTimeSec

SidToName(<well known sid>`)` //since 4.11.3: gives localized name of the sid [W] see also : SidToName

GetMyIpByTarget(<target ip addr>`) : string` //since 4.11.3.2 /4.11.6 [W/L/M] see also : GetMyIpByTarget

GetIpByName(<ip addr / ip name>`)` //since 4.11.3.2 [W/L/M] see also : GetIpByName

reencodestr(<str>, <from>, <to>`)` //since 4.11.4.2 [W/L/M] see also : reencodestr

strLoadTextFile ( <filename> ) //since 4.11.4.6 [W/L/M] see also : strLoadTextFile

strLoadTextFileWithEncoding ( <filename> , <encoding>`)` //since 4.11.4.6 [W/L/M] see also : strLoadTextFileWithEncoding

GetShortWinPathName(<longpath string>) //since 4.11.5.2 [W] see also : GetShortWinPathName

stringinput(< message str>,< boolstr confidential>`) : string` //since 4.12.1.2 [W/L/M] see also : stringinput

which(<command in path>`) : string` (command with path) //since 4.12.3.6 [W/L/M] see also : which

replaceOpsiConstants(<string>`) : string` //since 4.12.3.6 [W/L/M] see also : replaceOpsiConstants_string

ReadTOMLFile(<TOMLfilePath: String>`) : String` //since 4.12.5.0 [W/L/M] see also : ReadTOMLFile

GetTOMLAsString(<TOMLcontents: String>`) : String` //since 4.12.5.0 [W/L/M] see also : GetTOMLAsString

GetTOMLTableAsString(<TOMLcontents: String> , <table name : String>`) : String` //since 4.12.5.0 [W/L/M] see also : GetTOMLTableAsString

GetValueFromTOML(<TOMLcontents: String> , <keyPath: String> , <defaultValue: String>`) : String` //since 4.12.5.0 [W/L/M] see also : GetValueFromTOML

ModifyTOML(<TOMLcontents: String> , <command: String> , <keyPath: String> , <value: String>`) : String` //since 4.12.5.0 [W/L/M] see also : ModifyTOML

DeleteTableFromTOML(<TOMLcontents: String> , <tablePath: String>`) : String` //since 4.12.5 [W/L/M] see also : DeleteTableFromTOML

ConvertTOMLtoJSON(<TOMLcontents: String>`) : String` //since 4.12.5.0 [W/L/M] see also : ConvertTOMLtoJSON

Deprecated

GetNtVersion Deprecated - please use GetMsVersionInfo [W] see also : GetMsVersionInfo

IniVar (<key>`)` : (deprecated; use GetProductProperty) [W] see also : GetProductProperty

SubstringBefore (<string1>, <string2>`)` (deprecated; use splitString / takestring) [W/L/M] see also : splitString

String list functions
Important

splitString (<string1>, <string2>`)` [W/L/M]

set $list1$ = splitString ("\\server\share\dir","\")

see also : splitString

splitStringOnWhiteSpace (<string>`)` [W/L/M] see also : splitStringOnWhiteSpace

loadTextFile (<file name>`)` [W/L/M] see also : loadTextFile

loadUnicodeTextFile (<file name>`)` [W] see also : loadUnicodeTextFile

loadTextFileWithEncoding( <file name> , <encoding>`)` //since 4.11.5 [W/L/M] see also : loadTextFileWithEncoding

composeString (<string list>, <Link>`)` [W/L/M] see also : composeString

takeString (<index>, <list>`)` [W/L/M] see also : takeString

setStringInListAtIndex(<newstring>,<list>,<indexstr>`) : stringlist` //since 4.11.6 [W/L/M] see also : setStringInListAtIndex

takeFirstStringContaining(<list>,<search string>`)` [W/L/M] see also : takeFirstStringContaining

getOutStreamFromSection (<dos section name>`)` [W/L/M]

set $list$= getOutStreamFromSection ('DosInAnIcon_try')

shellCall (<command string>`) : stringlist (output)` //since 4.11.4.2 [W/L/M]

set $list$= shellCall('net start')

see also : shellCall_list

getReturnListFromSection (<xml section name>`)` [W/L/M] see also : getReturnListFromSection

getListContaining(<list>,<search string>`)` [W/L/M] see also : getListContaining

getListContainingList(<list1>,<list2>`)` //since 4.11.3.7 [W/L/M] see also : getListContainingList

count (<list>`)` [W/L/M] see also : count

emptylist (<list>`)` //since 4.11.3.7 [W/L/M] see also : emptylist

for %<identifier>`% in` <list> do <one statement | sub section> [W/L/M]

for %s% in $list1$ do sub_test_string

see also : forInDo

GetProcessList //since 4.11.1.2; gives list of exename;pid;dom/user [W/L/M] see also : GetProcessList

getProductPropertyList(<propname>,<default value>`)` //since 4.11.3 [W/L/M] see also : getProductPropertyList

getRegistryKeyList32(<regkey>`)` //since 4.11.3 [W] see also : getRegistryKeyList32

getRegistryKeyList64(<regkey>`)` //since 4.11.3 [W] see also : getRegistryKeyList64

getRegistryKeyListSysnative(<regkey>`)` //since 4.11.3 [W] see also : getRegistryKeyListSysnative

getRegistryKeyList(<regkey>, <access str>`)` //since 4.12.5.0 [W] see also : getRegistryKeyList

getRegistryVarList32(<regkey>`)` //since 4.11.3 [W] see also : getRegistryVarList32

getRegistryVarList64(<regkey>`)` //since 4.11.3 [W] see also : getRegistryVarList64

getRegistryVarListSysnative(<regkey>`)` //since 4.11.3 [W] see also : getRegistryVarListSysnative

getRegistryVarList(<regkey>, <access str>`)` //since 4.12.5.0 [W] see also : getRegistryVarList

getProfilesDirList //since 4.11.3.2 [W/L/M] see also : getProfilesDirList

listFiles (<Path>, <Searchmask> , <SearchSubDirectories>, <[Redirection]>`) : stringlist` //since 4.12.3 [W/L/M]

Set $Filelist$ = listFiles("C:\windows\system32","*.ico;*.dll","False","64bit")

see also : listFiles

replaceOpsiConstants(<string list>`) : stringlist` //since 4.12.3.6 [W/L/M] see also : replaceOpsiConstants_list

Infomaps

GetLocaleInfoMap [W] see also : GetLocaleInfoMap

GetMSVersionMap [W] see also : GetMSVersionMap

getLinuxVersionMap //since 4.11.4 [L]
keys are (example):

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

see also : getLinuxVersionMap

getFileInfoMap( <file name> ) [W] see also : getFileInfoMap

getProductMap // since 4.11.2.4 [W/L/M]
keys are: id, name, description, advice, productversion, packageversion, priority, installationstate, lastactionrequest, lastactionresult, installedversion, installedpackage, installedmodificationtime,actionrequest
see also : getProductMap

getRegistryVarMap32(<regkey>`)` //since 4.11.3 [W] see also : getRegistryVarMap32

getRegistryVarMap64(<regkey>`)` //since 4.11.3 [W] see also : getRegistryVarMap64

getRegistryVarMapSysnative(<regkey>`)` //since 4.11.3 [W] see also : getRegistryVarMapSysnative

getRegistryVarMap(<regkey>, <access str>`)` //since 4.12.5.0 [W] see also : getRegistryVarMap

getHWBiosInfoMap //since 4.11.4 [W/L/M] see also : getHWBiosInfoMap

editmap(< strlist>`) : stringlist` //since 4.12.1.2 [W/L/M] see also : editmap

Other

createStringList (<string0>, <string1> ,…​ ) [W/L/M]

set $list1$ = createStringList ('a','b')

see also : createStringList

reverse (<list>`)` [W/L/M] see also : reverse

getSectionNames(<ini-file>`)` [W/L/M] see also : getSectionNames

retrieveSection (<section name>`)` [W/L/M] see also : retrieveSection

getSubList (<start index> : <end index>, <list>`)` [W/L/M] see also : getSubList

getSubListByMatch (<search string>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByMatch_sl

getSubListByMatch (<search list>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByMatch_ll

getSubListByContaining ( <search string>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByContaining_sl

getSubListByContaining (<search list>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByContaining_ll

getSubListByKey (<search string>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByKey_sl

getSubListByKey (<search list>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByKey_ll

getKeyList (<list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getKeyList

addtolist(<list>,<string>`)` //since 4.10.8 [W/L/M] see also : addtolist

addListToList(<dest list>,<src list>`)` //since 4.10.8 [W/L/M] see also : addListToList

reencodestrlist(<list>, <from>, <to>`)` //since 4.11.4.2 [W/L/M] see also : reencodestrlist

removeFromListByContaining(<search string>`,` <target list>`) : stringlist` //since 4.11.5.1 [W/L/M] see also : removeFromListByContaining_str

removeFromListByContaining(<search list>`,` <target list>`) : stringlist` //since 4.11.5.1 [W/L/M] see also : removeFromListByContaining_list

removeFromListByMatch(<searchstring>,<target list>`) : stringlist` //since 4.11.6 [W/L/M] see also : removeFromListByMatch

LoadTOMLFile(<TOMLfilePath: String>`) : StringList` //since 4.12.5 [W/L/M] see also : LoadTOMLFile

GetTOMLAsStringList(<TOMLcontents: String>`) : StringList` //since 4.12.5 [W/L/M] see also : GetTOMLAsStringList

GetTOMLKeys(<TOMLcontents: String>`) : StringList` //since 4.12.5 [W/L/M] see also : GetTOMLKeys

GetTOMLTableNames(<TOMLcontents: String>`) : StringList` //since 4.12.5 [W/L/M] see also : GetTOMLTableNames

GetTOMLTable(<TOMLcontents: String> , <table name : String>`) : StringList` //since 4.12.5 [W/L/M] see also : GetTOMLTable

Boolean operators and functions

see also : Boolean Expressions

<string1> = <string2> [W/L/M]

<bool1> AND <bool2> [W/L/M]

<bool1> OR <bool2> [W/L/M]

NOT(<bool3>) [W/L/M]

FileExists (<file name>`)` [W/L/M] see also : FileExists

FileExists32 (<file name>`)` [W] see also : FileExists

FileExists64 (<file name>`)` [W] see also : FileExists

FileExistsSysNative (<file name>`)` [W] see also : FileExists

DirectoryExists (<folder path> [,<access str>]) : boolean //since 4.12.1 [W/L/M]
'sysnative' is the default for <access str>. Otherwise, it can be '32bit', '64bit' or 'sysnative' see also : DirectoryExists

FileOrFolderExists (<file or folder path> [,<access str>]) : boolean [W/L/M] 'sysnative' is the default for <access str>. Otherwise, it can be '32bit', '64bit' or 'sysnative' see also : FileOrFolderExists

fileIsSymlink (<file name>`)` // since 4.12.4.21 [W/L/M]
see also : fileIsSymlink

LineExistsIn (<string>, <file name>`)` [W/L/M] see also : LineExistsIn

LineBeginning_ExistsIn (<string>, <file name>`)` [W/L/M] see also : LineBeginning_ExistsIn

LineContaining_ExistsIn( <string>, <file name> ) //since 4.11.4.10: true: if a in <file name> contains <string> [W/L/M] see also : LineContaining_ExistsIn

XMLAddNamespace(<XMLfilename>, <XMLelementname>, <XMLnamespace>`)` [W] see also : XMLAddNamespace

XMLRemoveNamespace(<XMLfilename>, <XMLelementname>, <XMLnamespace>`)` [W] see also : XMLRemoveNamespace

HasMinimumSpace (<drive letter>, <capacity>`)` [W] see also : HasMinimumSpace

Example:

if not (HasMinimumSpace ("%SYSTEMDRIVE%", "500 MB"))
   LogError "Required free space of 500 MB not available on %SYSTEMDRIVE%"
   isFatalError
endif

opsiLicenseManagementEnabled [W/L/M] see also : opsiLicenseManagementEnabled

runningAsAdmin //since 4.11.1.1 [W/L/M] see also : runningAsAdmin

isLoginScript //since 4.11.2.1 [W] see also : isLoginScript

contains(<str>, <substr>`) : bool` //since 4.11.3: true if <substr> in <str> [W/L/M] see also : contains

isNumber(<str>`)` //since 4.11.3: true if <str> represents an integer [W/L/M] see also : isNumber

runningOnUefi //since 4.11.4.3: true: if the running OS was booted in UEFI mode [W] see also : runningOnUefi

runningInPE //since 4.12.0.13: true: if the running OS is a Windows PE [W/L/M] see also : runningInPE

runningInWAnMode //since 4.12.4.16: true: if opsiserver = localhost [W/L/M] see also : runningInWAnMode

isDriveReady(<drive letter>`)` //since 4.11.4.4: true: if the drive can be accessed [W] see also : isDriveReady

runningWithGui : bool` //since 4.12.3.6: true: if the running OS has a GUI (at Win+Mac always true)[M/L/W] see also : runningWithGui

saveTextFile(<list>, < filename>`)` //since 4.11.4.4: true: if list is succesfully written to file [W/L/M] see also : saveTextFile

saveTextFileWithEncoding(<list>, < filename>, <encoding>`) : bool` //since 4.11.6.4: true: if list is succesfully written to file [W/L/M] see also : saveTextFileWithEncoding

saveUnicodeTextFile(<list>, < filename>, <encoding>`) : bool` //since 4.12.4.13: true: if list is succesfully written to unicode file [W/L/M] see also : saveUnicodeTextFile

CompareDotSeparatedNumbers(<str1>,<relation str>,<str2>`)` //since 4.11.5.2: [W/L/M] see also : CompareDotSeparatedNumbers_bool

CompareDotSeparatedStrings(<str1>,<relation str>,<str2>`)` //since 4.11.5.2: [W/L/M] see also : CompareDotSeparatedStrings_bool

RegKeyExists(<regkey>[,<access str>]) : bool //since 4.12.0.16 [W]
<access str> = one of 32bit, 64bit, sysnative ; default sysnative see also : RegKeyExists

RegVarExists(<regkey>, <var str> ) : bool //since 4.12.0.16 [W]
<access str> = one of 32bit, 64bit, sysnative ; default sysnative see also : RegVarExists

isPingReachable(<host>) : boolean //since 4.12.3.6 [W/L/M] see also : isPingReachable

isValidFQDN(<domain name>) : boolean //since 4.12.4.4 [W/L/M] see also : isValidFQDN

fileHasBom (<file name>`) : boolean` //since 4.12.4.17 [W/L/M] see also : fileHasBom

SaveToTOMLFile(<TOMLcontents: String> , <TOML file Path: String>`) : boolean` //since 4.12.5 [W/L/M] see also : SaveToTOMLFile

ConvertTOMLfileToJSONfile(<TOMLfilePath: String> , <JSONfilePath: String>`) : boolean` //since 4.12.5 [W/L/M] see also : ConvertTOMLfileToJSONfile

Misc functions

Killtask <process name> [W/L/M] see also : Killtask

requiredOpsiscriptVersion <relation operator> <version> //since 4.12.3.6 [W/L/M]

requiredOpsiscriptVersion >= "4.12.3.6"

requiredWinstVersion <relation operator> <version> [W/L/M]
outdatet - use requiredOpsiscriptVersion see also : requiredOpsiscriptVersion

UpdateEnvironment //since 4.11.5 [W]:
Subsequent calls of winbatch with the parameter /RunElevated will see the changed Environment (NT6 only). see also : UpdateEnvironment

Flow control

'if - elseif - else - endif' [W/L/M] see also : IfElseEndif

Syntax:

if <condition>
;statement(s)
[elseif <condition>
;statement(s)]
[else
;statement(s)]
endif

elseif //since 4.12.4.37

Example:

Set $NTVer$ = GetMsVersionInfo
if ( $NTVer$ >= "6" )
     sub_install_win7
else
  if ( $NTVer$ = "5.1" )
    sub_install_winXP
  else
    stop "not a supported OS-Version"
  endif
endif

'for - to - do' Statement //since 4.11.5 [W/L/M] see also : ForToDo

for %<temporary string variable>% = <start string> to <end string> do <one statement>

Example:

for %s% = "1" to "5" do sub_iteration_test

'Switch / Case' Statement //since 4.11.5 [W/L/M]
ifdef::manual[see also : SwitchCase]
Can not be nested.
see also : [IfElseEndif]

Syntax:

Switch <string expression>
  Case <string const>
    <statement(s)>
  EndCase
  [DefaultCase
    <statement(s)>
   EndCase]
EndSwitch

Example:

set $ConstTest$ = "5"
Switch $ConstTest$
	Case "1"
		set $CompValue$ = "1"
	EndCase
	Case "2"
		set $CompValue$ = "2"
	EndCase
	DefaultCase
		set $CompValue$ = "notexisting"
	EndCase
EndSwitch

isFatalError [W/L/M] see also : isFatalError

isFatalError <string> //since 4.11.3.2 [W/L/M] see also : isFatalError

isSuccess //since 4.11.3.7 [W/L/M] see also : isSuccess

isSuspended //since 4.11.4.1 [W/L/M] see also : isSuspended

noUpdateScript //since 4.11.3.7 [W/L/M] see also : noUpdateScript

ExitWindows /Reboot [W/L/M] see also : Reboot

ExitWindows /ImmediateReboot [W/L/M] see also : ImmediateReboot

ExitWindows /ImmediateLogout [W] see also : ImmediateLogout

ExitWindows /ShutdownWanted [W] see also : ShutdownWanted

ExitWindows /RebootWanted (deprecated, acts like /Reboot) [W] see also : Reboot

sleepSeconds <Integer> or <string> : noresult [W/L/M] see also : sleepSeconds

ChangeDirectory <directory> //since 4.11.2.6 [W/L/M] see also : ChangeDirectory

3.3. Secondary Sections

3.3.1. Winbatch [W/L/M]

Function: execute programs via operating system API

[WinBatch<identifier>`]`

Modifier:

/LetThemGo

/WaitForProcessEnding "<program.exe>"

/TimeOutSeconds <seconds>

/WaitForWindowAppearing <window title> ('does not work with 64 Bit programs') [W]

/WaitForWindowVanish <window title> ('does not work with 64 Bit programs') [W]

/RunElevated // since 4.11.3: only at >= NT6 ; no network access [W]

/RunAsLoggedOnUser // since 4.11.3.5 ; works only inside 'userLoginScripts' [W]

/32Bit //since 4.11.3.5 [W]

/64Bit //since 4.11.3.5 [W]

/SysNative //since 4.11.3.5 [W]

3.3.2. DosBatch and DosInAnIcon (ShellBatch and ShellInAnIcon) [W/L/M]

Function: Execute section via cmd.exe [W] or bash [L/M]

[DosBatch<identifier>`]` <optional parameters> <winst <modifier>>

[DosInAnIcon<identifier>`]` <optional parameters> <winst <modifier>>

[ShellBatch<identifier>`]` <optional parameters> <winst <modifier>>

[ShellInAnIcon<identifier>`]` <optional parameters> <winst <modifier>>

Modifier: //since 4.11.1.1

/32Bit [W]

/64Bit [W]

/SysNative [W]

/showoutput [W/L/M] // since 4.11.4.7

/WaitForProcessEnding "<program.exe>" // since 4.12.4 [W/L/M]

/TimeOutSeconds <seconds> // since 4.12.4 [W/L/M]

/RunElevated // since 4.12.4: only at >= NT6 ; no network access [W]

/RunAsLoggedOnUser // since 4.12.4.31 ; works only inside 'userLoginScripts' [W]

The modifiers has to be seperated by 'winst' from the parameters.

DosInAnIcon_do_64bit_stuff winst /64Bit

Commands: see manual

3.3.3. ExecWith [W/L/M]

see also : ExecWith Sections

Function: Execute section via any interpreter

[ExecWith<identifier>`]` <path to interpreter>

Modifier:

/LetThemGo

/EscapeStrings

/32Bit //since 4.11.3.5 [W]

/64Bit //since 4.11.3.5 [W]

/SysNative //since 4.11.3.5 [W]

/RunAsLoggedOnUser // since 4.12.4.31 ; works only inside 'userLoginScripts' [W]

The modifiers has to be seperated by 'winst' from the parameters. The following example call the 64Bit version of the powershell.exe.

ExecWith_do_64bit_stuff "%System%\WindowsPowerShell\v1.0\powershell.exe" winst /64Bit

Commands: see manual

3.3.4. Files [W/L/M]

see also : Files

Function: File Operations

[Files<identifier>`]`

Modifier [W]:

/AllNTUserProfiles

/AllNTUserSendTo [W]

/32Bit //since 4.10.8 [W]

/64Bit //since 4.10.8 [W]

/SysNative //since 4.10.8 [W]

Commands:

checkTargetPath = <destination directory> [W/L/M]

copy [Options] <source file(s)> <destination directory> [W/L/M]

some options:

-s recursive [W/L/M]

-e empty Subdirectories

-V version control against targetdir [W]

-v version control against targetdir, %systemroot% and %system% (do not use it) [W]

-c continue without reboot even if it is needed [W]

-d date check [W]

-u update [W]

-x extract [W]

-w weak (do not overwrite protected files) [W]

-n no overwrite [W]

-r copy read only attribute [W]

-h follow symlinks [L] //since 4.11.6.14

delete [Options] <path[/mask]] // [W/L/M]

options:

-s recursive

-f force

r -del on reboot

c continue with out reboot

d [n] date

Example (do not forget the trailing Backslash):
delete -sf c:\delete_this_dir\

del [Options] <path[/mask]] //since 4.11.2.1 [W/L/M]

Works like delete but on
del -s -f c:\not-exists
if c:\not-exists not exists it do not search complete c:\ for not-exits

Example (you may forget the trailing Backslash):
del -sf c:\delete_this_dir

chmod <mode> <path> //since 4.11.4.1 [L]

hardlink <existing file> <new file> // since 4.11.5 [W/L/M]

symlink <existing file> <new file> // since 4.11.5 [W/L/M]
At Windows symlink is only available at NT6 and up.

rename <old filename> <new filename> // since 4.11.5 [W/L/M]

move <old filename> <new filename> // since 4.11.5 [W/L/M]

zipfile <source dir> <zip file> // since 4.12.1 [W/L/M]

unzipfile <zip file> <target dir> // since 4.12.1 [W/L/M]

3.3.5. Registry [W]

see also : Registry

Function: edit Registry

Standard method call:
[Registry<identifier>`]`
works with the specified section.

Alternative method call:
Registry loadUnicodeTextFile(<.reg file>`) /regedit`
import the specified <.reg file>.

Alternative method call (deprecated):
Registry loadUnicodeTextFile(<.addreg file>`) /addreg`
import the specified <.addreg file>.

Modifier:

/AllNTUserDats

/32Bit //since 4.10.8

/64Bit //since 4.10.8

/SysNative //since 4.10.8

Commands:

OpenKey <Key>

openkey [HKLM\Software\opsi.org]

Set <varname> = <registry type>:<value>

Add <varname> = <registry type>:<value>

Examples for registry types:

set "var1" = "my string"
set "var2" = REG_SZ:"my string"
set "var3" = REG_EXPAND_SZ:"%ProgramFiles%"
set "var4" = REG_DWORD:123	; Decimal
set "var5" = REG_DWORD:0x7b	; Hexadecimal
; REG_QWORD is supported since 4.12.6
set "var6" = REG_QWORD:59049772908	; Decimal
set "var7" = REG_QWORD:0xDBFA4076C	; Hexadecimal
set "var8" = REG_BINARY:00 01 02 0F 10
set "var9" = REG_MULTI_SZ:"A|BC|de"

Supp <varname> <list char> <supplement>

supp "Path" ; "C:\utils; %JAVABIN%"

GetMultiSZFromFile <varname> <file name>

SaveValueToFile <varname> <file name>

DeleteVar <varname>

DeleteKey <registry key> (does since 4.11.2.1 also work with /AllNTUserDats)

3.3.6. Patches [W/L/M]

see also : Patches

Function: edit Ini-files

[Patches<identifier>`]` <file name>

Modifier:

/AllNTUserProfiles //since 4.11.3 [W]

Commands:

add [<section name>`]` <variable1> = <value1>

set [<section name>`]<variable1> `= <value1>

addnew [<section name>`]<variable1> `= <value1>

change [<section name>`]<variable1> `= <value1>

del [<section name>`]` <variable1> = <value1>

del [<section name>`]` <variable1>

delsec [<section name>`]`

replace <variable1>`=<value1> <variable2>=`<value2>

3.3.7. PatchTextFile [W/L/M]

see also : PatchTextFile

Function: edit text files

[PatchTextFile<identifier>`]` <file name>

Modifier:

/AllNTUserProfiles //since 4.11.3.4 [W]

/encoding <encoding> //since 4.12.4.17 [W/L/M]

Commands:

Set_Mozilla_Pref (`"<preference type>", "<preference key>", "<preference value>")`
'preference type' takes any value.
Some examples for preference types: pref, user_pref, lock_pref or lockPref.

AddStringListElement_To_Mozilla_Pref (`"<preference type>", "<preference key>", "<add value>")`

Set_Netscape_User_Pref (`"<key>", "<value>")` ('deprecated')

AddstringListElement_To_Netscape_User_Pref ('deprecated')

FindLine <search string>

FindLine_StartingWith <search string>

FindLine_Containing <search string>

GoToTop

AdvanceLine [<number of lines>]

GoToBottom

DeleteTheLine

AddLine_ <line> or Add_Line_ <line>

InsertLine <line> or Insert_Line_ <line>

AppendLine <line> or Append_Line <line>

Append_File <file name>

Subtract_File <file name>

SaveToFile <file name>

Sorted

setKeyValueSeparator <separator char> //since 4.11.4.4 [W/L/M]

setValueByKey <keystr> <valuestr> //since 4.11.4.4 [W/L/M]

3.3.8. LinkFolder [W/L/M]

see also : LinkFolder

Function: Startmenue + Desktop Icons

[LinkFolder<identifier>`]`

Commands:

set_basefolder <system folder>

set_subfolder <folder path> (at Linux set always "")

set_link
  name:            <link name>
  target:          <path and name of the program>
  parameters:      [command line arguments]
  working_dir:     [working directory]
  icon_file:       [path and name of icon file, default=target]
  icon_index:      [number of icon in icon file, default=0] [W]
  shortcut:        [keyboard shortcut for calling the target] [W]
  window_state:    [initial show state of the window] [W]
  link_categories: [list of categories] [L]
end_link

delete_element <link name>

delete_subfolder <folder path> [W]

The predefined virtual system folders which can be used are at Windows:
desktop, sendto, startmenu, startup, programs, desktopdirectory,
common_startmenu, common_programs, common_startup, common_desktopdirectory
and at Linux:
common_programs,common_startup,desktop, startup

Predefined link_categories for Linux:
AudioVideo, Audio, Video, Development, Education, Game, Graphics, Network, Office, Settings, System, Utility

Examples

set_basefolder common_desktopdirectory
set_subfolder ""
set_link
  name: opsi-winst
  target: "%ProgramFiles32Dir%\opsi.org\opsi-client-agent\opsi-winst\winst32.exe"
end_link
[LinkFolder_configed_lin]
set_basefolder common_programs
set_subfolder ""

set_link
  name: opsi-configed-Local
  target: java
  parameters: $parameter$
  icon_file: "$InstallDir$/opsi.png"
  link_categories: System;Utility;
end_link

The predefined virtual system folders:
desktop, sendto, startmenu, startup, programs, desktopdirectory
are pointing to the folders of the user that the script is running. If you use it in a userLoginScript with the opsi 'User Profile Management' extension these virtual folders point to the folder of the user that just had logged in.

'shortcut' defaults to empty. // since 4.11.6.7
shortcut may be a combination of ['shift','alt','ctrl'] (not case sensitiv) divided by ' ', '-','+' an a 'Key' or a 'Virtual Key Code'.
The 'Key' is a letter ('A' - 'Z') or a numeral ('0' - '9'). All other Keys must be given by there 'Virtual Key Code' identifier. To get these identifier (as well as the allowed combinations) just use the following helper program:
http://download.uib.de/opsi4.0/helper/showkeys.exe

3.3.9. OpsiServiceCall [W/L/M]

see also : OpsiServiceCall

Function: opsi-Service access

[OpsiServiceCall<identifier>`]`

Commands: see manual

3.3.10. PatchHosts [W/L/M]

see also : PatchHosts

Function: hosts-files bearbeiten

[PatchHosts<identifier>`]`

Commands:

setaddr <hostname> <IPaddress>

setname <IPaddress> <hostname>

setalias <hostname> <alias>

setalias <IPadresse> <alias>

delalias <hostname> <alias>

delalias <IPaddress> <alias>

delhost <hostname>

delhost <ipadresse>

setComment <ident> <comment>

3.3.11. XML2 Sections [W/L/M]

see also : XML2 Sections

Function: edit XML files
since 4.12.1.0

[XML2<identifier>`]`

Commands:

  • strictMode = (true/false) ; Default: false

  • openNode <xml2 path>
    Open the given path as actual node. If the path does not exist, it will be created.

  • SetAttribute <attr name> <attr value>
    At the actual node set <attr value> as value of <attr name>. If <attr name> does not exist, it will be created.

  • AddAttribute <attr name> <attr value>
    If the attribute <attr name> does not exist at the actual node, it will be created with <attr value> as value. If <attr name> already exists, nothing will be changed.

  • DeleteAttribute <attr name>
    If the attribute <attr name> exists at the actual node, it will be deleted.

  • addNewNode <node name>
    Create at the actual node a new sub node <node name> and make this new node to the actual node.

  • setNodeText <string>

  • DeleteNode <xml2 path>

  • gotoParentNode
    Make the parent node to the actual node.

  • rootNodeOnCreate = <node name> // since 4.12.4.27
    If the file does not exist, it will be created with <node name> as root node name.

  • setNodePair <keyNodeName> <keyNodeTextContent> <valueNodeName> <valueNodeTextContent> // since 4.12.4.28
    Creates a <dict> entry like it is used in the Apple info.plist files.

Some notes on the command parameters:

  • <xml2 path> strictMode =false:
    A line of xml node names without any attributes seprated by '` // '.
    Example: `node_level-1_number-1 // node_level-2_B color="green"

  • <xml2 path> strictMode =true:
    A line of xml node names with all existing attributes seprated by '` // '.
    Example: `node_level-1_number-1 // node_level-2_B color="green" count="65"

see also : Abschnitt 3.4.25

see also : XML2 Functions

3.3.12. XMLPatch [W]

see also : XMLPatch

Function: edit XML files
Deprecated: please use xml2 sections: Abschnitt 3.3.11
and xml2 functions: Abschnitt 3.4.25

[XMLPatch<identifier>`]`

Commands: see manual

3.3.13. ExecPython [W/L/M]

see also : ExecPython

Function: Execute section via python interpreter

[ExecPython<identifier>`]`

Commands: see manual

3.3.14. LdapSearch [WLM]

see also : LdapSearch

Function: read from LDAP

[LdapSearch<identifier>`]`

Commands: see manual

3.4. By Topic

3.4.1. Compare related functions [W/L/M]

CompareDotSeparatedStrings(<string1>, <string2>`) : string` [W/L/M] see also : CompareDotSeparatedStrings_str

CompareDotSeparatedStrings(<str1>,<relation str>,<str2>`) : bool` //since 4.11.5.2: [W/L/M] see also : CompareDotSeparatedStrings_bool

CompareDotSeparatedNumbers(<string1>, <string2>`) : string` [W/L/M] see also : CompareDotSeparatedNumbers_str

CompareDotSeparatedNumbers(<str1>,<relation str>,<str2>`) : bool` //since 4.11.5.2: [W/L/M] see also : CompareDotSeparatedNumbers_bool

boolToString(<boolean expression>`)` : bool string (true/false) // since 4.12.0.0 [W/L/M] see also : boolToString

stringToBool(<string expression: true/false>`)` : boolean // since 4.12.0.0 [W/L/M] see also : stringToBool

3.4.2. Crypt / Hash related functions [W/L/M]

DecStrToHexStr ( <decstring>, <hexlength>`) : string` [W/L/M] see also : DecStrToHexStr

HexStrToDecStr (<hexstring>`) : string` [W/L/M] see also : HexStrToDecStr

base64EncodeStr(<string>`) : string` [W/L/M] see also : base64EncodeStr

base64DecodeStr(<string>`) : string` [W/L/M] see also : base64DecodeStr

RandomStr : string [W/L/M] see also : RandomStr

RandomIntStr(<number str>`) : string` [W/L/M] see also : RandomIntStr

encryptStringBlow(<keystring>,<datastring>`) : string` [W/L/M] see also : encryptStringBlow

decryptStringBlow(<keystring>,<datastring>`) : string` [W/L/M] see also : decryptStringBlow

md5sumFromFile(<path to file>`) : string` [W/L/M] see also : md5sumFromFile

hashFromFile(<FileName>, <Hashing Algorithm>`) : string` [W/L/M] //since 4.12.5 see also : hashFromFile

isCertInstalledInSystem(<label>`) : boolstring` [W/L/M] //since 4.12.4.37 see also : [isCertInstalledInSystem]

importCertToSystem(<filename>`) : noresult` [W/L/M] //since 4.12.4.37 see also : [importCertToSystem]

removeCertFromSystem(<label>`) : noresult` [W/L/M] //since 4.12.4.37 see also : [removeCertFromSystem]

listCertificatesFromSystem : stringlist` [W/L/M] //since 4.12.4.37 see also : [listCertificatesFromSystem]

3.4.3. Defined Functions and Libraries [W/L/M]

since 4.12.0.0

Definition

DefFunc <func name>([calltype parameter ptype][,[calltype parameter ptype]]) : ftype
<function body>
endfunc

Where:

  • DefFunc is the keyword used to start defining a local function.

  • '<func name>' is the freely choosen name of the function.

  • 'calltype' is the call type of the parameter [val | ref]. val='Call by Value', ref='Call by Reference'. Default: val

  • 'parameter' is the freely selected name of the call parameter which is available as a local variable within the function under the aforementioned name.

  • 'ptype' is the type of data of the parameter and either string or stringlist.

  • 'ftype' is the type of data of the function and either string ,stringlist or void. void declares that no result is returned.

  • '<function body>' is the body of the function which must conform to the opsi-script syntax.

  • endfunc is the keyword used to end defining a local function.

see also : localfunctions

importLib <string expr> ; import library // since 4.12.0.0
<string expr> : <file name>[.<file extension>][::<function name>]
If no '.<file extension>' is given .opsiscript is used as default.
If no '::<function name>' is given, all function from the given file will be imported.

<file name> is:

  • A complete path to an existing file. [W/L/M]

  • An existing file in %ScriptPath% [W/L/M]

  • A file in %opsiScriptHelperPath%\lib [W]
    Is equivalent to: '%ProgramFiles32Dir%\opsi.org\opsiScriptHelper\lib'

  • An existing file in %ScriptPath%/../lib [W/L/M]

  • An existing file in %WinstDir%\lib [W] or /usr/share/opsi-script/lib [L]

The tests for the location of the <file name> are done in the order above. 'opsi-script' uses the first file it finds that has a matching name.

see also : Abschnitt 9.24

3.4.4. Encoding related functions [W/L/M]

encoding=<encoding> // (default is system encoding) since 4.11.4.2 see also : encoding

GetLocaleInfoMap : stringlist [W] see also : GetLocaleInfoMap

reencodestr(<str>, <from>, <to>`) : string` //since 4.11.4.2 [W/L/M] see also : reencodestr

reencodestrlist(<list>, <from>, <to>`) : stringlist` //since 4.11.4.2 [W/L/M] see also : reencodestrlist

fileHasBom (<file name>) : boolean` //since 4.12.4.17 [W/L/M] see also : fileHasBom

loadUnicodeTextFile (<file name>`) : stringlist` [W/L/M] see also : loadUnicodeTextFile

loadTextFileWithEncoding( <file name> , <encoding>`) : stringlist` //since 4.11.5 [W/L/M] see also : loadTextFileWithEncoding

strLoadTextFileWithEncoding ( <filename> , <encoding>`) : string` //since 4.11.4.6 [W/L/M] see also : strLoadTextFileWithEncoding

saveTextFileWithEncoding(<list>, < filename>`,` <encoding>`) : bool` //since 4.11.6.4: true: if list is succesfully written to file [W/L/M] see also : saveTextFileWithEncoding

includelog <file name> <tail size> [<encoding>] ` : noresult`//since 4.11.4.1 [W/L/M] see also : includelog

3.4.5. Error / Warning related functions [W/L/M]

ExitOnError = <boolean value> // (default=false) see also : ExitOnError

ScriptErrorMessages = <boolean value> // (default=true)

see also : ScriptErrorMessages

FatalOnSyntaxError = <boolean value> // (default=true) since 4.11.3.2 see also : FatalOnSyntaxError

FatalOnRuntimeError = <boolean value> // (default=false) since 4.11.3.2 see also : FatalOnRuntimeError

LogError <string> or LogError = <const string> see also : LogError

LogWarning <string> or LogWarning = <const string> see also : LogWarning

isFatalError [W/L/M] see also : isFatalError

isFatalError <string> //since 4.11.3.2 [W/L/M] see also : isFatalError

markErrorNumber see also : markErrorNumber

errorsOccurredSinceMark <relation> <integer> : boolean see also : errorsOccurredSinceMark

markErrorNumber
comment "log error and thereby increase the error counter"
if errorsOccurredSinceMark > 0
	comment "There was an error ..."
endif

getLastExitCode : string (exitcode) [W/L/M] see also : getLastExitCode

shellCall (<command string>`) : string (exitcode)` //since 4.11.6.1 [W/L/M] see also : shellCall_str

processCall(<string>`) : string (exitcode)` //since 4.11.6.1 [W/L/M] see also : processCall

getLastServiceErrorClass : string see also : getLastServiceErrorClass

getLastServiceErrorMessage : string see also : getLastServiceErrorMessage

3.4.6. File related functions [W/L/M]

strLoadTextFile (<file name>`) : string` [W/L/M] see also : strLoadTextFile

strLoadTextFileWithEncoding ( <filename> , <encoding>`) : string` //since 4.11.4.6 [W/L/M] see also : strLoadTextFileWithEncoding

loadTextFile (<file name>`) : stringlist` [W/L/M] see also : loadTextFile

loadUnicodeTextFile (<file name>`) : stringlist` [W] see also : loadUnicodeTextFile

loadTextFileWithEncoding( <file name> , <encoding>`) : stringlist` //since 4.11.5 [W/L/M] see also : loadTextFileWithEncoding

fileHasBom (<file name>) : boolean` //since 4.12.4.17 [W/L/M] see also : fileHasBom

FileExists (<file name>`) : bool` [W/L/M] see also : FileExists

FileExists32 (<file name>`) : bool` [W] see also : FileExists

FileExists64 (<file name>`) : bool` [W] see also : FileExists

FileExistsSysNative (<file name>`) : bool` [W] see also : FileExists

DirectoryExists (<folder path> [,<access str>]) : boolean //since 4.12.1 [W/L/M]
'sysnative' is the default for <access str>. Otherwise, it can be '32bit', '64bit' or 'sysnative' see also : DirectoryExists

FileOrFolderExists (<file or folder path> [,<access str>]) : boolean [W/L/M] 'sysnative' is the default for <access str>. Otherwise, it can be '32bit', '64bit' or 'sysnative' see also : FileOrFolderExists

fileIsSymlink (<file name>`) : bool` // since 4.12.4.21 [W/L/M]
see also : fileIsSymlink

resolveSymlink (<file name>`) : <file name>` // since 4.12.4.21 [W/L/M]
see also : resolveSymlink

listFiles (<Path>, <Searchmask> , <SearchSubDirectories>, <[Redirection]>`) : stringlist` //since 4.12.3 [W/L/M]

Set $Filelist$ = listFiles("C:\windows\system32","*.ico;*.dll","False","64bit")

see also : listFiles

forcePathDelims (<path string>`) : <path string>` // since 4.12.4.21 [W/L/M]
see also : forcePathDelims

LineExistsIn (<string>, <file name>`) : bool` [W/L/M] see also : LineExistsIn

LineBeginning_ExistsIn (<string>, <file name>`) : bool` [W/L/M] see also : LineBeginning_ExistsIn

LineContaining_ExistsIn( <string>, <file name> ) : bool //since 4.11.4.10 [W/L/M]
true: if a in <file name> contains <string> see also : LineContaining_ExistsIn

saveTextFile(<list>, < filename>`) : bool` //since 4.11.4.4 [W/L/M]
true: if list is succesfully written to file see also : saveTextFile

saveTextFileWithEncoding(<list>, < filename>`,` <encoding>`) : bool` //since 4.11.6.4 [W/L/M]
true: if list is succesfully written to file see also : saveTextFileWithEncoding

getFileInfoMap( <file name> ) : stringlist [W] see also : getFileInfoMap

getFileInfoMap32( <file name> ) : stringlist //since 4.11.6.6 [W] see also : getFileInfoMap

getFileInfoMap64( <file name> ) : stringlist //since 4.11.6.6 [W] see also : getFileInfoMap

getFileInfoMapSysnative( <file name> ) : stringlist //since 4.11.6.6 [W] see also : getFileInfoMap

ExtractFilePath (<path>`) : string` [W/L/M] see also : ExtractFilePath

ExtractFileExtension (<path>`) : string` [W/L/M] //since 4.12.1 see also : ExtractFileExtension

ExtractFileName (<path>`) : string` [W/L/M] //since 4.12.1 see also : ExtractFileName

see also: Abschnitt 3.3.4

see also: Abschnitt 3.3.7

3.4.7. Ini file related functions [W/L/M]

GetValueFromInifile (<file path>, <section>, <key>, <default value>, OPTIONAL <encoding>`) : string` [W/L/M]
see also : GetValueFromInifile

getSectionNames(<ini-file>`) : stringlist` [W/L/M] see also : getSectionNames

GetSectionFromInifile(<ini-file>`) : stringlist` [W/L/M] see also : GetSectionFromInifile

getValue(<key string>, <hash string list>`) : string` [W/L/M] see also : getValue

getValueBySeparator(<key string>,<separator string>,<hash string list>`) : string` //since 4.11.2.1 [W/L/M] see also : getValueBySeparator

setValueByKey(<key>, <value>, <targetlist> ) : stringlist [W/L/M] see also : [setValueByKey]

getValueFromFile(<key string>, <file name>`) : string` //since 4.11.4.4 [W/L/M] see also : getValueFromFile

getValueFromFileBySeparator(<key string>,<separator string>,<file name>`) : string` //since 4.11.4.4 [W/L/M] see also : getValueFromFileBySeparator

see also: Abschnitt 3.3.6

3.4.8. Interaction [W/L/M]

Pause <string> or Pause = <const string> see also : Pause

Stop <string> or stop = <const string> see also : Stop

setActionProgress <string> : noresult //since 4.11.3 [W/L/M] see also : setActionProgress

Message <string> or Message = <const string> see also : Message

ShowMessageFile <string> see also : ShowMessageFile

ShowBitMap [<file name>] [<sub title>] see also : ShowBitMap

stringinput(< message str>,< boolstr confidential>`) : string` //since 4.12.1.2 [W/L/M] see also : stringinput

editmap(< strlist>`) : stringlist` //since 4.12.1.2 [W/L/M] see also : editmap

3.4.9. License Management related functions [W/L/M]

DemandLicenseKey( poolId [, productId [,windowsSoftwareId]] ) : string

set $mykey$ = DemandLicenseKey ("", "office2007")

see also : DemandLicenseKey

FreeLicense (`poolId [, productId [,windowsSoftwareId]]) : string`

set $result$ = FreeLicense("", "office2007")

see also : FreeLicense

getLastServiceErrorClass : string see also : getLastServiceErrorClass

getLastServiceErrorMessage : string see also : getLastServiceErrorMessage

opsiLicenseManagementEnabled : bool see also : opsiLicenseManagementEnabled

3.4.10. Linux specific functions [W/L/M]

GetOS : string // 'Linux' or 'Windows_NT' or 'macos' [W/L/M] see also : GetOS

getLinuxDistroType : string // 'debian' or 'redhat' or 'suse' (see getLinuxVersionMap) [L] see also : getLinuxDistroType

getLinuxVersionMap : stringlist //since 4.11.4 [L] see also : getLinuxVersionMap

chmod in Files sections [L/M] see also : Commands

waitForPackageLock(<wait_seconds>,<abort_on_timeout>`) : bool` // since 4.11.6.1 [L] see also : waitForPackageLock

importlib "uib_lin_install" :

cleanupPackageSystem : void //since 4.13.4 [L] see also : cleanupPackageSystem

installupdates : string //since 4.13.4 [L] see also : installupdates

debinstall($packagelist$ : stringlist) : string //since 4.13.4 [L] see also : debinstall

redinstall($packagelist$ : stringlist) : string //since 4.13.4 [L] see also : redinstall

suseinstall($packagelist$ : stringlist) : string //since 4.13.4 [L] see also : suseinstall

ucsinstall($packagelist$ : stringlist) : string //since 4.13.4 [L] see also : ucsinstall

genericLinInstall($packagelist$ : stringlist) : string
see also : genericLinInstall

linuxInstallOneOf($packagelist$ : stringlist) : string
see also : genericLinInstall

isOneInstalled($packagelist$ : stringlist) : string
see also : linuxInstallOneOf

linuxInstallOneFile($packagefile$ : string) : string
see also : linuxInstallOneFile

linuxRemoveOnePackage($packagename$ : string) : string
see also : linuxRemoveOnePackage

linuxRemoveOneOf($packagelist$ : stringlist) : string
see also : linuxRemoveOneOf

3.4.11. Logging related functions [W/L/M]

SetLogLevel = <number> or SetLogLevel = <string> // (default=6)

SetLogLevel = 7
SetLogLevel = "7"

SetDebug_Lib = <boolean value> // (default=false) see also : SetDebugLib

Message <string> or Message = <const string> see also : Message

comment <string> or comment = <const string> see also : comment

LogError <string> or LogError = <const string> see also : scriptWasExecutedBefore

LogWarning <string> or LogWarning = <const string> see also : LogError

includelog <file name> <tail size> //since 4.11.2.1 [W/L/M] see also : includelog

includelog <file name> <tail size> [<encoding>] //since 4.11.4.1 [W/L/M] see also : includelog

includelog "%Scriptpath%\test-files\10lines.txt" "5"

SetConfidential <secret string> //since 4.11.3.5 [W/L/M] see also : setConfidential

asConfidential( <secret string expression> ) : string //since 4.12.0.16 [W/L/M] see also : asConfidential_str

asConfidential( <secret stringlist expression> ) : stringlist //since 4.12.4.15 [W/L/M] see also : asConfidential_list

forceLogInAppendMode = <boolean value> // (default=false); if true, log will be send in append mode . //since 4.12.3.6 see also : forceLogInAppendMode

opsi-configs

opsi-script.global.debug_prog : boolean ; if false: only Warnings and Errors from program logging; default: false
see also : Central configuration via opsi Configs

opsi-script.global.debug_lib : boolean ; if false: only Warnings and Errors from library logging; default: false
see also : Central configuration via opsi Configs

opsi-script.global.default_loglevel : intstr ; set the default log level; default: '6'
see also : Central configuration via opsi Configs

opsi-script.global.force_min_loglevel : intstr ; set the minimal loglevel; default: '0'
see also : Central configuration via opsi Configs

opsi-script.global.ScriptErrorMessages : boolean ; overwrites the opsi-script internal default; default: false
see also : ScriptErrorMessages

opsi-script.global.AutoActivityDisplay : boolean ; overwrites the opsi-script internal default; default: true
see also : AutoActivityDisplay

opsi-script.global.SupressSystemEncodingWarning : boolean ; suppress some encoding warnings; default: false
see also : SupressSystemEncodingWarning

opsi-script.global.ReverseProductOrderByUninstall : boolean ; product list is reordered for uninstall; default: false
see also : ReverseProductOrderByUninstall

opsi-script.global.log_rotation_count : boolean ; number of opsi-script.log backups; default: 8
see also : log_rotation_count

opsi-script.global.writeProductLogFile : boolean ; logs for every single opsi product; default: false
see also : writeProductLogFile

3.4.12. macOS specific functions [W/L/M]

GetOS : string // 'Linux' or 'Windows_NT' or 'macos' [W/L/M] see also : GetOS

getMacosVersionInfo : string //macOS Version Information //since 4.12.1.0 [M] see also : getMacosVersionInfo

getMacosVersionMap : stringlist //macOS Version map //since 4.12.1.0 [M] see also : getMacosVersionMap

GetSystemType : string //OS Architecture ("64 Bit System" or "x86 System") [W/L/M] see also : GetSystemType

getOSArchitecture // OS Architecture (x86_32 / x86_64/ arm_64) //since 4.12.4.17 [W/L/M]
see also : getOSArchitecture

importlib "uib_macosinstalllib" :

install_macos_app($myapp$ : string) : string [M]
see also : xref:install_macos_app>>

install_macos_pkg($mypkg$ : string) : string [M]
see also : xref:install_macos_pkg>>

install_macos_dmg($mydmg$ : string) : string [M]
see also : xref:install_macos_dmg>>

install_macos_zip($myzip$ : string) : string [M]
see also : xref:install_macos_zip>>

install_macos_generic($myfile$ : string) : string [M] see also : install_macos_generic

3.4.13. Network related functions [W/L/M]

GetHostsName (<hostaddress> ) : string [W/L/M] see also : GetHostsName

GetHostsAddr (<hostname> ) : string [W/L/M] see also : GetHostsAddr

GetMyIpByTarget(<target ip addr>`) : string` //since 4.11.3.2 /4.11.6 [W/L/M] see also : GetMyIpByTarget

GetIpByName(<ip addr / ip name>`) : string` //since 4.11.3.2 [W/L/M] see also : GetIpByName

isValidIP4 (<ip4adr>) : boolean //since 4.12.1 see also : isValidIP4

isValidIP4Network (<ip4adr>, <netmask>) : boolean //since 4.12.1 see also : isValidIP4Network

isValidIP4Host (<ip4adr>, <netmask>) : boolean //since 4.12.1 see also : isValidIP4Host

getIP4NetworkByAdrAndMask (<ip4adr>, <netmask>) : string //since 4.12.1 see also : getIP4NetworkByAdrAndMask

getDefaultNetmaskByIP4adr (<ip4adr>) : string //since 4.12.1 see also : getDefaultNetmaskByIP4adr

parseUrl(<url string>) : stringlist //since 4.12.1 see also : parseUrl

createUrl(<urlcomponents list>) : string //since 4.12.1 see also : createUrl

isPingReachable(<host>) : boolean //since 4.12.3.6 see also : isPingReachable

isValidFQDN(<domain name>) : boolean //since 4.12.4.4 [W/L/M] see also : isValidFQDN

cidrToNetmask (<string>) : string //since 4.12.4.37 see also : [cidrToNetmask]

netmaskToCidr (<string>) : string //since 4.12.4.37 see also : [netmaskToCidr]

isCertInstalledInSystem(<label>`) : boolstring` [W/L/M] //since 4.12.4.37 see also : [isCertInstalledInSystem]

importCertToSystem(<filename>`) : noresult` [W/L/M] //since 4.12.4.37 see also : [importCertToSystem]

removeCertFromSystem(<label>`) : noresult` [W/L/M] //since 4.12.4.37 see also : [removeCertFromSystem]

listCertificatesFromSystem(<label>`) : stringlist` [W/L/M] //since 4.12.4.37 see also : [listCertificatesFromSystem]

3.4.14. Number related functions [W/L/M]

isNumber(<str>`) : bool` //since 4.11.3: true if <str> represents an integer [W/L/M] see also : isNumber

CompareDotSeparatedNumbers(<str1>,<relation str>,<str2>`) : bool` //since 4.11.5.2: [W/L/M] see also : CompareDotSeparatedNumbers_bool

CompareDotSeparatedNumbers(<string1>, <string2>`) : string` [W/L/M] see also : CompareDotSeparatedNumbers_str

calculate(<arithmetic string expression>`) : string (number)` // since 4.11.3.5 [W/L/M]
knows: +-*/() see also : calculate

DecStrToHexStr ( <decstring>, <hexlength>`) : string` [W/L/M] see also : DecStrToHexStr

HexStrToDecStr (<hexstring>`) : string` [W/L/M] see also : HexStrToDecStr

RandomIntStr(<number str>`) : string` [W/L/M] see also : RandomIntStr

3.4.15. Operating System related functions [W/L/M]

GetOS : string // 'Linux' or 'Windows_NT' or 'macos' [W/L/M] see also : GetOS

GetMsVersionInfo : string //Windows Version Information [W] see also : GetMsVersionInfo

GetMSVersionMap : stringlist [W] see also : GetMSVersionMap

getLinuxDistroType : string // 'debian' or 'redhat' or 'suse' (see getLinuxVersionMap) [L] see also : getLinuxDistroType

getLinuxVersionMap : stringlist //since 4.11.4 [L] see also : getLinuxVersionMap

getMacosVersionInfo : string //macOS Version Information //since 4.12.1.0 [M] see also : getMacosVersionInfo

getMacosVersionMap : stringlist //macOS Version map //since 4.12.1.0 [M] see also : getMacosVersionMap

GetSystemType : string //OS Architecture ("64 Bit System" or "x86 System") [W/L/M] see also : GetSystemType

getOSArchitecture // OS Architecture (x86_32 / x86_64/ arm_64) //since 4.12.4.17 [W/L/M]
see also : getOSArchitecture

getListFromWMI(<wmi namespace str>,<wmi class str>,<property list>,<condition str>`) : stringlist` //since 4.12.1.0 [W] see also : opsi-wmi-test.exe (small helper application works like getListFromWMI)

EnvVar (<environment variable>`) : string` [W/L/M] see also : EnvVar

getProfilesDirList : stringlist //since 4.11.3.2 [W/L/M] see also : getProfilesDirList

listFiles (<Path>, <Searchmask> , <SearchSubDirectories>, <[Redirection]>`) : stringlist` //since 4.12.3 [W/L/M]

Set $Filelist$ = listFiles("C:\windows\system32","*.ico;*.dll","False","64bit")

see also : listFiles

which(<command in path>`) : string` (command with path) //since 4.12.3.6 [W/L/M] see also : which

runningAsAdmin : bool //since 4.11.1.1 [W/L/M] see also : runningAsAdmin

runningOnUefi : bool` //since 4.11.4.3: true: if the running OS was booted in UEFI mode [W/L/M] see also : runningOnUefi

runningInPE : bool` //since 4.12.0.13: true: if the running OS is a Windows PE [W] see also : runningInPE

runningInWAnMode //since 4.12.4.16: true: if opsiserver = localhost [W/L/M] see also : runningInWAnMode

isDriveReady(<drive letter>`) : bool`` //since 4.11.4.4: true: if the drive can be accessed [W] see also : isDriveReady

runningWithGui : bool` //since 4.12.3.6: true: if the running OS with GUI (at Win+Mac always true)[M/L/W] see also : runningWithGui

3.4.16. opsiservicecall and json Related functions [W/L/M]

jsonIsValid(<jsonstr>`) : boolean` //since 4.11.6: [W/L/M] see also : jsonIsValid

jsonIsArray(<jsonstr>`) : boolean` //since 4.11.6: [W/L/M] see also : jsonIsArray

jsonIsObject(<jsonstr>`) : boolean` //since 4.11.6: [W/L/M] see also : jsonIsObject

jsonAsObjectHasKey(<jsonstr>,<keystr>`) : boolean` //since 4.11.6: [W/L/M] see also : jsonAsObjectHasKey

jsonAsArrayCountElements(<jsonstr>`) : intstr` //since 4.11.6: [W/L/M] see also : jsonAsArrayCountElements

jsonAsObjectCountElements(<jsonstr>`) : intstr` //since 4.11.6: [W/L/M] see also : jsonAsObjectCountElements

jsonAsArrayGetElementByIndex(<jsonstr>, <indexstr>`) : jsonstring` //since 4.11.6: [W/L/M] see also : jsonAsArrayGetElementByIndex

jsonAsObjectGetValueByKey(<jsonstr>, <keystr>`) : valuestring` //since 4.11.6: [W/L/M] see also : jsonAsObjectGetValueByKey

jsonAsObjectSetValueByKey(<jsonstr>, <keystr>,<valuestring>`) : jsonstring` //since 4.11.6: [W/L/M] see also : jsonAsObjectSetValueByKey

jsonAsObjectSetStringtypeValueByKey(<jsonstr>, <keystr>,<valuestring>`) : jsonstring` //since 4.11.6: [W/L/M] see also : jsonAsObjectSetStringtypeValueByKey

jsonAsObjectDeleteByKey(<jsonstr>, <keystr>`) : jsonstring` //since 4.11.6.4: [W/L/M] see also : jsonAsObjectDeleteByKey

jsonAsArrayPutObjectByIndex(<jsonstr>, <indexstr>, <objectstr>`) : jsonstring` //since 4.11.6: [W/L/M] see also : jsonAsArrayPutObjectByIndex

jsonAsArrayDeleteObjectByIndex(<jsonstr>, <indexstr>`) : jsonstring` //since 4.11.6.4: [W/L/M] see also : jsonAsArrayDeleteObjectByIndex

jsonAsArrayToStringList(<jsonstr>`) : stringlist` //since 4.11.6: [W/L/M] see also : jsonAsArrayToStringList

jsonAsObjectGetKeyList(<jsonstr>`) : stringlist` //since 4.11.6: [W/L/M] see also : jsonIsArray

jsonStringListToJsonArray(<strlist>`) : jsonstr` //since 4.11.6: [W/L/M] see also : jsonAsObjectGetKeyList

convert2Jsonstr(<string>`)` //since 4.10.8.3

see also: OpsiServiceCall Abschnitt 3.3.9

3.4.17. opsi related functions [W/L/M]

getProductMap : stringlist // since 4.11.2.4 [W/L/M]
keys are: id, name, description, advice, productversion, packageversion, priority, installationstate, lastactionrequest, lastactionresult, installedversion, installedpackage, installedmodificationtime,actionrequest see also : getProductMap

getProductPropertyList(<propname>,<default value>`) : stringlist` //since 4.11.3 [W/L/M] see also : getProductPropertyList

GetProductProperty (<PropertyName>, <DefaultValue> ) : string [W/L/M] see also : GetProductProperty

GetConfidentialProductProperty ( <PropertyName>, <DefaultValue>`) : string` //since 4.11.5.2 [W/L/M] see also : GetConfidentialProductProperty

setActionProgress <string> : noresult //since 4.11.3 [W/L/M] see also : setActionProgress

retrieveSection (<section name>`) : stringlist` [W/L/M] see also : retrieveSection

replaceOpsiConstants(<string list>`) : stringlist` //since 4.12.3.6 [W/L/M] see also : replaceOpsiConstants_list

replaceOpsiConstants(<string>`) : string` //since 4.12.3.6 [W/L/M] see also : replaceOpsiConstants_string

runningInWanMode : boolean //since 4.12.4.17 [W/L/M] see also : runningInWanMode

reloadProductList //since 4.12.6.1 [W/L/M] see also : reloadProductList

3.4.18. Process and Script Related functions

Killtask <process name> ` : noresult` [W/L/M] see also : Killtask

ChangeDirectory <directory> ` : noresult` //since 4.11.2.6 [W/L/M] see also : ChangeDirectory

GetProcessList : stringlist //since 4.11.1.2; gives list of exename;pid;dom/user [W/L/M] see also : GetProcessList

processIsRunning(<process name>`) : boolean` //since 4.11.6.1 [W/L/M] see also : processIsRunning

isProcessChildOf(<searchprocstr>, <parentprocstr>): bool //since 4.12.4.35 [W/L/M]
see also : [isProcessChildOf]

shellCall (<command string>`) : stringlist (output)` //since 4.11.4.2 [W/L/M] see also : shellCall_list

set $list$= shellCall('net start')

shellCall (<command string>`) : noresult` //since 4.11.6.1 [W/L/M] see also : shellCall

shellCall (<command string>`) : string (exitcode)` //since 4.11.6.1 [W/L/M] see also : shellCall_str

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]
see also : powershellCall_list

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]
see also : powershellCall

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]
see also : powershellCall_str

getOutStreamFromSection (<dos section name>`) : stringlist (output)` [W/L/M]

set $list$= getOutStreamFromSection ('DosInAnIcon_try')

processCall(<string>`) : string (exitcode)` //since 4.11.6.1 [W/L/M] see also : processCall

getLastExitCode : string (exitcode) [W/L/M] see also : getLastExitCode

includelog <file name> <tail size> : noresult //since 4.11.2.1 [W/L/M] see also : includelog

includelog <file name> <tail size> [<encoding>] : noresult //since 4.11.4.1 [W/L/M] see also : includelog

waitForPackageLock(<seconds timeout string>,<bool should we kill>`) : bool` //since 4.11.6.1 [L] see also : waitForPackageLock

which(<command in path>`) : string` (command with path) //since 4.12.3.6 [W/L/M] see also : which

executeSection(<string expr with section call>`)` //since 4.12.3.9 [W/L/M] see also : executeSection

see also: ExecWith sections Abschnitt 3.3.3

see also: ShellBatch sections Abschnitt 3.3.2

see also: Winbatch sections Abschnitt 3.3.1

3.4.19. Regular expression related functions [W/L/M]:

isRegexMatch(<string>, <pattern>) : boolean //since 4.12.1 see also : isRegexMatch

getSubListByContainingRegex(<pattern>, <target list>) : stringlist //since 4.12.1 see also : getSubListByContainingRegex

getSubListByContainingRegex(<pattern list>, <target list>) : stringlist //since 4.12.1 see also : getSubListByContainingRegex

getRegexMatchList(<pattern>, <target list>) : stringlist //since 4.12.1 see also : getRegexMatchList

getRegexMatchList(<pattern list>, <target list>) : stringlist //since 4.12.1 see also : getRegexMatchList

removeFromListByContainingRegex(<pattern>, <target list>) : stringlist //since 4.12.1 see also : removeFromListByContainingRegex

removeFromListByContainingRegex(<pattern list>, <target list>) : stringlist //since 4.12.1 see also : removeFromListByContainingRegex

stringReplaceRegex(<string>, <pattern>, <replacement string>) : string //since 4.12.1 see also : stringReplaceRegex

stringReplaceRegexInList(<target list>, <pattern>, <replacement string>) : stringlist //since 4.12.1 see also : stringReplaceRegexInList

3.4.20. Registry related functions [W]

getRegistryValue(<keystr>, <varstr> ) : string //since 4.12.0.16 [W]
<access str> = one of 32bit, 64bit, sysnative ; default sysnative see also : getRegistryValue

GetRegistrystringvalue(`"[key] var") : string` [W] see also : GetRegistrystringvalue

GetRegistryStringValue32 (`"[key] var") : string` //since 4.10.8 [W] see also : GetRegistryStringValue32

GetRegistryStringValue64 (`"[key] var") : string` //since 4.10.8 [W] see also : GetRegistryStringValue64

GetRegistryStringValueSysNative (`"[key] var") : string` //since 4.10.8 [W] see also : GetRegistryStringValueSysNative

getRegistryKeyList32(<regkey>`) : stringlist` //since 4.11.3 [W] see also : getRegistryKeyList32

getRegistryKeyList64(<regkey>`) : stringlist` //since 4.11.3 [W] see also : getRegistryKeyList64

getRegistryKeyListSysnative(<regkey>`) : stringlist` //since 4.11.3 [W] see also : getRegistryKeyListSysnative

getRegistryKeyList(<regkey>, <access str>`) : stringlist` //since 4.12.5.0 [W] see also : getRegistryKeyList

getRegistryVarList32(<regkey>`) : stringlist` //since 4.11.3 [W] see also : getRegistryVarList32

getRegistryVarList64(<regkey>`) : stringlist` //since 4.11.3 [W] see also : getRegistryVarList64

getRegistryVarListSysnative(<regkey>`) : stringlist` //since 4.11.3 [W] see also : getRegistryVarListSysnative

getRegistryVarList(<regkey>, <access str>`) : stringlist` //since 4.12.5.0 [W] see also : getRegistryVarList

getRegistryVarMap32(<regkey>`) : stringlist` //since 4.11.3 [W] see also : getRegistryVarMap32

getRegistryVarMap64(<regkey>`) : stringlist` //since 4.11.3 [W] see also : getRegistryVarMap64

getRegistryVarMapSysnative(<regkey>`) : stringlist` //since 4.11.3 [W] see also : getRegistryVarMapSysnative

getRegistryVarMap(<regkey>, <access str>`) : stringlist` //since 4.12.5.0 [W] see also : getRegistryVarMap

RegKeyExists(<regkey>[,<access str>]) : bool //since 4.12.0.16 [W]
<access str> = one of 32bit, 64bit, sysnative ; default sysnative see also : RegKeyExists

RegVarExists(<regkey>, <var str> ) : bool //since 4.12.0.16 [W]
<access str> = one of 32bit, 64bit, sysnative ; default sysnative see also : RegVarExists

see also: Abschnitt 3.3.5

see also : Registry-Sections

see also : 64 bit

3.4.21. String handling functions [W/L/M]

see also : string

splitString (<string1>, <string2>`) : stringlist` [W/L/M] see also : splitString

set $list1$ = splitString ("\\server\share\dir","\")

splitStringOnWhiteSpace (<string>`) : stringlist` [W/L/M] see also : splitStringOnWhiteSpace

composeString (<string list>, <Link>`) : string` [W/L/M] see also : composeString

takeString (<index>, <list>`) : string` [W/L/M] see also : takeString

setStringInListAtIndex(<newstring>,<list>,<indexstr>`) : stringlist` //since 4.11.6 [W/L/M] see also : setStringInListAtIndex

takeFirstStringContaining(<list>,<search string>`) : string` [W/L/M] see also : takeFirstStringContaining

getIndexFromListByContaining(<list> : stringlist,<search string> : string`)` : <number> : string //since 4.12.0.13 [W/L/M] see also : getIndexFromListByContaining

contains(<str>, <substr>`) : bool` //since 4.11.3: true if <substr> in <str> [W/L/M] see also : contains

isNumber(<str>`) : bool` //since 4.11.3: true if <str> represents an integer [W/L/M] see also : isNumber

trim(<string>`) : string` [W/L/M] see also : trim

lower(<string>`) : string` [W/L/M] see also : lower

upper(<string>`)` [W/L/M] see also : upper

unquote(<string>,<quote-string>`) : string` //since 4.11.2.1 [W/L/M] see also : unquote

unquote2(<string>,<quote-string>`) : string` //since 4.11.5.2 [W/L/M] see also : unquote2

stringReplace(<string>, <oldPattern>, <newPattern>`) : string` //since 4.11.3 [W/L/M] see also : stringReplace

strLength(<string>`) : string (number)` //since 4.11.3 [W/L/M] see also : strLength

strPos(<string>, <sub string>`) : string (numner)` //since 4.11.3 [W/L/M] see also : strPos

strPart(<string>, <start pos>, <number of chars>`) : string` //since 4.11.3 [W/L/M] see also : strPart

getValue(<key string>, <hash string list> ) : string [W/L/M] see also : getValue

getValueBySeparator(<key string>,<separator string>,<hash string list> ) : string //since 4.11.2.1 [W/L/M] see also : getValueBySeparator

getValueFromFile(<key string>, <file name>`) : string` //since 4.11.4.4 [W/L/M] see also : getValueFromFile

getValueFromFileBySeparator(<key string>,<separator string>,<file name>`) : string` //since 4.11.4.4 [W/L/M] see also : getValueFromFileBySeparator

EscapeString: <sequence of characters> : string// [W/L/M] see also : EscapeString

stringReplaceRegex(<string>, <pattern>, <replacement string>) : string //since 4.12.1 [W/L/M] see also : stringReplaceRegex

stringinput(< message str>,< boolstr confidential>`) : string` //since 4.12.1.2 [W/L/M] see also : stringinput

3.4.22. Stringlist handling functions [W/L/M]

see also : stringlist

getListContaining(<list>,<search string>`) : stringlist` [W/L/M] see also : getListContaining

getListContainingList(<list1>,<list2>`) : stringlist` //since 4.11.3.7 [W/L/M] see also : getListContainingList

getIndexFromListByContaining(<list> : stringlist,<search string> : string`)` : <number> : string //since 4.12.0.13 [W/L/M] see also : getIndexFromListByContaining

count (<list>`) : string (number)` [W/L/M] see also : count

emptylist (<list>`) : stringlist` //since 4.11.3.7 [W/L/M] see also : emptylist

for %<identifier>`% in` <list> do <one statement | sub section> [W/L/M]

for %s% in $list1$ do sub_test_string

createStringList (<string0>, <string1> ,…​ ) : stringlist [W/L/M]

set $list1$ = createStringList ('a','b')

see also : createStringList

reverse (<list>`) : stringlist` [W/L/M] see also : reverse

getSubList (<start index> : <end index>, <list>`) : stringlist` [W/L/M] see also : getSubList

getSubListByMatch (<search string>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByMatch_sl

getSubListByMatch (<search list>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByMatch_ll

getSubListByContaining ( <search string>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByContaining_sl

getSubListByContaining (<search list>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByContaining_ll

getSubListByKey (<search string>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByKey_sl

getSubListByKey (<search list>, <target list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getSubListByKey_ll

getKeyList (<list>`)` :stringlist //since 4.12.0.14 [W/L/M] see also : getKeyList

addtolist(<list>,<string>`) : stringlist` //since 4.10.8 [W/L/M] see also : addtolist

addListToList(<dest list>,<src list>`) : stringlist` //since 4.10.8 [W/L/M] see also : addListToList

reencodestrlist(<list>, <from>, <to>`) : stringlist` //since 4.11.4.2 [W/L/M] see also : reencodestrlist

removeFromListByContaining(<search string>`,` <target list>`) : stringlist` //since 4.11.5.1 [W/L/M] see also : removeFromListByContaining_str

removeFromListByContaining(<search list>`,` <target list>`) : stringlist` //since 4.11.5.1 [W/L/M] see also : removeFromListByContaining_list

removeFromListByMatch(<searchstring>,<target list>`) : stringlist` //since 4.11.6 [W/L/M] see also : removeFromListByMatch

takeString (<index>, <list>`) : string` [W/L/M] see also : takeString

takeFirstStringContaining(<list>,<search string>`) : string` [W/L/M] see also : takeFirstStringContaining

setStringInListAtIndex(<newstring>,<list>,<indexstr>`) : stringlist` //since 4.11.6 [W/L/M] see also : setStringInListAtIndex

jsonAsArrayToStringList(<jsonstr>`) : stringlist` //since 4.11.6: [W/L/M] see also : jsonAsArrayToStringList

jsonStringListToJsonArray(<strlist>`) : jsonstr` //since 4.11.6: [W/L/M] see also : jsonStringListToJsonArray

jsonAsObjectGetKeyList(<jsonstr>`) : stringlist` //since 4.11.6: [W/L/M] see also : jsonAsObjectGetKeyList

splitString(<string1>, <string2>`)` : stringlist [W/L/M]

set $list1$ = splitString ("\\server\share\dir","\")

see also : splitString

splitStringOnWhiteSpace (<string>`) : stringlist` [W/L/M] see also : splitStringOnWhiteSpace

composeString(<string list>, <Link>`) : string` [W/L/M] see also : composeString

getValue(<key string>, <hash string list> ) : string [W/L/M] see also : getValue

getValueBySeparator(<key string>,<separator string>,<hash string list> ) : string //since 4.11.2.1 [W/L/M] see also : getValueBySeparator

setValueByKey(<key>, <value>, <targetlist> ) : stringlist [W/L/M] see also : [setValueByKey]

getSubListByContainingRegex(<pattern>, <target list>) : stringlist //since 4.12.1 see also : getSubListByContainingRegex

getSubListByContainingRegex(<pattern list>, <target list>) : stringlist //since 4.12.1 see also : getSubListByContainingRegex

getRegexMatchList(<pattern>, <target list>) : stringlist //since 4.12.1 see also : getRegexMatchList

getRegexMatchList(<pattern list>, <target list>) : stringlist //since 4.12.1 see also : getRegexMatchList

removeFromListByContainingRegex(<pattern>, <target list>) : stringlist //since 4.12.1 see also : removeFromListByContainingRegex

removeFromListByContainingRegex(<pattern list>, <target list>) : stringlist //since 4.12.1 see also : removeFromListByContainingRegex

stringReplaceRegexInList(<target list>, <pattern>, <replacement string>) : stringlist //since 4.12.1 see also : stringReplaceRegexInList

editmap(< strlist>`) : stringlist` //since 4.12.1.2 [W/L/M] see also : editmap

areListsEqual(< strlist1>, <strlist2>, <flag>`) : boolean` see also : areListsEqual

GetSectionFromInifile(<ini-file>`) : stringlist` [W/L/M] see also : GetSectionFromInifile

3.4.23. Time / Date related functions [W/L/M]

sleepSeconds <Integer> or <string> : noresult [W/L/M]
breaks the program execution for <string> seconds. <string> has to represent an Integer Value
see also : sleepSeconds

markTime : noresult [W/L/M]
sets a time stamp for the current system time and logs it. see also : markTime

getDiffTimeSec : string (Time in seconds since last marktime) //since 4.11.3 [W/L/M] see also : getDiffTimeSec

timeStampAsFloatStr : string (Floating Number - format: 'days.decimal days') //since 4.11.6 [W/L/M] see also : timeStampAsFloatStr

3.4.24. Usercontext / loginscripts related functions [W]:

GetUserSID(<Windows Username>`) : string` see also : GetUserSID

GetLoggedInUser : string //since 4.11.1.2 see also : GetLoggedInUser

GetUsercontext : string //since 4.11.1.2 see also : GetUsercontext

GetScriptMode : string possible values 'Machine','Login' //since 4.11.2.1 see also : GetScriptMode

saveVersionToProfile : noresult - save productversion-packageversion to local profile //since 4.11.2.1 see also : saveVersionToProfile

readVersionFromProfile : string - read productversion-packageversion from local profile //since 4.11.2.1 see also : readVersionFromProfile

scriptWasExecutedBefore : boolean - is true if saved and running productversion-packageversion are identical //since 4.11.2.1 see also : scriptWasExecutedBefore

3.4.25. XML related functions (XML2) [W/L/M]:

getXml2DocumentFromFile(<path to xml file>`) : xml2stringlist` //since 4.12.1 see also : getXml2DocumentFromFile

getXml2Document(<stringlist wit xml>`) : xml2stringlist` //since 4.12.1 see also : getXml2DocumentFromFile

xml2GetFirstChildNodeByName(<xml2stringlist>, <node name str>`) : xml2stringlist` //since 4.12.1. see also : xml2GetFirstChildNodeByName

getXml2UniqueChildnodeByName(<xml2stringlist>, <node name str>`) : xml2stringlist` //since 4.12.1. see also : getXml2UniqueChildnodeByName

getXml2AttributeValueByKey(<xml2stringlist>, <attr name str>`) : string` //since 4.12.1. see also : getXml2AttributeValueByKey

getXml2Text(<xml2stringlist>`) : string` //since 4.12.1. see also : getXml2Text

see also : Abschnitt 3.3.11

see also : XML2 Section

3.4.26. TOML files related functions [W/L/M]:

LoadTOMLFile(<TOMLfilePath: String>`) : StringList` //since 4.12.5 see also : LoadTOMLFile

ReadTOMLFile(<TOMLfilePath: String>`) : String` //since 4.12.5 see also : ReadTOMLFile

GetTOMLAsStringList(<TOMLcontents: String>`) : StringList` //since 4.12.5 see also : GetTOMLAsStringList

GetTOMLAsString(<TOMLcontents: String>`) : String` //since 4.12.5 see also : GetTOMLAsString

GetTOMLKeys(<TOMLcontents: String>`) : StringList` //since 4.12.5 see also : GetTOMLKeys

GetTOMLTableNames(<TOMLcontents: String>`) : StringList` //since 4.12.5 see also : GetTOMLTableNames

GetTOMLTable(<TOMLcontents: String> , <table name : String>`) : StringList` //since 4.12.5 see also : GetTOMLTable

GetTOMLTableAsString(<TOMLcontents: String> , <table name : String>`) : String` //since 4.12.5 see also : GetTOMLTableAsString

GetValueFromTOML(<TOMLcontents: String> , <keyPath: String> , <defaultValue: String>`) : String` //since 4.12.5 see also : GetValueFromTOML

ModifyTOML(<TOMLcontents: String> , <command: String> , <keyPath: String> , <value: String>`) : String` //since 4.12.5 see also : ModifyTOML

DeleteTableFromTOML(<TOMLcontents: String> , <tablePath: String>`) : String` //since 4.12.5 see also : DeleteTableFromTOML

SaveToTOMLFile(<TOMLcontents: String> , <TOML file Path: String>`) : boolean` //since 4.12.5 see also : SaveToTOMLFile

ConvertTOMLtoJSON(<TOMLcontents: String>`) : String` //since 4.12.5 see also : ConvertTOMLtoJSON

ConvertTOMLfileToJSONfile(<TOMLfilePath: String> , <JSONfilePath: String>`) : boolean` //since 4.12.5
see also : ConvertTOMLfileToJSONfile

4. Betrieb von opsi-script unter Linux oder macOS

Seit Version 4.11.4 steht 'opsi-script' auch unter Linux zur Verfügung.

Seit Version 4.12.1 steht 'opsi-script' auch unter macOS zur Verfügung.

Bedingt durch den Fortgang der Portierung und durch die Unterschiede der Betriebssysteme stehen bestimmte Funktionalitäten nicht unter allen Betriebssystemen zur Verfügung. Im folgenden sind entsprechende Abschnitte markiert:

  • [W/L/M] sowohl unter Windows, Linux als auch unter macOS verfügbar

  • [W] nur unter Windows verfügbar

  • [L] nur unter Linux verfügbar

  • [M] nur unter macOS verfügbar

4.1. Wichtige Unterschiede und Hinweise

'opsi-script.exe' ist unter Windows ein GUI Programm, welches über den Parameter /silent auch ohne GUI gestartet werden kann.

'opsi-script' unter Linux und macOS ist ein Kommandozeilen Programm, welches auch ohne Zugriff auf ein Display gestartet werden kann. Es prüft aber automatisch ob der Zugriff auf ein grafisches Display möglich ist und startet wenn möglich die grafische Variante 'opsi-script-gui'. Dies kann über den Parameter -silent unterdrückt werden.

'opsi-script-gui' ist eine GUI Version, welche sich auch nicht ohne grafisches Display starten lässt.

Unter Linux und macOS ist das Parameterzeichen nicht "/" sondern "-". Also statt unter Windows opsi-script /help hier opsi-script -help.

4.2. Pfade unter Linux

Unter Linux sind die unterschiedlichen Komponenten gemäß des Linux Filesystem Hierachie Standard nicht an einer Stelle zu finden. Daher hier ein Überblick:

Seit opsi-client-agent 4.2 liegen all Komponenten von opsi-script unter /opt/opsi-script/.

Vor opsi-client-agent 4.2: * Ausführbare Programme:
/usr/bin/opsi-script
/usr/bin/opsi-script-nogui

  • Language files:
    /usr/share/locale

  • Skin files:
    Default = /usr/share/opsi-script/skin
    Custom = /usr/share/opsi-script/customskin

  • opsi-script library files:
    /usr/share/opsi-script/lib

Unabhängig von der Version gilt:

  • Verzeichnisse für Logdateien:
    Ausgeführt als root: /var/log/opsi-script
    Ausgeführt als user: /tmp

  • Config files:
    /etc/opsi-script

4.3. Pfade unter macOS

Unter macOS liegen all Komponenten von opsi-script unter /Applications/opsi-script/.

  • Verzeichnisse für Logdateien:
    Ausgeführt als root: /var/log/opsi-script
    Ausgeführt als user: /tmp

  • Config files:
    /etc/opsi-script

4.4. Verwendung von Pfaden in opsiscript

Seit Version 4.11.4 wird bei allen Funktionen welche einen Pfad erwarten, intern eine Funktion aufgerufen welchen den übergebenen String in einen für das Betriebssystem gültigen Pfad wandeln. Es werden also alle Pfadtrennzeichen korrekt gesetzt. So wird z.B. aus dem Pfad /home/opsiproduct\myproduct\CLIENT_DATA unter Linux /home/opsiproduct/myproduct/CLIENT_DATA. Dies bedeutet auch, dass unter Linux keine Dateien angelegt oder verarbeitet werden können welche einen Backslash im Namen haben.

4.5. Linuxspezifische Funktionen

Zur Unterstützung von Linux gibt es folgende Linuxspezifische Funktionen:

In den folgenden Kapiteln werden spezielle opsi Linux Befehle zur Installation von Software vorgestellt, welche aus der opsi-script Library uib_lin_install stammen. Diese Dokumentation ist in Englisch, da sie direkt aus dem Quellcode automatisch generiert wurde.

Zum Verständnis zunächst ein Überblick über die unterschiedlichen Ansätze der Methoden:

  • Distributionsunabhängige Methoden:

    • cleanupPackageSystem

    • installupdates

  • Installation von einem oder mehreren Paketen aus online Repos für eine spezifische Distribution
    Soll nur ein Paket installiert werden, so ist in dem Aufrufen statt $packagelist$, zu verwenden: createStringList(<package name>)
    Die Paketnamen in der Liste müssen zur Distribution / Version passen.

    • debinstall($packagelist$ : stringlist) : string //since 4.12.4 [L]

    • redinstall($packagelist$ : stringlist) : string //since 4.12.4 [L]

    • suseinstall($packagelist$ : stringlist) : string //since 4.12.4 [L]

    • ucsinstall($packagelist$ : stringlist) : string //since 4.12.4 [L]

  • Installation / Deinstallation von einem oder mehren Paketen für eine bekannte Distribution / Version (d.h. Paketnamen müssen passen).
    Der notwendige Befehl wird anhand der Distribution ermittelt.

    • genericLinInstall($packagelist$ : stringlist) : string

    • linuxRemoveOnePackage($packagename$ : string) : string

    • linuxInstallOneFile($packagefile$ : string) : string

  • Installation / check / deinstallation von einem Paket aus online Repos für unterschiedliche Distributionen / Versionen, weswegen das Paket auch unterschiedliche Namen haben kann.
    D.h. es wird davon ausgegangen, das die Paketnamen in der Liste alles pseudonyme für das selbe Paket sind aber für unterschiedliche Versionen bzw. Distributionen. Der notwendige Befehl wird anhand der Distribution ermittelt.

    • linuxInstallOneOf($packagelist$ : stringlist) : string

    • isOneInstalled($packagelist$ : stringlist) : string

    • linuxRemoveOneOf($packagelist$ : stringlist) : string

Die Details zu den genannten Befehlen der Library finden sich hier: Documentation of opsi library: uib_lin_install.opsiscript

Verweise auf diese und weitere Linux-spezifische Bibliotheks Funktionen finden Sie hier: Linux specific functions

4.6. Beispiel Scripte für Linux

4.6.1. Nur unter Linux ausführen

[Actions]
DefVar $OS$

set $OS$ = GetOS

if not ($OS$ = "Linux")
	logError "Installation aborted: wrong OS version: only Linux allowed"
	isFatalError "wrong OS"
endif

4.6.2. Welche Linux Version

[Actions]
DefVar $distCodeName$
DefVar $distroName$
DefVar $distRelease$
DefVar $distrotype$


DefStringList $linuxInfo$

set $distrotype$ = getLinuxDistroType
set $linuxInfo$ = getLinuxVersionMap
set $distCodeName$ = getValue("Codename", $linuxInfo$)
set $distRelease$ = getValue("Release", $linuxInfo$)
set $distroName$  = getValue("Distributor ID", $linuxInfo$)
Tabelle 1. getLinuxVersionMap Result Examples
Distro Distributor ID Release Codename Description

Ubuntu Focal

Ubuntu

20.04

focal

Debian 8

Debian

8.3

jessie

Debian GNU/Linux 8.3 (jessie)

openSUSE Leap 42.1

SUSE LINUX

42.1

n/a

openSUSE Leap 42.1 (x86_64)

SLES12SP1

SUSE LINUX

12.1

n/a

SUSE Linux Enterprise Server 12 SP1

CentOS 7.0

CentOS

7.0.1406

Core

CentOS Linux release 7.0.1406 (Core)

RedHat 7.0

RedHatEnterpriseServer

7.0

Maipo

Red Hat Enterprise Linux Server release 7.0 (Maipo)

UCS 4.1

Univention

4.1-1 errata122

Vahr

Univention Corporate Server 4.1-1 errata122 (Vahr)

4.6.3. ShellInAnIcon Aufruf

[Actions]

ShellInAnIcon_ls

[ShellInAnIcon_ls]
set -x
ls
exit $?

Es ist oft hilfreich mit set -x anzufangen, damit der Skriptablauf in der Logdatei erkennbar ist. Die letzte Zeile sollte exit $? sein, damit zumindest der letzte exitcode der Sektion übergeben wird.

4.6.4. Hinzufügen eines Linux Paket Repositories

Listing 1. Ubuntu / Debian
[Actions]
DefVar $newrepo$

set $newrepo$ = "deb http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/Debian_7.0/ ./"

comment "Method 1: use add-apt-repository ..."
ShellInAnIcon_add_rep_deb
ShellInAnIcon_add_repokey_deb
comment "Method 2: use add-apt-repository ..."
PatchTextFile_add_repo_deb "/etc/apt/sources.list"
ShellInAnIcon_add_repokey_deb

[ShellInAnIcon_add_rep_deb]
set -x
export export DEBIAN_FRONTEND=noninteractive
apt-get --yes --force-yes install software-properties-common
apt-get --yes --force-yes install python-software-properties
add-apt-repository '$newrepo$'
exit $?

[PatchTextFile_add_repo_deb]
FindLine_StartingWith "$newrepo$"
DeleteTheLine
GoToBottom
InsertLine "$newrepo$"

[ShellInAnIcon_add_repokey_deb]
set -x
export wget --no-check-certificate -O - $newrepo$/Release.key | apt-key add -
apt-get update
exit $?
Listing 2. SUSE
[Actions]
DefVar $newrepo$

set $newrepo$ = "http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/openSUSE_13.1/home:uibmz:opsi:opsi40.repo"

ShellInAnIcon_add_opsi_repository_suse

[ShellInAnIcon_add_opsi_repository_suse]
set -x
export zypper --no-gpg-checks --non-interactive --gpg-auto-import-keys ar --refresh $newrepo$
zypper --no-gpg-checks --non-interactive --gpg-auto-import-keys refresh
exit $?
Listing 3. CentOS / Redhat
[Actions]
DefVar $newrepo$

set $newrepo$ = "http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/CentOS_7/home:uibmz:opsi:opsi40.repo"

comment "Method 1: use wget ..."
ShellInAnIcon_add_repo_redhat
ShellInAnIcon_refresh_repo_redhat
comment "Method 2: use PatchTextFile ..."
PatchTextFile_add_repo_redhat "/etc/yum.repos.d/mynew.repo"
ShellInAnIcon_refresh_repo_redhat

ShellInAnIcon_add_repo_redhat

[ShellInAnIcon_add_repo_redhat]
set -x
export yum -y install wget
cd /etc/yum.repos.d
wget --no-check-certificate $newrepo$
exit $?

[PatchTextFile_add_repo_redhat]
AppendLine "[home_uibmz_opsi_opsi40]"
AppendLine "name=opsi 4.0 (CentOS_7)"
AppendLine "type=rpm-md"
AppendLine "baseurl=http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/CentOS_7/"
AppendLine "gpgcheck=1"
AppendLine "gpgkey=http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/CentOS_7/repodata/repomd.xml.key"
AppendLine "enabled=1"

[ShellInAnIcon_refresh_repo_redhat]
set -x
yum makecache
yum -y repolist
exit $?

4.6.5. Löschen eines Repositories

Listing 4. Ubuntu / Debian
[Actions]
DefVar $delrepo$
DefStringlist = $resultlist$

set $delrepo$ = "deb http://download.opensuse.org/repositories/home:/uibmz:/opsi:/opsi40/Debian_7.0/ ./"

if LineBeginning_ExistsIn($delrepo$, "/etc/apt/sources.list")
	PatchTextFile_del_repo_deb  "/etc/apt/sources.list"
	set $resultlist$ = shellCall("apt-get update")
endif

[PatchTextFile_del_repo_deb]
FindLine_StartingWith "$delrepo$"
DeleteTheLine
Listing 5. SUSE
[Actions]
DefVar $delrepo$

comment "$delrepo$ is the section name of the repo file in /etc/zypp/repos.d/"
comment "$delrepo$ can be found by zypper lr"
set $delrepo$ = "home_uibmz_opsi_opsi40"
ShellInAnIcon_del_opsi_repository_suse

[ShellInAnIcon_del_opsi_repository_suse]
set -x
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
zypper --non-interactive rr  $delrepo$
exit $?
Listing 6. CentOS / Redhat
[Actions]
DefVar $delrepo$

comment "$delrepo$ ist the name of the repo file in /etc/yum.repos.d"
set $delrepo$ = "/etc/yum.repos.d/home:uibmz:opsi:opsi40.repo"

[ShellInAnIcon_del_opsi_repository_redhat]
set -x
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
rm $delrepo$
yum makecache
yum -y repolist
exit $?

4.6.6. Installieren eines Paketes

Generic for all supported distributions

A simple example:

[Actions]
importlib "uib_lin_install"

DefStringlist $packages$
DefVar $installresult$

comment "install new needed packages"
if waitForPackageLock("300", "false")
	comment "we got the package lock."
else
	LogError "could not get Package Lock"
endif

set $packages$ = CreateStringlist("lsb-release","cifs-utils","xterm")
set $installresult$ = genericLinInstall($packages$)
if not(stringtobool($installresult$))
	LogError "failed install packages"
	Message "failed install packages"
	isFatalError "failed dependent packages"
endif

A more sophisticated example:

[Actions]
importlib "uib_lin_install"

DefStringlist $packages$
DefVar $installresult$
DefStringlist $errorList$
DefVar $fatal_error$
DefVar $result_string$

if waitForPackageLock("300", "false")
	comment "we got the package lock."
else
	LogError "could not get Package Lock"
endif

comment "update and clean package system"
cleanupPackageSystem()

comment "install pending updates"
set $result_string$ = installupdates()

comment "install new needed packages"
set $packages$ = CreateStringlist("lsb-release","cifs-utils","xterm")
set $installresult$ = genericLinInstall($packages$)
if not(stringtobool($installresult$))
	if waitForPackageLock("300", "false")
		comment "we got the package lock."
	else
		LogError "could not get Package Lock"
	endif
	cleanupPackageSystem()
	set $installresult$ = genericLinInstall($packages$)
	if not(stringtobool($installresult$))
		LogError "failed install packages"
		Message "failed install packages"
		;isFatalError "failed install packages"
		set $fatal_error$ = "true"
		set $errorList$ = addtolist($errorList$, " failed install packages")
	endif
endif

4.7. macOS spezifische Funktionen

Für die Unterstützung von macOS gibt es die folgenden spezifischen Funktionen:

  • GetOS // 'Linux' or 'Windows_NT' or 'macOS' [W/L/M] GetOS

  • getMacosVersionInfo [M] getMacosVersionInfo

  • getMacosVersionMap [M] getMacosVersionMap

  • getOSArchitecture // 'x86_32' or 'x86_64' or 'arm_64' [W/L/M] OSArchitecture

  • chmod in Files sections [L/M] chmod

  • importlib "uib_macosinstalllib" :

  • install_macos_app($myapp$ : string) : string [M]

  • install_macos_pkg($mypkg$ : string) : string [M]

  • install_macos_dmg($mydmg$ : string) : string [M]

  • install_macos_zip($myzip$ : string) : string [M]

  • install_macos_generic($myfile$ : string) : string [M]

Die Details zu den genannten Befehlen der Library finden sich hier: Documentation of opsi library: uib_macosinstalllib.opsiscript

Verweise auf weitere macOS-spezifische Bibliotheks Funktionen finden Sie hier: macOS specific functions

4.8. Beispiel Scripte für macOS

4.8.1. Nur auf macOS ausführen

[Actions]
DefVar $OS$

set $OS$ = GetOS

if not ($OS$ = "macOS")
	logError "Installation aborted: wrong OS version: only macOS allowed"
	isFatalError "wrong OS"
endif

4.8.2. Welche macOS Version

Der code:

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

5. Start / Log / Exitcodes / Testsyntax

5.1. Kommandozeilen Parameter

Der 'opsi-script' enthält unter Windows seit Version 4.11.3 ein Manifest mit der Option:
<requestedExecutionLevel level="highestAvailable" />. Dies bedeutet, dass unter NT6 als Administrator aufgerufen, versucht wird als 'elevated' Prozess zu arbeiten. Wird der 'opsi-script' mit User Rechten aufgerufen, so läuft er unter den Rechten dieses Users.

Wird der 'opsi-script' ohne Parameter aufgerufen, so startet er interaktiv.

'opsi-script' kann ja nach Kontext und Verwendungszweck mit unterschiedlichen Parametern gestartet werden.

Es existieren eine Vielzahl von Optionen welche teilweise nur in Kombination und dann in der richtigen Reihenfolge verwendet werden können.

Note

Unter Linux or macOS ist das Parameterzeichen nicht "/" sondern "-". Also statt unter Windows opsi-script /help unter Linux / macOS opsi-script -help.

Allgemeine Optionen:

  • /? oder /h[elp]
    Hilfe aufrufen

  • /silent
    opsi-script ohne GUI ausführen

Ausführung eines (oder mehrerer) Skripts:
opsi-script <scriptfile>[;<scriptfile>]* [<logfile>]
Dabei ist:
<scriptfile> = Name der Scriptdatei inclusive Pfad
<logfile> = Name der Logdatei inclusive Pfad
Logpfade siehe auch: Abschnitt 5.2

  • /parameter <parameterstring>
    Einen String als (über die String-Funktion ParamStr) abfragbaren Parameter übergeben.
    Dabei ist <parameterstring> ein String der keine Leerzeichen enthält.

  • /logfile <logfile>
    Festlegen des Logfiles:
    Dabei ist:
    <logfile> = Name der Logdatei inclusive Pfad
    Logpfade siehe auch: Abschnitt 5.2

  • /lang <lang>
    Festlegen der Lokalisierung:
    Dabei ist:
    <lang> = Zwei Buchstaben Kurzbezeichnung der Sprache (de,en,fr,es,…​)

  • /batch
    Ausführen eines angegeben Skriptes mit Batchoberflache. Die Batch-Oberfläche bietet keine Möglichkeiten für Benutzereingaben.In Kombination mit der Option /silent wird auch die Batch-Oberfläche ausgeblendet. Beim Aufruf ohne den Parameter /batch erscheint die Dialog-Oberfläche. Mit ihr ist die interaktive Auswahl von Skript- und Protokolldatei möglich (in erster Linie für Testzwecke gedacht).

  • /testsyntax (seit 4.12.7.)
    Ausführen eines angegeben Skriptes im testsyntax-Modus. In der Regel in der Kombination mit der Option /batch.
    siehe auch: Abschnitt 5.4

  • /productid <productId>
    Verwendung zusammen mit /servicebatch ; siehe dort.

  • /servicebatch
    Ausführen eines angegeben Scriptes mit Batchoberflache und mit opsi-service Verbindung, so als würde das auch angegebene /productid auf 'setup' stehen.
    Dabei muß die Scriptdatei als erster Parameter angegeben sein.
    Dabei muß auch der Parameter /opsiservice und seine Zusatzparameter angegeben sein.
    Dabei muß auch der Parameter /productid angegeben sein. Dieser Parameter wird verwendet um in der Kommunikation mit dem opsi-Service das angegeben Script so auzuführen als wäre es das 'setup-script' des mit <productId> angegebenen opsi-produktes.

  • /logproductid <productId>
    Bei der Erstellung der Logdatei soll <productId> als Quelle des Logs angegeben werden.
    Wird z.B. verwendet bei Scripten welche mit einem temporären user arbeiten und in dessem Kontext Scripte als Teil des Produktes <productId> ausgeführen.

  • /normalwindow
    Schaltet im nicht interaktiven Modus die Maximierung der Batchoberfläche aus.

  • /usercontext <[ domain\]username >
    Wenn der angegebene user angemeldet ist, wird versucht die Ermittlung von Konstanten wie %CurrentAppdataDir%, %CurrentStartmenuDir%, %CurrentDesktopDir%, %CurrentStartupDir%, %CurrentProgramsDir%, %CurrentSendToDir%, %CurrentProfileDir% im Kontext dieses Users auszuführen. Meist verwendet im Zusammenhang mit der 'User Profile Management' Erweiterung.

  • /opsiservice <opsiserviceurl>
    /clientid <clientname>
    /username <username>
    /password <password>
    [/sessionid <sessionid>]
    [/credentialfile <credentialfile>]
    Angabe der Verbindungsdaten zum opsi-service:
    Dabei müssen entweder /clientid und /username und /password sowie optional die /sessionid angegeben werden
    oder diese Daten werden in einem /credentialfile zur Verfügung gestellt.

Beeinflussung was im Kontext des /opsiservice getan werden soll:

  • Default (keine weiteren der folgenden Parameter):
    Abarbeitung der Aktionsanforderungen welche für den client auf dem opsi-server gespeichert sind.

  • /allloginscripts oder /loginscripts
    Abarbeitung der Loginscripts der opsi-produkte. Dabei werden bei /allloginscripts alle dem opsi-server bekannten login-scripte ausgeführt und bei /loginscripts nur die Login-Scripte von Produkten welche auf dem Client installiert sind oder waren (es existiert für das Produkt ein productOnClient Objekt).

  • /productlist <productid>[,<productid>]*
    Bearbeite die angegebene /productlist so, als würden für diese Produkte die Aktionsanforderung auf dem opsi-server auf 'setup' stehen.
    Üblicherweise verwendet vom event_silent_install.

  • /processproducts <productid>[,<productid>]*
    Abarbeitung der Aktionsanforderungen welche für den Client auf dem opsi-Server gespeichert sind, aber beschränkt auf die Produkte welche mit /processproducts übergeben wurden.

5.2. Loging Dateien und Pfade

Die Default Logdatei heist opsi-script.log. Es werden per default bis zu 8 Sicherungskopien angelegt: opsi-script_0.log bis opsi-script_8.log.
Die Anzahl der Sicherungskopien kann per config [opsi-script-configs_log_rotation_count] geändert werden.

Die Logdateien werden im Encoding UTF-8 angelegt.

Die default Protokolldateien werden unter Windows in das Verzeichnis 'c:\opsi.org\log' geschrieben, welches der 'opsi-script' zu erstellen versucht. Wenn der 'opsi-script' nicht erfolgreich bei der Erstellung diese Protokollverzeichnisses ist, wird das Benutzer TEMP-Verzeichnis zum Speichern der Protokolldatei genutzt.

Logdateien unter Linux:
Ausgeführt als root (default): /var/log/opsi-script Ausgeführt als user: /tmp

Der Name der Protokolldatei und der Speicherort können durch eine spezifizierte Kommandozeile überschrieben werden.

In dem Fall, dass der opsi-script ein Skript im /batch mode und mit einem spezifizierten (und funktionierenden) User Kontext aufgerufen wird, ist der voreingestellte Protokollpfad opsi/tmp in dem Anwendungsverzeichnis des Benutzers. Dieses wird überschreiben, wenn eine anderer Protokollpfad angegeben ist.

Neben dem normalen Logfile wird auch eine opsi-script.history Logdatei geschrieben. Diese enthält für jeden Produktlauf seit der Installation eine Zeile nach dem Muster:
<timestamp> handled: <productid> Version: <version> Request: <request> Result: <result>
Beispiel:
2022-01-18 00:09 handled : gimp Version: 2.10.30-1 Request: setup Result: success

5.3. Exitcodes

Es gibt (seit 4.12.7.0) folgende Exitcodes:

  • 0 :
    Das Programm opsi-script hat sich ohne internen Fehler beendet und alle ausgeführten Skripte waren erfolgreich.

  • 1 :
    Das Programm opsi-script hat sich ohne internen Fehler beendet aber ein (oder mehr) ausgeführte Skripte sind nicht erfolgreich durchgelaufen (failed).

  • >1 :
    Es ist ein interner Fehler im Programm opsi-script aufgetreten (das sollte nicht passieren). Die Skriptausführung ist vermutlich fehlgeschlagen.

5.4. Prüfen der Skript-Syntax (testsyntax-Modus)

Verfügbar seit 4.12.7.

Wird opsi-script im testsyntax-Modus gestartet, so wird das gewählte Skript nicht komplett ausgeführt, sondern auf Syntaxfehler geprüft.
Ein solcher testsyntax-Lauf zeichnet sich durch folgende Eigenschaften aus:

  • Im Rahmen einer solchen Prüfung werden alle Zeilen des Skriptes durchlaufen. Also z.B. auch die Zweige einer if-else-endif Anweisung, welche normalerweise nie erreicht werden.

  • Alle Anweisungen, welche in irgendeiner Weise das System verändern würden, werden nicht ausgeführt.

  • Wird ein Syntaxfehler gefunden, so wird dies in der Logdatei vermerkt.
    Das Skript wird aber nicht beim ersten Syntaxfehler abgebrochen sondern bis zum Ende durchlaufen und so alle gefundenen Syntaxfehler im Log vermerkt.

  • Alle Anweisungen, welche den Skriptlauf in irgendeiner Form abbrechen (wie z.B. isFatalError), werden ignoriert.

  • In der Logdatei findet sich im Kopfteil die Warnung:
    Running in TestSyntax mode !!.

  • Wird ein Syntaxfehler gefunden, so wird das Skript als failed behandelt. Das hat die folgenden Auswirkungen:

    • In der Logdatei steht am Ende: script finished: failed.

    • Der opsi-script Prozess endet mit einem Exitcode = 1.

    • Ist opsi-script im 'Servicekontext' gestartet, also z.B. durch das Managementinterface per 'on_demand' und läuft im testsyntax-Modus, so wird das Produkt markiert als: Status: unknown und Report entweder ok: testsyntax oder failed: testsyntax

Testsyntax Ergebnis im opsi-configed: 1. Zeile: failed
Wenn Sie ein Script mit testsyntax prüfen, so sind zusätzliche Laufzeitfehlermeldungen in der Logdatei zu erwarten. Diese können zunächst ignoriert werden. Diese Laufzeitfehlermeldungen entstehen als Nebenwirkung des testsyntax-Laufs, da hier z.B. Variablen leer sind (oder andere unerwartete Werte haben).

Um ein Skript im testsyntax-Modus zu starten, gibt es folgende Möglichkeiten:

Screenshot: opsi-script im interaktiven Modus
Abbildung 1. opsi-script im interaktiven Modus
  • Interaktiv :
    Im interaktiven Modus das ausgewählte Skript über den Button Test Syntax (anstatt Start) starten.

  • Im Servicekontext :
    Über den config ('Hostparameter') opsi-script.global.testsyntax = true wird opsi-script dazu veranlasst, Scripte nur im testsyntax-Modus auszuführen.
    ACHTUNG: Stellen Sie diesen Config nur für einzelne Rechner auf true und vergessen Sie nicht, ihn wieder zurück auf false zu stellen!
    siehe auch: Abschnitt 6.2

  • Kommandozeilenparameter :
    Beim Aufruf des opsi-script kann der Parameter /testsyntax mitgegeben werden. Dann wird das angegebene Skript im testsyntax-Modus ausgeführt.
    siehe auch: Abschnitt 5.1

6. Weitere Konfigurationsoptionen

6.1. Zentrales Protokollieren von Fehlermeldungen

Wenn opsi-script im Kontext des opsi-service gestartet wird, werden die Protokoll-Informationen über den opsi-web-service an den opsi-server gesendet.

6.2. Zentrale Konfiguration über opsi Configs (Host Parameter)

Über opsi Configs (Host-Parameter) kann das Verhalten des opsi-script (z.B. beim Logging) beeinflusst werden:

  • opsi-script.global.debug_prog : boolean
    Wenn false, werden Logmeldungen, welche zum Debuggen des opsi-script selbst dienen, nicht ausgegeben, soweit es sich nicht um Warnungen oder Fehler handelt.
    Default: false
    Damit werden die Logdateien entlastet und nur noch Meldungen, die Skript-relevant sind, stehen in den Logdateien. Die Umstellung der entsprechenden Logmeldungen im Quellcode des opsi-script ist noch nicht abgeschlossen und wird bei ca. 1700 Log-Aufrufen auch noch etwas dauern.

  • opsi-script.global.debug_lib : boolean
    Wenn false, so werden Logmeldungen aus lokalen Funktionen, welche aus Libraries importiert wurden, nur ausgegeben, soweit es sich um Warnungen oder Fehler handelt.
    Der Wert kann innerhalb eines Skriptes mit der Anweisung SetDebug_Lib überschrieben werden.
    Default : false
    siehe auch SetDebugLib

  • opsi-script.global.default_loglevel : intstr
    Setzt (überschreibt) den Standard default Loglevel von opsi-script.
    Dieser Config hat keinen Einfluss auf Skripte, bei denen der Loglevel per setLogLevel explizit gesetzt worden ist.
    Default : '7'
    siehe auch SetLogLevel
    siehe auch [opsi-script-configs_force_min_loglevel]

  • opsi-script.global.force_min_loglevel : intstr
    Erzwingt einen minimalen Loglevel.
    Dies dient dazu, bei der Entwicklung und/oder Fehlersuche gezielt und temporär für einzelne Clients den Loglevel zu erhöhen ohne hierzu Anpassungen am Skript vornehmen zu müssen.
    Default: '0'
    siehe auch SetLogLevel
    siehe auch [opsi-script-configs_default_loglevel]

  • opsi-script.global.ScriptErrorMessages : boolean
    Wenn false, werden Syntax-Fehlermeldungen nicht interaktiv ausgegeben sondern nur in die Logdatei geschrieben. Im Produktivbetrieb ist es sinnvoll, dass dieser Parameter false ist. Daher ist der Default für diesen Config false. Der Default von opsi-script für diesen Parameter ist (aus historischen Gründen) true. Im Servicekontext überschreibt der Config den Default von opsi-script. Außerhalb des Servicekontext gilt der Default von opsi-script. Diese Default-Werte können innerhalb eines Skriptes mit der Anweisung ScriptErrorMessages überschrieben werden.
    Default: false
    siehe auch : ScriptErrorMessages

  • opsi-script.global.AutoActivityDisplay : boolean
    Wenn true, wird während des Laufs von externen Prozessen (winbatch,dosbatch,execwith Sektionen) ein (marquee) Fortschrittsbalken (der Endlos durch läuft) angezeigt.
    Default: true
    siehe auch : AutoActivityDisplay

  • opsi-script.global.supresssystemencodingwarning : boolean
    Wenn true, wird die Warnung: Encoding=system makes the opsiscript not portable between different OS unterdrückt.
    Default: false
    siehe auch : encoding

  • opsi-script.global.reverseproductorderbyuninstall : boolean
    Wenn true, wird die ProductListe umsortiert, so dass uninstall-Aktionen als erstes und in umgekehrter Reihenfolge der Installation durchgeführt werden.
    Default: false

  • opsi-script.global.log_rotation_count : string (number) // seit 4.12.4.29
    Gibt die Anzahl der lokal auf dem Client gesicherten Backups des opsi-script.log an. (opsi-script_0.log, opsi-script_1.log, …​)
    Default = 8 ; Maximal = 999

  • opsi-script.global.writeProductLogFile : boolean // seit 4.12.4.35
    Wenn true, wird auf dem Client im Unterverzeichnis lastprodlogs des opsi-script Logverzeichnisses ( z.B. c:\opsi.org\log\lastprodlogs) für jedes opsi-Produkt eine eigene Logdatei geschrieben. Der Name der Logdatei ist <productId>.log. Es existiert dann für jedes Produkt der Log des letzten Skriptlaufs. Im Fall, dass ein Skript Reboots innerhalb des Skriptes beinhaltet, so enthält dieses Log nur den Teil nach dem letzten Reboot.
    Default: false

  • opsi-script.global.testsyntax : boolean // seit 4.12.7.0
    Wenn true, werden die Skripte von opsi-script im testsyntax-Modus ausgeführt.
    Default: false
    siehe auch: Abschnitt 5.4

6.3. Skinnable 'opsi-script' [W/L/M]

Ab Version 3.6 verfügt 'opsi-script' einen veränderbare Oberfläche. Seine Elemente liegen im Unterverzeichnis winstskin des Verzeichnisses, in dem der ausgeführte opsi-script liegt. Die editierbare Definitionsdatei ist skin.ini.

Seit Version 4.12.4.15 sucht der 'opsi-script' nach dem zu verwendenden Skin Verzeichnis in folgender Reihenfolge, wobei das erste Verzeichnis, welches eine skin.ini enthält verwendet wird:

Windows:

%OpsiScriptDir% = C:\Program Files (X86)\opsi.org\opsi-client-agent\opsi-script

  1. %OpsiScriptDir%\..\custom\customskin

  2. %OpsiScriptDir%\skin

  3. %OpsiScriptDir%\winstskin(for backward compatibility)

Linux:

%OpsiScriptDir% = /opt/opsi-script

  1. '/usr/share/opsi-script/skin'

  2. '/usr/share/opsi-script/customskin' (for backward compatibility)

  3. %OpsiScriptDir%/skin

macOS:

%OpsiScriptDir% = /Applications/opsi-script/Contents/macOS

  1. '/usr/share/opsi-script/skin'

  2. %OpsiScriptDir%/../Resources/skin

Mit dem Befehl SetSkinDirectory kann ein SkinDirectory auch im Script angegeben werden. Wird bei diesem Befehl ein leerer oder ungültiger Pfad angegeben, so wird der Defaultpfad verwendet.

Beispiel:

SetSkinDirectory "%ScriptPath%\testskin"
sleepseconds 1
SetSkinDirectory ""

6.3.1. Anpassung an Corporate Identity

Alle graphischen Komponenten des opsi-script basieren auf den Darstellungskomponenten zum Anzeigen von Grafiken und werden auf die selbe Weise angepasst. Farben können auf drei unterschiedliche Weise angegeben werden: Als symbolischer Name (clRed), als Hexadezimalwert ($FF00FF) oder als rgb Wertliste ((255,0,0)). Ein Hilfsprogramm zur Auswahl von Farben und deren richtigen Schreibweise ist der opsi color chooser.

Als Hintergrund Grafikformate kommt eine Vielzahl unterschiedlicher Bitmap Formate wie .bmp, .png, jpeg usw in Frage. All dies Formate sind wieder Containerformate, dh. z.B. PNG ist nicht unbeding gleich PNG. Evtl ist das eine Darstellbar und das andere nicht. Ein Hilfsprogramm mit dem Sie schnell prüfen können ob eine gegeben Bitmap Grafik korrekt angezeigt werden wird, ist der opsi bitmap viewer.

Die Dateien, die Sie beim opsi-script anpassen können finden Sie im Verzeichnis /var/lib/opsi/depot/opsi-client-agent/files/opsi-script/skin:

  • bg.png
    Die Default Hintergrundgrafik des 'opsi-script' in welche dann zur Laufzeit Textmeldungen und Produktlogos eingeblendet werden. Der Name kann in der Datei skin.ini angepasst werden.

  • skin.ini
    Die Konfigurationsdatei in der festgelegt ist, an welcher Stelle, mit welchem Font und Farbe Textmeldungen eingeblendet werden. Und ab opsi-script Version XY welches Thema geladen werden soll.

Seit opsi-script Version 4.12.4.35 besteht die Möglichkeit zwischen zwei Themen (Theme) zu wählen. Ist Theme = default oder nichts angegeben wird das Standard-Aussehen von opsi-script beibehalten wie Sie es kennen und Sie haben über die skin.ini folgende detaillierte Einstellmöglichkeiten (hier belegt mit den ausgelieferten Default-Werten):

[Form]
Theme = default #diese Zeile kann hier auch weggelassen werden
Color = $00FFB359

[LabelVersion]
Left = 20
Top = 367
Width = 85
Height = 16
FontName = Arial
FontSize = 7
FontColor = $00E2A973
FontBold = false
FontItalic = false
FontUnderline = false

[LabelProduct]
Left = 260
Top = 100
Width = 315
Height = 100
FontName = Arial
FontSize = 32
FontColor = $00E7E7E7
FontBold = false
FontItalic = false
FontUnderline = false

[LabelInfo]
Alignment=Center
Left = 60
Top = 260
Width = 520
Height = 24
FontName = Arial
FontSize = 11
FontColor = $00E7E7E7
FontBold = true
FontItalic = false
FontUnderline = false

[LabelDetail]
Left = 60
Top = 285
Width = 520
Height = 20
FontName = Arial
FontSize = 8
FontColor = $00E7E7E7
FontBold = false
FontItalic = false
FontUnderline = false

[LabelCommand]
Left = 60
Top = 310
Width = 520
Height = 20
FontName = Arial
FontSize = 8
FontColor = $00E7E7E7
FontBold = false
FontItalic = false
FontUnderline = false

[LabelProgress]
Left = 60
Top = 335
Width = 520
Height = 40
FontName = Arial
FontSize = 8
FontColor = $00E7E7E7
FontBold = false
FontItalic = false
FontUnderline = false

[ActivityBar]
Left = 60
Top = 350
Width = 420
Height = 10
BarColor = clBlue

[ImageBackground]
File = bg.png

[ImageProduct]
File = product.png
Left = 40
Top = 65
Width = 160
Height = 160

[Image1Over]
File =
Left = 0
Top = 0
Width = 0
Height = 0

[Image2Over]
File =
Left = 0
Top = 0
Width = 0
Height = 0

[ProgressBar]
Left = 275
Top = 160
Width = 280
Height = 20
BarColor = $00E7E7E7
StartColor = $00E7E7E7
FinalColor = $00E7E7E7
ShapeColor = $00E7E7E7
Shaped = true
ShowFullBlock = false
RoundCorner = true
BlockSize = 10
SpaceSize = 3
Cylinder = true
Glass = true

Setzen sie Theme = WindowsSimple um nur eine einfache Oberfläche beim Installieren von opsi-Produkten anzuzeigen. Diese ähnelt der von Windows verwendeten wenn Betriebssystemupdates installiert werden. Es gibt folgende Einstellmöglichkeiten (hier belegt mit den ausgelieferten Default-Werten):

[Form]
Theme = WindowsSimple #Diese Zeile ist hier nötig und darf nicht geändert werden
Color = clHotLight

[LabelInfo]
Caption = Software wird installiert. Bitte warten.

6.3.2. Schutz Ihrer Änderungen vor Updates: Das custom Verzeichnis

Möchten Sie Änderungen welche Sie an den oben genannten Dateien durchgeführt haben, davor schützen, das selbige beim Einspielen einer neuen Version des opsi-client-agenten verloren gehen, so können Sie hierfür das custom Verzeichnis /var/lib/opsi/depot/opsi-client-agent/files/custom (früher /var/lib/opsi/depot/opsi-client-agent/files/opsi/custom) verwenden. Das komplette custom Verzeichnis wird bei der Installation einer neuen Version des opsi-client-agenten gesichert und wieder hergestellt, so das hier gemachte Änderungen nicht verloren gehen.

  • custom/opsi-script/skin/.
    wird bei der Installation des opsi-client-agent auf dem Client nach C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-script\skin kopiert.

6.4. 'opsi-script' encoding [W/L/M]

Einige Hinweise zu den verwendeten Begriffen:

  • ASCII, plain ASCII
    ASCII ist eine Abkürzung von: American Standard Code for Information Interchange
    'plain ascii': 7 Bit pro Zeichen; kann 128 verschiedene Zeichen darstellen. Hier enthalten sind die arabischen Ziffern, die Zeichen des lateinischen Alphabetes in Groß- und Kleinschreibung sowie eine Reihe von Sonder- und Steuerzeichen.
    Diese 128 Zeichen finden sich auch in den nachfolgend beschriebenen Erweiterungen wieder.

  • ANSI, Codepages
    Verwendet 8 Bit pro Zeichen (also ein Byte). Damit können Die ersten (unteren) 128 Zeichen entsprechen plain ASCII. Die oberen 128 Zeichen sind für unterschiedliche Alphabete in unterschiedlichen 'Codepages' definiert. Bekannte 'code pages':
    Windows-1252 = CP1252 = ISO 8851-1 = Western Europe code page.
    Die 256 Zeichen von CP1252 sind auch die Basis von Unicode UTF-16.
    'ANSI' ist eine Abkürzung von: American National Standards Institute:
    https://stackoverflow.com/questions/701882/what-is-ansi-format :
    'ANSI encoding is a slightly generic term used to refer to the standard code page on a system, ( …​ )The name "ANSI" is a misnomer, since it does not correspond to any actual ANSI standard, but the name has stuck.'
    In Deutsch:
    'ANSI encoding ist ein verbreiteter Begriff um sich auf die Standard code page eines Systems zu beziehen. (…​.) Der Name "ANSI" ist allerdings falsch und irreführend, da es keinen entsprechenden ANSI-Standard gibt. Trotzdem ist der Begriff allgemein üblich.'
    Was ist dann mit dem Begriff ANSI encoding gemeint ?
    https://wiki.freepascal.org/Character_and_string_types#AnsiChar says:
    'A variable of type AnsiChar, also referred to as char, is exactly 1 byte in size, and contains one "ANSI" (local code page) character.'
    In Deutsch:
    'Ein ANSI Zeichen hat eine Länge von einem Byte und ist gemäß der lokalen code page definiert.'
    Die Probleme mit der Verwendung von Codepages sind:

    • Für unterschiedliche Regionen in der Welt müssen unterschiedliche Codepages verwendet werden.

    • Es können nur maximal 255 Zeichen dargestellt werden aber viele Alphabete haben deutlich mehr Zeichen.

  • Unicode, UTF-8
    'Unicode' ist (wie 'ANSI') eine Encodingfamilie (nicht ein Encoding).
    Der bedeutendste Unterschied im Vergleich zu code pages ist, das um ein Zeichen zu codieren hier bis zu 4 Bytes verwendet werden. Damit können 'alle' Alphabete in einem Encoding untergebracht werden.
    Die wichtigsten Mitglieder der 'Familie' Unicode sind:

    • UTF-16-LE (auch teilweise bezeichnet als 'Windows Unicode'):
      Hier wird für jedes Zeichen mindestens 2 Byte (bis zu 4 Byte) verwendet. Das 'LE' steht für 'Little Endian' und gibt Auskunft über die Reihenfolge der Bytes. (Zeichen 'n' : LE='6E 00', BE='00 6E').

    • UTF-8:
      Verwendet für alle 'plain ASCII' Zeichen 1 Byte. Für alles was darüber hinaus geht werden 2 bis 4 Byte verwendet.
      Dies bedeutet auch, das eine Datei welche nur 'plain ASCII' Zeichen enthält es binär keinen Unterschied macht, ob diese nun als 'UTF-8' oder 'cp1252' abgespeichert worden ist.

    • BOM
      Eine Datei mit einem 'Unicode' encoding kann (muß aber nicht) in den ersten 4 Byte eine Information über das verwendete (unicode-)Encoding enthalten - den 'BOM' ('Byte Order Mark'). opsi-script erkennt und verwendet einen 'BOM' so er vorhanden ist.

Das Default Encoding für ein Script ist das Encoding das Systems auf dem der opsi-script läuft. D.h. auf einem Griechischen System wird das script mit unter Windows mit cp1253 interpretiert während das selbe Script auf einem deutschem Windows System mit cp1252 und auf einem Linux oder macOS System mit UTF-8 interpretiert wird.

Wir empfehlen dringend alle opsiscript Dateien in UTF-8 encoding zu erzeugen und die Zeile encoding=utf8 in die Datei einzufügen.
Dies macht Ihre Dateien besser portierbar.
Siehe hierzu auch den nachfolgenden Abschnitt.

  • encoding=<encoding>
    Seit Version 4.11.4.1 kann bei einem Script (egal ob Hauptscript, sub, include oder library) das encoding auch angegeben werden. Dazu gibt es den Befehl:
    encoding=<encoding>
    Dieser Befehl kann an einer beliebigen Stelle in der Scriptdatei stehen.
    Wird dieser Befehl nicht gefunden, so wird zunächst davon ausgegangen, das das Encoding der Datei dem Systemencoding des laufenden Betriebssystems entspricht. Unter Linux und macOS wäre dies UTF-8. Unter Windows ist dies ein cp* abhängig von der Lokalisierung. In Westeuropa z.B. cp1252.
    Wenn die einzulesende Datei Umlaute enthält (also nicht nur 'plain ASCII' ist), so führt das fehlen der Zeile encoding=utf8 zu der Warnung:
    'Encoding=system makes the opsiscript not portable between different OS'.
    Diese Warnung kann unterdrückt werden durch den config (Hostparameter):
    opsi-script.global.supresssystemencodingwarning = true.
    siehe auch [opsi-script-configs_supresssystemencodingwarning]
    Wenn die einzulesende Datei Umlaute enthält (also nicht nur 'plain ASCII' ist) und es einen Widerspruch zwischen dem detektierten Encoding (z.B. über ein BOM) und dem impliziten Encoding system bzw. dem per encoding= angegebenen Encoding gibt, so wird folgende Warnung in das Log geschrieben:
    'Warning: Given encodingString <> is different from the expected encoding <>'

    Bei der Verwendung von encoding=<encoding>
    kann <encoding> ist eines der folgenden Werte sein:

Tabelle 2. Encodings
encoding erlaubter alias Bemerkung

system

verwende encoding des laufenden OS

auto

versuche das encoding zu erraten.

UTF-8

utf8

UTF-8BOM

utf8bom

Ansi

ansi

8 Bit Encoding mit Codepage

CP1250

cp1250

Zentral- und osteuropäische Sprachen

CP1251

cp1251

Kyrillisches Alphabet

CP1252

cp1252

Westeuropäische Sprachen

CP1253

cp1253

Griechisches Alphabet

CP1254

cp1254

Türkisches Alphabet

CP1255

cp1255

Hebräisches Alphabet

CP1256

cp1256

Arabisches Alphabet

CP1257

cp1257

Baltische Sprachen

CP1258

cp1258

Vietnamesische Sprachen

CP437

cp437

Die ursprüngliche Zeichensatztabelle des IBM-PC

CP850

cp850

"Multilingual (DOS-Latin-1)", westeuropäische Sprachen

CP852

cp852

Slawische Sprachen (Latin-2), zentraleuropäische und osteuropäische Sprachen

CP866

cp866

Kyrillisches Alphabet

CP874

cp874

Thai Alphabet

CP932

cp932

Japanische Schreibsysteme (DBCS)

CP936

cp936

GBK für chinesische Kurzzeichen (DBCS)

CP949

cp949

Hangul/Koreanische Schriftzeichen (DBCS)

CP950

cp950

Chinesische Langzeichen (DBCS)

ISO-8859-1

iso8859-1

Latin-1

ISO-8859-2

iso8859-2

Latin-2

KOI-8

koi8

Kyrillisches Alphabet

UCS-2LE

ucs2le, utf16le

(UTF-16-LE, Windows Unicode Standard)

UCS-2BE

ucs2be, utf18be

(UTF-16-BE)

siehe auch : [reencodestr]
siehe auch : [reencodestrlist]
siehe auch : [strLoadTextFileWithEncoding]
siehe auch : [loadUnicodeTextFile]
siehe auch : [loadTextFileWithEncoding]

Quellen siehe auch:

7. Das opsi-script Skript

Wie schon erwähnt, interpretiert das Programm opsi-script eine eigene, einfache Skriptsprache, die speziell auf die Anforderungen von Softwareinstallationen zugeschnitten ist. Jede Installation wird durch ein spezifisches Skript beschrieben und gesteuert.

In diesem Abschnitt ist der Aufbau eines opsi-script Skripts im Überblick skizziert – etwa so, wie man es braucht, um die Funktionsweise eines Skripts in etwas nachvollziehen zu können.

Sämtliche Elemente werden in den nachfolgenden Abschnitten genauer beschrieben, so dass auch deutlich wird, wie Skripte entwickelt und abgeändert werden können.

7.1. Ein Beispiel

In ihren äußeren Form ähneln die opsi-script Skripte .INI-Dateien. Sie setzen sich aus einzelnen Abschnitten (Sektionen) zusammen, die jeweils durch eine Überschrift (den Sektionsnamen) in eckigen Klammern [] gekennzeichnet sind. Ein beispielhaftes, schematisches opsi-script Skript (hier mit einer Fallunterscheidung für verschiedene Betriebssystem-Varianten) könnte etwas so aussehen:

[Actions]
Message "Installation von Mozilla"
SetLogLevel=6

;Welche Windows-Version?
DefVar $MSVersion$

Set $MSVersion$ = GetMsVersionInfo
if CompareDotSeparatedNumbers($MSVersion$,">=","6")
  sub_install_winnt6
else
  stop "not a supported OS-Version"
endif


[sub_install_winnt6]
Files_copy_winnt6
WinBatch_Setup

[Files_copy_winnt6]
copy "%scriptpath%\files_win10\*.*" "c:\temp\installation"

[WinBatch_Setup]
c:\temp\installation\setup.exe

Wie lassen sich die Sektionen oder Abschnitte dieses Skripts lesen?

7.2. Primäre und sekundäre Unterprogramme des opsi-script Skripts

Dass das Skript insgesamt als die Vorschrift zur Ausführung einer Installation anzusehen ist, d.h. als eine Art von Programm, kann jeder seiner Sektionen als Teil- oder Unterprogramm (auch als "Prozedur" oder "Methode" bezeichnet) aufgefasst werden.

Das Skript besteht demnach aus einer Sammlung von Teilprogrammen. Damit ein Mensch oder ein Interpreter-Programm es richtig liest, muss bekannt sein, welches der Teilprogramme Priorität hat, mit welchem also in der Abarbeitung angefangen werden soll.

Für die opsi-script Skripte ist festgelegt, dass die primäre Sektion mit dem Titel [Actions] abgearbeitet wird. Alle anderen Sektionen fungieren als Unterprogramme und können von dieser Sektion aufgerufen werden. Nur in den Sub-Sektionen können dann wiederum Unterprogramme aufgerufen werden.

Wird ein Script als 'userLoginScript' aufgerufen, und enthält eine Sektion [ProfileActions] so wird das Script ab dieser Sektion abgearbeitet.

Dies liefert die Grundlage für die Unterscheidung zwischen primären und sekundären Unterprogrammen:

Die primären oder Steuerungssektionen umfassen:

  • die Actions-Sektion

  • die Sub-Sektionen (Unterprogramme der Actions-Sektion, die auch deren Syntax und Funktionslogik erben).

  • die ProfileActions-Sektion die je nach script mode (Machine/Login) unterschiedlich interpretiert wird.

In diesen Sektionsarten können andere Sektionstypen aufgerufen werden, so dass der Ablauf des Skripts "im Großen" geregelt wird.

Dagegen weisen die sekundären, aufgabenspezifischen Sektionen eine eng an die jeweilige Funktion gebundene Syntax auf, die keinen Verweis auf andere Sektionen erlaubt. Derzeit existieren die folgenden Typen sekundärer Sektionen:

  • Files-Sektionen,

  • WinBatch-Sektionen,

  • DosBatch/DosInAnIcon/ShellInAnIcon-Sektionen,

  • Registry-Sektionen

  • Patches-Sektionen,

  • PatchHosts-Sektionen,

  • PatchTextFile-Sektionen,

  • XMLPatch-Sektionen (nicht mehr empfohlen),

  • XML2-Sektionen,

  • LinkFolder-Sektionen,

  • opsiServiceCall-Sektionen,

  • ExecPython-Sektionen,

  • ExecWith-Sektionen,

  • LDAPsearch-Sektionen.

Im Detail wird Bedeutung und Syntax der unterschiedlichen Sektionstypen in den Abschnitten Syntax und Bedeutung der primären Sektionen eines opsi-script Skripts und Sekundäre Sektionen behandelt.

7.3. String-Ausdrücke im opsi-script Skript

In den primären Sektionen können textuelle Angaben (String-Werte) auf verschiedene Weisen bestimmt werden:

  • Durch die direkte Nennung des Inhalts, in der Regel in (doppelten) Anführungszeichen, Beispiele:
    '"Installation von Mozilla"'
    '"n:\home\user name"'

  • Durch die Anführung einer String-Variable oder String-Konstante, die einen Wert "enthält" oder "trägt":
    '$MsVersion$'
    kann – sofern der Variable zuvor ein entsprechender Wert zugewiesen wurde - für "6.1" stehen .

  • Durch Aufruf einer Funktion, die einen String-Wert ermittelt:
    'EnvVar ("Username")'
    holt z.B. einen Wert aus der Systemumgebung, in diesem Fall den Wert der Umgebungsvariable Username. Funktionen können auch parameterlos sein, z.B.
    'GetMsVersionInfo'
    Dies liefert auf einem Win7-System wieder den Wert "6.1" (anders als bei einer Variablen wird der Wert aber bei jeder Verwendung des Funktionsnamens neu bestimmt).

Durch einen additiven Ausdruck, der einfache String-Werte bzw. -Ausdrücke zu einem längeren String verkettet (wer unbedingt will, kann dies als Anwendung der Plus-Funktion auf zwei Parameter ansehen …​).
'$Home$ + "\mail"'

(Mehr zu diesem Thema in Kapitel String-Werte, String-Ausdrücke und String-Funktionen).

In den sekundären Sektionen gilt die jeweils spezifische Syntax, die z.B. beim Kopieren weitgehend der des "normalen" DOS-copy-Befehls entspricht. Daher können dort keine beliebigen String-Ausdrücke verwendet werden. Zum "Transport" von String-Werten aus den primären in die sekundären Sektionen eignen sich ausschließlich einfache Werte-Träger, also die Variablen und Konstanten.

Im nächsten Kapitel folgt Genaueres zu Definition und Verwendung von Variablen und Konstanten.

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

8.1. 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.

8.2. 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.

8.2.1. 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.

8.2.2. 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:

8.2.3. 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%'

8.2.4. 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

8.2.5. 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.

8.2.6. 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).

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

8.3.1. 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.

8.3.2. 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"

8.3.3. 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:

8.3.4. 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).

8.4. 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.

9. Syntax und Bedeutung der primären Sektionen eines opsi-script Skripts [W/L/M]

Wie bereits in Abschnitt Primäre und sekundäre Unterprogramme des opsi-script Skripts dargestellt, zeichnen sich die Actions-Sektion dadurch aus, dass sie den globalen Ablauf der Abarbeitung eines opsi-script-Skripts 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 Skripts.

9.1. Die primären Sektionen [W/L/M]

In einem Skript können vier Arten primärer Sektionen vorkommen:

  • eine Initial-Sektion zu Beginn des Skripts (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 Log-Level). 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 Skripts 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]

9.2. Parametrisierungsanweisungen für den opsi-script [W/L/M]

9.2.1. 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

0 = nothing (absolut nichts)
1 = essential ("unverzichtbares")
2 = critical (unerwartet Fehler die zu einem Programmabbruch führen)
3 = error (Fehler, die kein laufendes Programm abbrechen)
4 = warning (das sollte man sich nochmal genauer anschauen)
5 = notice (wichtige Aussagen zu dem Programmverlauf)
6 = info (zusätzlich Informationen)
7 = debug (wichtige debug Meldungen)
8 = debug2 (mehr debug Informationen und Daten)
9 = confidential (Passwörter und andere sicherheitsrelevante Daten)
  • 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 Stringlisten Variablen, die Ausgaben von externen Prozessen, soweit diese nicht einer Stringliste zugewiesen werden, die Ergebnisse der Teilauswertung boolscher Ausdrücke (hinter if)

  • Auf Loglevel 8 wird geloggt:
    Stringlisten welche von Funktionen erzeugt werden, die Ausgaben von externen Prozessen, wenn diese einer Stringliste zugewiesen werden

Der Default ist "7".
siehe auch : opsi-script-configs_default_loglevel siehe auch : opsi-script-configs_force_min_loglevel

SetDebug_Lib = <boolean value> //seit 4.12.8.0
Wenn false, so werden Logmeldungen aus lokalen Funktionen, welche aus Libraries importiert wurden, nur ausgegeben, soweit es sich um Warnungen oder Fehler handelt.
Der Default ist false.
siehe auch : opsi-script-configs_debug_lib

9.2.2. Logdatei im Append-Mode senden

  • forceLogInAppendMode = <boolean value> //seit 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.

9.2.3. 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>

9.2.4. Reaktion auf Fehler [W/L/M]

Zu unterscheiden sind zwei Sorten von Fehlern, die unterschiedlich behandelt werden müssen:

  1. fehlerhafte Anweisungen, die der opsi-script nicht "versteht", d.h. deren Interpretation nicht möglich ist (syntaktischer Fehler),

  2. 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 Skripts 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 Stringliste 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 Skripts.

  • ExitOnError = <Wahrheitswert>
    Mit dieser Anweisung wird festgelegt, ob bei Auftreten eines Fehlers die Abarbeitung des Skripts 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.

9.2.5. 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.

9.2.6. 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,dosbatch,execwith Sektionen) ein (marquee) Fortschrittsbalken (der Endlos durch läuft) angezeigt.
    siehe auch: opsi-script-configs_AutoActivityDisplay

9.2.7. 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.

9.3. 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.

9.3.1. 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"

9.3.2. 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"'

9.3.3. 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".

9.3.4. 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.

9.3.5. String-Funktionen zur Ermittlung des Betriebssystemtyps

  • 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 auch GetMsVersionName

Tabelle 3. Windows Versionen
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".

Tabelle 4. Windows Versionen
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)

9.3.6. 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' / 'DosBatch' / 'ExecWith' Sektion aus.
    Der Aufruf anderer opsi-script Befehle ( wie z.B. einer 'Files' Sektion) verändert den gefundenen ExitCode nicht.
    Bei 'DosBatch' 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:

DosInAnIcon_exit1
set $ConstTest$ = "1"
set $CompValue$ = getLastExitCode
if ($ConstTest$ = $CompValue$)
	comment "DosBatch / DosInAnIcon  exitcode passed"
else
	set $TestResult$ = "not o.k."
	LogWarning "DosBatch / DosInAnIcon  exitcode failed"
endif

[DosInAnIcon_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, liefert GetUsercontext den leeren String.

9.3.7. 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 Default sysnative. Ü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 stattdessen getRegistryValue 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"

  • 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'.

9.3.8. 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ützt GetValueFromInifile 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","")'

9.3.9. 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 Datei properties.conf befindet. Wenn ja, wird versucht aus dieser Datei den Wert des Properties zu lesen. Dabei wird die Datei properties.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 Datei properties.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 wie GetProductProperty 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)

9.3.10. 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.

9.3.11. 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.

  • [FileExists]

  • [FileOrFolderExists]

  • [DirectoryExists]

  • [fileIsSymlink]

  • StringSplit (`STRINGWERT1, STRINGWERT2, INDEX)`
    (abgekündigt: use splitString / 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

  • strLoadTextFile ( <filename> ) //since 4.11.4.6 [W/L/M]
    liefert die erste Zeile von <filename> als String.
    siehe auch : [strLoadTextFileWithEncoding]

  • 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"

9.3.12. 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 funktion CompareDotSeparatedNumbers : [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 funktion CompareDotSeparatedStrings : [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 von marktime.
    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]

9.3.13. (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.

9.3.14. 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

9.4. String-Listenverarbeitung [W/L/M]

Eine String-Liste (oder ein String-Listenwert) ist eine Abfolge von String-Werten. Der Wert einer Stringliste 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 Stringliste liefert

  • Aus einer Stringlisten Variable

  • Seit 4.12.4.32 aus einem String im json style, welche als Stringliste 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 Stringliste 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).

9.4.1. 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

0x0000001 (VER_NT_WORKSTATION)
0x0000002 (VER_NT_DOMAIN_CONTROLLER)
0x0000003 (VER_NT_SERVER)

SuiteMask

0x00000001 (VER_SUITE_SMALLBUSINESS)
0x00000002 (VER_SUITE_ENTERPRISE)
0x00000004 (VER_SUITE_BACKOFFICE)
0x00000008 (VER_SUITE_COMMUNICATIONS)
0x00000010 (VER_SUITE_TERMINAL)
0x00000020 (VER_SUITE_SMALLBUSINESS_RESTRICTED)
0x00000040 (VER_SUITE_EMBEDDEDNT)
0x00000080 (VER_SUITE_DATACENTER)
0x00000100 (VER_SUITE_SINGLEUSERTS)
0x00000200 (VER_SUITE_PERSONAL)
0x00000400 (VER_SUITE_SERVERAPPLIANCE)
  • 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

  • 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

Die Funktion GetLocaleInfoMap ersetzt die ältere GetLocaleInfo, da diese Werte ausliest, die schwierig zu interpretieren sind:

  • getLocaleInfo
    (abgekündigt): Bitte GetLocaleInfoMap 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 Default root\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

Sie funktioniert ähnlich wie die oben beschriebene Funktion getListFromWMI.

Die Benutzeroberfläche von 'opsi-wmi-test' gliedert sich in zwei Bereiche.

Im oberen Bereich ('Connection to WMI service') werden die Daten abgefragt, die benötigt werden um eine Verbindung zum WMI Service aufzubauen. Benötigt wird der Computername ('Computer') der angesprochen werden soll, der WMI Namensraum ('NameSpace') der zu verwendenden WMI Klasse, sowie eventuell Benutzername ('User') und Password ('Password'). Beim Start von opsi-wmi-test.exe sind hierfür schon Standardwerte ('Computer' = localhost, 'NameSpace' = \root\cimv2, 'User' = < > , 'Password' = < >) angegeben mit der auf den lokalen WMI Service und den am meisten verwendeten WMI Klassen zugegriffen werden kann.
Es gibt auch die Möglichkeit auf entfernte Computer zuzugreifen. Dann muss der entsprechende Netzwerkname unter dem der Computer zu erreichen ist und eventuell Benutzername und Password angegeben werden.

opsi-wmitestgui-start
Abbildung 2. GUI von opsi-wmi-test. Im oberen Bereich ('Connection to WMI service') können die Parameter eingegben werden die benötigt werden um eine Verbindung zum WMI Service aufzubauen. Im unteren Bereich ('Request to WMI service') werden die Daten abgefragt die benötigt werden um die gewünschte Anfrage an den WMI Service zu stellen.

Im unteren Bereich ('Request to WMI service') werden die Daten abgefragt die benötigt werden um die gewünschte Anfrage an den WMI Service zu stellen. Benötigt wird hierbei die WMI Klasse ('Class') bzw. ihr Alias ('Alias') und die Eigenschaften ('WMI Properties') die abgefragt werden sollen. Die WMI Klasse kann entweder direkt im entsprechendem Feld ('Class' oder 'Alias') eingegeben oder über eine Liste ausgewählt werden (Abbildung 9.2). Nachdem die Klasse ausgewählt ist werden ihre Eigenschaften in dem Feld 'Available WMI Properties' angezeigt.

opsi-wmitestgui-2

Verfügbare Eigenschaften können ausgewählt und dann mittels drag & drop oder der Schaltfläche

opsi-wmitestgui-button-pfeil-rechts

nach 'Selected WMI Properties' verschoben werden (Abbildung 9.3) .
Anmerkung: Dies geht auch umgekehrt. Eigenschaften können von 'Selected WMI Properties' wieder nach 'Available WMI Properties' per drag & drop oder der Schaltfläche

opsi-wmitestgui-button-pfeil-links

verschoben werden.

opsi-wmitestgui-3
opsi-wmitestgui-4
Abbildung 3. Nachdem sich Eigenschaften im Feld 'Selected WMI Properties' befinden, kann durch anklicken der Schaltfläche 'Execute' die Anfrage an den WMI Service gestellt werden. In dem Feld 'Condition' kann die Abfrage noch mittels SQL Anweisungen verfeinert werden.

Nachdem sich Eigenschaften im Feld 'Selected WMI Properties' befinden, kann durch anklicken der Schaltfläche 'Execute' die Anfrage an den WMI Service gestellt werden. In dem Feld 'Condition' kann die Abfrage noch mittels SQL Anweisungen verfeinert werden, z.B. where <property> = <value>.

Die endgültige Abfrage wird im 'Query' Feld angezeigt. Sie kann von dort kopiert werden aber dort nicht verändert werden. Das Ergebnis der Anfrage wird in einem extra Fenster ausgegeben. Dabei kann es sich auch um eine Fehlermeldung handeln falls die Anfrage nicht bearbeitet werden konnte.

opsi-wmitestgui-resultwindow
Abbildung 4. Das Ergebnis der Anfrage wird in einem extra Fenster ausgegeben

In einem dritten Fenster haben Sie nun alle Daten Ihrer Abfrage : 'Namespace', 'Selected Class', 'Properties list', 'Selected Properties' and 'All available Properties'. Sie können diese Daten von hier aus per cut&paste in Ihr opsi-script übertragen

opsi-wmitestgui-querywindow
Abbildung 5. In einem dritten Fenster haben Sie nun alle Daten Ihrer Abfrage : 'Namespace', 'Selected Class', 'Properties list', 'Selected Properties' and 'All available Properties'.

9.4.2. 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.

9.4.3. 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.

9.4.4. (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 wie getLocaleInfoMap, getFileVersionMap, geliefert werden. siehe auch: Info Maps.

  • getValueBySeparator(<key string>,<separator string>,<hash string list> ) //since 4.11.2.1 [W/L/M]
    arbeitet wie getValue 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 hat count ($list1$) den Wert "5".

9.4.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 bei DosInAnIcon (ShellInAnIcon),ExecWith und ExecPython Aufrufen – die Ausgabe der Kommandozeilenprogramme in der Form einer String-Liste ein. Z.B. liefert der Ausdruck getOutStreamFromSection ('DosInAnIcon_netstart')
    wenn die aufgerufene Sektion definiert ist durch

set $list$ = getOutStreamFromSection ('DosInAnIcon_netstart')

[DosInAnIcon_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 ('DosInAnIcon_netstart winst /sysnative')

[DosInAnIcon_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:

DosInAnIcon_netstart winst /sysnative

[DosInAnIcon_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:

DosInAnIcon_netstart winst /sysnative
set $exitcode$ = getLastExitcode

[DosInAnIcon_netstart]
net start

siehe auch: shellCall_str

  • getReturnListFromSection ( Sectionname ) [W/L/M]
    In Sektionen bestimmter Typen – derzeit implementiert nur für XMLPatch-und opsiServiceCall-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

9.4.6. 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

9.4.7. 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 Funktion GetProductProperty 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 Datei properties.conf befindet. Wenn ja, wird versucht aus dieser Datei den Wert des Properties zu lesen. Dabei wird die Datei properties.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 Datei properties.conf nicht gefunden oder enthält den gesuchten Eintrag nicht, so wird der <default value> zurückgegeben.
    <default value> kann bei getProductPropertyList (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]

9.4.8. 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)

9.4.9. 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.

  • 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

  • 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).

9.4.10. 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.

9.5. 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%',
					]

9.6. 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]

9.7. 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

Encoding

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

9.7.1. 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/
Encoding

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 Skripts 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" ]

9.8. 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.

opsi-regexpr-tester-start

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.

opsi-regexpr-tester-input

Wenn die Regular Expression zu dem Text (oder teilen davon) passt, so werden die passenden Teile grün markiert und 'successful' angezeigt.

opsi-regexpr-tester-success

Wenn die Regular Expression zu keinem Textteil passt, so wird ein Fehler angezeigt.

opsi-regexpr-tester-failure

Ü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.

9.9. 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.

9.10. 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: "

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

9.11. 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 ('DosInAnIcon_netstart winst /sysnative')
    
    [DosInAnIcon_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:

    DosInAnIcon_netstart winst /sysnative
    
    [DosInAnIcon_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:

    DosInAnIcon_netstart winst /sysnative
    set $exitcode$ = getLastExitcode
    
    [DosInAnIcon_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 der powershell.exe ist per default sysnative. 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 auf Restricted steht, können Skripte nicht ohne weiteres ausgeführt werden. Daher hat der Befehl powershellCall per default folgendes Verhalten: Die aktuelle ExecutionPolicy wird gesichert und die ExecutionPolicy auf RemoteSigned 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 Funktion powershellCall dort aufgerufen, wo eine Stringliste erwartet wird, so enthält die Stringliste die Ausgabe von <commandstr>.
    Seit 4.12.4.35:
    Wird als aktuelle ExecutionPolicy AllSigned 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. angegebene PASSPARAS 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 Abschnitt 10.16.1
    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-Befehls Get-Partition enthält NULL-Characters \u0000 in der Spalte DriveLetter überall dort, wo kein Laufwerksbuchstabe steht. Das führt in opsi-script zu Problemen beim direkten Einlesen der Ausgabe von Get-Partition. Möchte man die Ausgabe von Get-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 Funktion powershellCall 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 Funktion powershellCall 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 wie winbatch 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.

9.12. 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 DosBatch oder Winbatch Aufrufe erben trotzdem das 'alte' Environment. Daher danach winbatch 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.

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.

9.13. 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 arbeitet includelog 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 Befehl encoding angegeben. Wird als encoding auto 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"

  • SetConfidential <secret string> [W/L/M]
    Dient dazu vertrauliche Informationen (z.B. Passwörter) aus den Logdateien fernzuhalten. Diese werden dort durch '(confidential)' ersetzt.
    Wir 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:

    1. Sichern des aktuellen Loglevels

    2. Setzen des Loglevel auf Warning (4)

    3. Auswerten der übergeben Stringexpression (z.B. einer Funktion welche einen String liefert)

    4. Setzen dieses ermittelten Strings als Confidential d.h. dieser String wird ab jetzt nicht mehr geloggt.

    5. Wiederherstellen des ursprünglichen Loglevels

    6. 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----

  • 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 function asconfidential, but for stringlists.

9.14. 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 andere message 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.

9.15. 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'

  • 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 mit readVersionFromProfile 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 auch scriptWasExecutedBefore

  • 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 mit readVersionFromProfile 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 mit saveVersionToProfile möglich ist). Somit benötigen Sie nur diese eine Funktion in einer if 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

9.16. 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

9.17. 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

9.18. 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

9.18.1. 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.

9.18.2. 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:

  • 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".

  • 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 denn 0.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 und 1.24a > 1.23b.

siehe auch: Stringfunktion`CompareDotSeparatedNumbers(<string1>, <string2>)>> : [CompareDotSeparatedNumbers_str]
siehe auch: Stringfunktion `CompareDotSeparatedStrings(
<string1>, <string2>`)` : [CompareDotSeparatedStrings_str]
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

  • 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 wird true zurückgegeben, ansonsten false.
    Die Zugriffsart ist per Default sysnative. Ü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> ) : 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 wird true zurückgegeben, ansonsten false.
    Die Zugriffsart ist per Default sysnative. Ü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.

9.19. 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.

9.19.1. 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"

9.19.2. 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

9.20. 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:

  1. 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).

  2. Die bezeichneten Befehle können auch in einer andere Datei untergebracht werden, welche als externe Sektion läuft.

  3. Jede String-Liste kann als eine Befehlsliste für einen Sub-Programm Aufruf benutzt werden.

Zur Syntax der Sub-Programm Aufrufe im einzelnen:

9.20.1. 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:

  1. Das Sub-Programm ist eine Zeilenabfolge, die im sich ausführbaren Bereich des opsi-script Skripts 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.

  2. 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.

  1. 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".

9.21. 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 als ExitWindows /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 Skripts beendet hat.

  • ExitWindows /ImmediateReboot [W/L/M]
    unterbricht die normale Ausführung eines Skripts, 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 /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

9.22. 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 Skripts, 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 Produktstaus 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 Skripts 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 von markErrorNumber 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.

9.23. Lokale Funktionen [W/L/M]

Seit Version 4.12 kennt opsi-script auch lokale Funktionen.

Ein Beispiel:

<