This is an old revision of the document!
Dies soll ein Konzept für OPSI ohne dauerhaft installierten LoginBlocker darstellen. Dadurch werden Benutzer niemals grundlos an der Anmeldung am Betriebssystem gehindert. Der LoginBlocker wird dabei bedarfsweise im System registriert und blockt somit nur bei anstehenden Softwareinstallationen.
Da PRE- und POSTinstallation als normales OPSI-Paket realisiert werden muss hier mit Prioritäten gearbeitet werden. Das PREinstallation Paket hat eine hohe Priorität und wird vor allen anderen ausgeführt. Das POSTinstallation Paket hat die niedrigste Priorität und wird als letztes ausgeführt. Dadurch ist sichergestellt, dass die Reihenfolge auf jeden Fall korrekt ist.
Eine Installation enthält also immer mindestens einen Neustart.
Software bei denen bekannt ist, dass eine Installation mit angemeldetem Benutzer nicht funktioniert da es zu Konflikten kommen kann bekommen das PRE- und das POSTinstallationspaket als Abhängigkeit eingetragen.
Interessant wird dies System vor allem mit dem VPN/WAN Plugin bei dem das so lästiges abwarten der TimeOuts beim Systemstart entfällt.
Damit überhaupt eine Verbindung zum OPSI Server stattfindet (beim Systemstart wird ja kein Connect durchgeführt) wird ein weiteres Event benötigt welches gelegentlich auf Software prüft. Dazu eignet sich am besten ein Timer Event (Beschreibung folgt)
Ich habe aus den bestehenden Skripten von UIB einige Codezeilen übernommen. Unter anderem die Zeilen aus der Installation des opsi-client-agents bei dem der LoginBlocker installiert wird. Dazu wird aus diesem außerdem Paket der Ordner OpsiLoginBlocker benötigt. Dieser muss dem PREinstallation Paket hinzugefügt werden.
[Package] version: 1 depends: incremental: False [Product] type: localboot id: preinstallation name: PREinstallation description: PREinstallation Package advice: Passt die Hostparameter an version: 3 priority: 93 licenseRequired: False productClasses: setupScript: PREinstallation.ins uninstallScript: updateScript: alwaysScript: onceScript: customScript: userLoginScript: [ProductProperty] type: unicode name: install_loginblocker multivalue: False editable: False description: install_loginblocker values: ["false", "true"] default: ["true"] [Changelog]
; This script is based on Code from UIB GmbH with some modifications from Tobias Friede ; This script comes with ABSOLUTELY NO WARRANTY ; Die Benutzung erfolgt auf eigene Verantwortung. [Actions] requiredWinstVersion >= "4.10.8.6" DefVar $ProductId$ DefStringList $configStates$ DefVar $install_loginblocker$ set $install_loginblocker$ = GetProductProperty("install_loginblocker", "false") ; --------------------------------------- Set $ProductId$ = "PREinstallation" ; --------------------------------------- ShowBitmap "%SCRIPTPATH%\opsi.png" $ProductId$ if $install_loginblocker$ = "true" sub_install_loginblocker ;registry_write_loginblocker_flag !!noch nicht implementiert!! Dient dazu damit das Postinstallation Script erkennen kann ob der LoginBlocker durch ein Preinstallation Script installiert wurde. else message "Run installation without LoginBlocker" endif ; --------------------------------------- ; Enable gui_startup ; --------------------------------------- set $configStates$ = addtolist($configStates$, "[newmap]") set $configStates$ = addtolist($configStates$, "type=ConfigState") set $configStates$ = addtolist($configStates$, "configId=opsiclientd.event_gui_startup.active") set $configStates$ = addtolist($configStates$, "values= true") set $configStates$ = addtolist($configStates$, "objectId=%opsiserviceUser%") markErrorNumber OpsiServiceHashList_configState_updateObjects if errorsOccuredSinceMark > 0 isFatalError endif [OpsiServiceHashList_configState_updateObjects] "method": "configState_updateObjects" "HashList": "$configStates$" "params": [ ] ExitWindows /Reboot [sub_install_loginblocker] DefVar $INST_NTVersion$ DefVar $INST_SystemType$ Set $INST_SystemType$ = GetSystemType set $INST_NTVersion$ = GetMsVersionInfo comment "copying loginblocker" if $INST_NTVersion$ >= "6.0" if ($INST_SystemType$ = "64 Bit System") Files_copy_vista_loginblocker_64 /Sysnative else Files_copy_vista_loginblocker_32 endif endif ; Registriere LogInBlocker if ($INST_NTVersion$ >= "6.0") Registry_vista_loginblocker /Sysnative else message "Sorry, I can not install the CredentialProvider on XP" endif [Files_copy_vista_loginblocker_64] copy -Vc "%SCRIPTPATH%\opsiloginblocker\64bit\*.dll" "%SYSTEM%" [Files_copy_vista_loginblocker_32] copy -Vc "%SCRIPTPATH%\opsiloginblocker\32bit\*.dll" "%SYSTEM%" [Registry_vista_loginblocker] ;openkey [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{d2028e19-82fe-44c6-ad64-51497c97a02a}] ;set ""="OpsiLoginBlocker" openkey [HKEY_CLASSES_ROOT\CLSID\{d2028e19-82fe-44c6-ad64-51497c97a02a}] set ""="OpsiLoginBlocker" openkey [HKEY_CLASSES_ROOT\CLSID\{d2028e19-82fe-44c6-ad64-51497c97a02a}\InprocServer32] set ""="OpsiLoginBlocker.dll" set "ThreadingModel"="Apartment" openkey [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filters\{d2028e19-82fe-44c6-ad64-51497c97a02a}] set ""="OpsiLoginBlocker" set "LoginBlockerTimeoutConnect"=reg_dword:120 set "StartOpsiCredentialProvider"=reg_dword:0x00000000 set "LoginBlockerLogLevel"=reg_dword:6
[Package] version: 1 depends: incremental: False [Product] type: localboot id: postinstallation name: POSTinstallation description: POSTinstallation Package advice: version: 2.0 priority: -91 licenseRequired: False productClasses: setupScript: POSTinstallation.ins uninstallScript: updateScript: alwaysScript: onceScript: customScript: userLoginScript: [Changelog]
; This script is based on Code from UIB GmbH with some modifications from Tobias Friede ; This script comes with ABSOLUTELY NO WARRANTY ; Die Benutzung erfolgt auf eigene Verantwortung. [Actions] requiredWinstVersion >= "4.10.8.6" DefVar $ProductId$ DefStringList $configStates$ ; ---------------------------------------------------------------- Set $ProductId$ = "POSTinstallation" ; ---------------------------------------------------------------- ShowBitmap "%SCRIPTPATH%\opsi.png" $ProductId$ Registry_vista_del_loginblocker /Sysnative set $configStates$ = addtolist($configStates$, "[newmap]") set $configStates$ = addtolist($configStates$, "type=ConfigState") set $configStates$ = addtolist($configStates$, "configId=opsiclientd.event_gui_startup.active") set $configStates$ = addtolist($configStates$, "values= false") set $configStates$ = addtolist($configStates$, "objectId=%opsiserviceUser%") markErrorNumber OpsiServiceHashList_configState_updateObjects if errorsOccuredSinceMark > 0 isFatalError endif [OpsiServiceHashList_configState_updateObjects] "method": "configState_updateObjects" "HashList": "$configStates$" "params": [ ] [Registry_vista_del_loginblocker] deletekey [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{d2028e19-82fe-44c6-ad64-51497c97a02a}] deletekey [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filters\{d2028e19-82fe-44c6-ad64-51497c97a02a}] deletekey [HKEY_CLASSES_ROOT\CLSID\{d2028e19-82fe-44c6-ad64-51497c97a02a}]
ACHTUNG: Seien Sie beim bearbeiten der Host-Parameter vorsichtig. Durch falsche Einstellungen kann der opsi-client-agent unter umständen seine Verbindung zum Server verlieren. Sie können diese Clients dann nicht mehr verwalten!!!
Damit das Konzept korrekt umgesetzt werden kann, werden spezielle Host-Parameter benötigt. Ich habe dazu die Client-Events von UIB zum Teil deaktiviert (active = false). Anschließend habe ich eine eigene, neue Konfiguration gebaut.
Diese besteht aus folgenden Events (ich habe diese mit dem Kürzel fhg “markiert”):
event_fhg_gui_startup Bei einem normalen Systemstart dient das event dazu eine Verbindung mit dem Server aufzubauen und evtl. eine Produkt Synchronisation zu beginnen. Dieser Vorgang läuft im Hintergrund ab und die Benutzer merken davon nichts.
event_fhg_timer Läuft automatisch alle X Minuten ab und ruft wie gui_startup das event_fhg_sync auf um eventuell anstehende Produkte zu synchronisieren.
event_fhg_sync Wird von gui_startup oder timer aufgerufen und führt die Produktsynchronisation zwischen Client & Server aus.
event_fhg_sync_completed Wenn die Produktsyncronisation erfolgreich abgeschlossen wurde, startet dieses event die Produktinstallation. Ist ein Benutzer angemeldet wird er vor dieser Produktaktion informiert. Wird das PREinstallation Paket ausgeführt wird der Benutzer ebenfalls beim Reboot vorher gefragt.
[event_gui_startup] super = event_fhg_sync type = gui startup name = gui_startup block_login = False active = False [event_gui_startup{user_logged_in}] name = gui_startup shutdown_warning_time = 300 block_login = false active = False [event_gui_startup{cache_ready}] use_cached_config = true use_cached_products = true action_user_cancelable = 3 action_warning_time = 60 active = False [event_gui_startup{installation_pending}] name = gui_startup active = False [event_on_demand] super = default type = custom name = on_demand event_notifier_command = [event_on_demand{user_logged_in}] name = on_demand shutdown_warning_time = 300 action_user_cancelable = 4 shutdown_user_cancelable = 10 [event_software_on_demand] super = default type = sw on demand [event_sync] super = default type = template process_actions = false event_notifier_command = sync_config_to_server = true sync_config_from_server = true cache_products = true cache_dynamic_bandwidth = true [event_timer] super = sync type = timer active = False interval = 60 [event_net_connection] super = sync type = custom active = False wql = SELECT * FROM __InstanceModificationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_NetworkAdapter' AND TargetInstance.NetConnectionStatus = 2 [event_sync_completed] super = default type = sync completed event_notifier_command = process_actions = False get_config_from_service = true write_log_to_service = True active = False post_sync_config_to_server = True [event_sync_completed{cache_ready_user_logged_in}] reboot = False shutdown_user_cancelable = 10 shutdown_warning_time = 300 action_user_cancelable = 3 action_warning_time = 60 super = event_sync_completed active = False [event_sync_completed{cache_ready}] reboot = False active = False [event_user_login] super = default type = user login action_type = login active = False action_message = Starting to process user login actions. action_message[de] = Beginne mit der Verarbeitung der Benutzer-Anmeldungs-Aktionen. action_message[fr] = Traitement des actions à la connexion de l'utilisateur. block_login = false process_shutdown_requests = false get_config_from_service = false update_config_file = false write_log_to_service = false update_action_processor = true event_notifier_command = %opsiclientd_notifier.command% -s notifier\\userlogin.ini event_notifier_desktop = default action_processor_command = %action_processor.command% /sessionid %service_session% /allloginscripts /silent action_processor_desktop = default action_processor_timeout = 300 [event_on_shutdown] super = default type = custom name = on_shutdown active = False [event_on_shutdown{installation_pending}] name = on_shutdown active = False [event_silent_install] super = default type = custom name = silent_install event_notifier_command = process_shutdown_requests = false action_processor_command = %action_processor.command% /productlist %action_processor_productIds% /silent action_processor_desktop = winlogon action_processor_timeout = 300 action_processor_productids = swaudit,hwaudit [event_timer_silentinstall] super = silent_install type = timer active = False interval = 21600 [precondition_user_logged_in] user_logged_in = true [precondition_cache_ready] config_cached = true products_cached = true [precondition_cache_ready_user_logged_in] user_logged_in = true config_cached = true products_cached = true [precondition_installation_pending] installation_pending = true [event_on_demand_ask] super = on_demand [event_on_demand_ask{user_logged_in}] action_user_cancelable = 10 action_warning_time = 60 shutdown_user_cancleable = 10 shutdown_warning_time = 1000 [event_silent] action_processor_command = %action_processor.command% /sessionid %service_session% /silent super = on_demand [event_sync_completed{user_logged_in}] shutdown_user_cancelable = 10 shutdown_warning_time = 2000 action_user_cancelable = 2 action_warning_time = 1000 active = False [event_usercontext] action_processor_command = block_login = False [event_timer{cache_ready_user_logged_in}] super = event_sync_completed process_actions = False action_user_cancelable = 3 action_warning_time = 500 active = False [event_timer{cache_ready}] super = event_sync_completed active = False [event_timer{user_logged_in}] super = event_sync [event_fhg_gui_startup] super = event_fhg_sync type = gui startup block_login = False use_cached_products = True [event_fhg_sync] cache_dynamic_bandwidth = True cache_products = True event_notifier_command = process_actions = False super = default sync_config_from_server = False sync_config_to_server = False type = template [event_fhg_sync_completed] event_notifier_command = get_config_from_service = true process_actions = false super = default type = sync completed use_cached_config = false use_cached_products = false write_log_to_service = True sync_config_to_server = False writelogtoservice = True active = False update_config_file = True [event_fhg_sync_completed{cache_ready_user_logged_in}] action_user_cancelable = 3 action_warning_time = 500 process_actions = True sync_config_to_server = False shutdown_user_cancelable = 10 shutdown_warning_time = 500 [event_fhg_sync_completed{cache_ready}] process_actions = True sync_config_to_server = True [event_fhg_timer] active = True interval = 2000 super = fhg_sync type = timer [event_fhg_timer{cache_ready_user_logged_in}] use_cached_config = False use_cached_products = False user_cached_config = False user_cached_products = False [event_fhg_timer{cache_ready}] active = False super = default