Benutzerdefiniertes Update mit Windows SteadyState
Hallo zusammen,
kennt sich hier noch jemand mit SteadyState aus? Das war das Programm von Microsoft, mit dem man unter Windows XP einen PC in den "Kiosk-Modus" versetzen konnte, und mit dem auch ein Festplattenschutz à la HD-Guard, Drive.Keeper usw. möglich war.
Wenn man so einen Festplattenschutz aktiv hat, ist natürlich das Problem, daß Software-Updates (z.B. von Anti-Virus-Programmen) nicht möglich waren bzw. nach dem nächsten Neustart wieder entfernt wurden. SteadyState konnte die Windows-Updates von Haus aus einspielen, für andere Updates konnte man ein Update-Script erstellen und dieses durch SteadyState aufrufen lassen. Dazu startete SteadyState den Rechner zu einem bestimmten Zeitpunkt neu (nur bis zum Anmeldemaske), spielte dann die Updates ein und übernahme die Änderungen dauerhaft.
Ich habe nun einen Präsentationsrechner unter Windows XP laufen, der mit SteadyState geschützt wird. Auf diesem Rechner soll nun auch Avira Professional Security installiert werden. Der Rechner selbst ist zwar durch den Festplattenschutz schon weitgehend gegen Malware geschützt, aber zur Laufzeit könnte natürlich durchaus ein Wurm den Rechner befallen und von dort aus andere Rechner im Netzwerk attackieren.
Nun habe ich ein Update-Script (in VB6) geschrieben und dies als EXE-Datei compiliert, auf dem Rechner hinterlegt und in SteadyState eingebunden, so daß es täglich um 6 Uhr aufgerufen wird. Das Script ruft die Update-Funktion von Avira als Administrator auf und wartet dann, bis die update.exe wieder beendet ist:
Formularmodul
Modul "Funktionen"
Das klappt hervorragend, wenn ich an dem PC angemeldet bin und das Programm manuell starte. Das Update wird dann ordnungsgemäß durchgeführt, ist aber natürlich beim nächsten Reboot wieder weg.
Beim Aufruf über SteadyState schlägt das Script aber fehl. Da ich an verschiedenen Stellen eine Kontrollzeile in eine Protokolldatei (auf eine nicht durch den Festplattenschutz geschützte Partition) schreiben lasse, weiß ich auch wo, nämlich beim Aufruf der Funktion W2KRunAsUser. Die Kontrollzeile, die direkt nach diesem Aufruf geschrieben werden sollte, fehlt bereits.
Hat jemand eine Idee, warum das nicht klappt?
Danke im Voraus,
Sarek
kennt sich hier noch jemand mit SteadyState aus? Das war das Programm von Microsoft, mit dem man unter Windows XP einen PC in den "Kiosk-Modus" versetzen konnte, und mit dem auch ein Festplattenschutz à la HD-Guard, Drive.Keeper usw. möglich war.
Wenn man so einen Festplattenschutz aktiv hat, ist natürlich das Problem, daß Software-Updates (z.B. von Anti-Virus-Programmen) nicht möglich waren bzw. nach dem nächsten Neustart wieder entfernt wurden. SteadyState konnte die Windows-Updates von Haus aus einspielen, für andere Updates konnte man ein Update-Script erstellen und dieses durch SteadyState aufrufen lassen. Dazu startete SteadyState den Rechner zu einem bestimmten Zeitpunkt neu (nur bis zum Anmeldemaske), spielte dann die Updates ein und übernahme die Änderungen dauerhaft.
Ich habe nun einen Präsentationsrechner unter Windows XP laufen, der mit SteadyState geschützt wird. Auf diesem Rechner soll nun auch Avira Professional Security installiert werden. Der Rechner selbst ist zwar durch den Festplattenschutz schon weitgehend gegen Malware geschützt, aber zur Laufzeit könnte natürlich durchaus ein Wurm den Rechner befallen und von dort aus andere Rechner im Netzwerk attackieren.
Nun habe ich ein Update-Script (in VB6) geschrieben und dies als EXE-Datei compiliert, auf dem Rechner hinterlegt und in SteadyState eingebunden, so daß es täglich um 6 Uhr aufgerufen wird. Das Script ruft die Update-Funktion von Avira als Administrator auf und wartet dann, bis die update.exe wieder beendet ist:
Formularmodul
Private Sub Form_Load()
Dim AdminName As String
Dim AdminPassword As String
Dim AdminDomain As String
Dim ExecCommand As String
Dim ExecDirectory As String
Dim ExecOptions As String
Dim CheckEXE As String
AdminName = "Administrator"
AdminPassword = "anzeige"
AdminDomain = "Display"
ExecDirectory = "c:\programme\avira\antivir desktop\"
ExecCommand = "avcenter.exe"
ExecOptions = "/STARTSILENTUPDATE"
CheckEXE = "update.exe"
' Kontrolleintrag ins Log schreiben
Open "d:\avira.log" For Append As 1
Print #1, Format(Now(), "yyyy.mm.dd-HH:MM:SS") & ";Programm gestartet"
Close 1
' Aufruf des Avira Updates als Administrator
Dummy = W2KRunAsUser(AdminName, AdminPassword, AdminDomain, Chr(34) & ExecDirectory & ExecCommand & Chr(34) & " " & ExecOptions, ExecDirectory)
' Kontrolleintrag ins Log schreiben
Open "d:\avira.log" For Append As 1
Print #1, Format(Now(), "yyyy.mm.dd-HH:MM:SS") & ";Aufruf "
Close 1
' Warten bis avcenter.exe die update.exe aufgerufen hat
Do
DoEvents
Loop Until IsEXERunning(CheckEXE) = -1
' Kontrolleintrag ins Log schreiben
Open "d:\avira.log" For Append As 1
Print #1, Format(Now(), "yyyy.mm.dd-HH:MM:SS") & ";update.exe läuft"
Close 1
' Warten bis update.exe durchgelaufen ist
Do
DoEvents
Loop Until IsEXERunning(CheckEXE) <> -1
' Kontrolleintrag ins Log schreiben
Open "d:\avira.log" For Append As 1
Print #1, Format(Now(), "yyyy.mm.dd-HH:MM:SS") & ";Update finished"
Close 1
' Fünf Minuten zuwarten
Start = Timer
Do While Timer < Start + 300
DoEvents
Loop
' Kontrolleintrag ins Log schreiben
Open "d:\avira.log" For Append As 1
Print #1, Format(Now(), "yyyy.mm.dd-HH:MM:SS") & ";Pause finished"
Close 1
' Programm schließen
Dim oForm As Form
For Each oForm In VB.Forms
Unload oForm
Next
End Sub
Modul "Funktionen"
' zunächst die benötigten API-Deklarationen
Private Declare Function CreateToolhelpSnapshot Lib "Kernel32" _
Alias "CreateToolhelp32Snapshot" ( _
ByVal lFlgas As Long, _
ByVal lProcessID As Long) As Long
Private Declare Function ProcessFirst Lib "Kernel32" _
Alias "Process32First" ( _
ByVal hSnapshot As Long, _
uProcess As PROCESSENTRY32) As Long
Private Declare Function ProcessNext Lib "Kernel32" _
Alias "Process32Next" ( _
ByVal hSnapshot As Long, _
uProcess As PROCESSENTRY32) As Long
Private Declare Function LogonUser Lib "advapi32.dll" Alias _
"LogonUserA" _
(ByVal lpszUsername As String, _
ByVal lpszDomain As String, _
ByVal lpszPassword As String, _
ByVal dwLogonType As Long, _
ByVal dwLogonProvider As Long, _
phToken As Long) As Long
Private Declare Function CreateProcessAsUser Lib "advapi32.dll" _
Alias "CreateProcessAsUserA" _
(ByVal hToken As Long, _
ByVal lpApplicationName As Long, _
ByVal lpCommandLine As String, _
ByVal lpProcessAttributes As Long, _
ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, _
ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, _
ByVal lpCurrentDirectory As String, _
lpStartupInfo As STARTUPINFO, _
lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function CreateProcessWithLogonW Lib "advapi32.dll" _
(ByVal lpUsername As String, _
ByVal lpDomain As String, _
ByVal lpPassword As String, _
ByVal dwLogonFlags As Long, _
ByVal lpApplicationName As Long, _
ByVal lpCommandLine As String, _
ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, _
ByVal lpCurrentDirectory As String, _
ByRef lpStartupInfo As STARTUPINFO, _
ByRef lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" _
(ByVal hObject As Long) As Long
Private Declare Function SetErrorMode Lib "kernel32.dll" _
(ByVal uMode As Long) As Long
Private Declare Function GetVersionExA Lib "kernel32.dll" _
(lpVersionInformation As OSVERSIONINFO) As Integer
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwflags As Long
szexeFile As String * MAX_PATH
End Type
Private Type STARTUPINFO
cb As Long
lpReserved As Long ' !!! must be Long for Unicode string
lpDesktop As Long ' !!! must be Long for Unicode string
lpTitle As Long ' !!! must be Long for Unicode string
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwflags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type
Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
Private Const TH32CS_SNAPPROCESS As Long = 2&
Private Const MAX_PATH As Long = 260
Private Const CREATE_DEFAULT_ERROR_MODE = &H4000000
Private Const LOGON_WITH_PROFILE = &H1
Private Const LOGON_NETCREDENTIALS_ONLY = &H2
Private Const LOGON32_LOGON_INTERACTIVE = 2
Private Const LOGON32_PROVIDER_DEFAULT = 0
Private Const VER_PLATFORM_WIN32_NT = &H2
' CreateProcessAsUser() requires that the caller has the following permissions
' Permission Display Name
' ---------------------------------------------------------------
' SE_ASSIGNPRIMARYTOKEN_NAME Replace a process level token
' SE_INCREASE_QUOTA_NAME Increase quotas
Public Function W2KRunAsUser(ByVal UserName As String, _
ByVal Password As String, _
ByVal DomainName As String, _
ByVal CommandLine As String, _
ByVal CurrentDirectory As String) As Long
Dim si As STARTUPINFO
Dim pi As PROCESS_INFORMATION
Dim wUser As String
Dim wDomain As String
Dim wPassword As String
Dim wCommandLine As String
Dim wCurrentDir As String
Dim Result As Long
si.cb = Len(si)
wUser = StrConv(UserName + Chr$(0), vbUnicode)
wDomain = StrConv(DomainName + Chr$(0), vbUnicode)
wPassword = StrConv(Password + Chr$(0), vbUnicode)
wCommandLine = StrConv(CommandLine + Chr$(0), vbUnicode)
wCurrentDir = StrConv(CurrentDirectory + Chr$(0), vbUnicode)
Result = CreateProcessWithLogonW(wUser, wDomain, wPassword, _
LOGON_WITH_PROFILE, 0&, wCommandLine, _
CREATE_DEFAULT_ERROR_MODE, 0&, wCurrentDir, si, pi)
' CreateProcessWithLogonW() does not
If Result <> 0 Then 'Result ist bool Wert.
CloseHandle pi.hThread
CloseHandle pi.hProcess
W2KRunAsUser = 0
Else
W2KRunAsUser = Err.LastDllError
MsgBox "CreateProcessWithLogonW() failed with error " & _
Err.LastDllError, vbExclamation
End If
End Function
' Prüft, ob eine EXE-Datei bereits ausgeführt wird
Public Function IsEXERunning(ByVal sFilename As String) As Long
Dim lSnapshot As Long
Dim uProcess As PROCESSENTRY32
Dim nResult As Long
' "Snapshot" des aktuellen Prozess ermitteln
lSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
If lSnapshot <> 0 Then
uProcess.dwSize = Len(uProcess)
' Ersten Prozess ermitteln
nResult = ProcessFirst(lSnapshot, uProcess)
Do Until nResult = 0
' Prozessliste durchlaufen
If InStr(LCase$(uProcess.szexeFile), LCase$(sFilename)) > 0 Then
' Jepp - EXE gefunden
IsEXERunning = True
Exit Do
End If
' nächster Prozess
nResult = ProcessNext(lSnapshot, uProcess)
Loop
' Handle schliessen
CloseHandle lSnapshot
End If
End Function
Das klappt hervorragend, wenn ich an dem PC angemeldet bin und das Programm manuell starte. Das Update wird dann ordnungsgemäß durchgeführt, ist aber natürlich beim nächsten Reboot wieder weg.
Beim Aufruf über SteadyState schlägt das Script aber fehl. Da ich an verschiedenen Stellen eine Kontrollzeile in eine Protokolldatei (auf eine nicht durch den Festplattenschutz geschützte Partition) schreiben lasse, weiß ich auch wo, nämlich beim Aufruf der Funktion W2KRunAsUser. Die Kontrollzeile, die direkt nach diesem Aufruf geschrieben werden sollte, fehlt bereits.
Hat jemand eine Idee, warum das nicht klappt?
Danke im Voraus,
Sarek
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 220819
Url: https://administrator.de/forum/benutzerdefiniertes-update-mit-windows-steadystate-220819.html
Ausgedruckt am: 10.04.2025 um 04:04 Uhr
2 Kommentare
Neuester Kommentar
Moin.
Kann es wohl sein, dass das ausführende Konto (vermutlich System) gar nicht für runas genutzt werden kann?
Lass die Impersonation doch einmal weg und führ es einfach aus, ohne den Admin anzugeben.
BItte antworte auch noch in dem Update-Thread Konzept für Updates von Firefox, Flash Player usw. unter Benutzerrechten
Kann es wohl sein, dass das ausführende Konto (vermutlich System) gar nicht für runas genutzt werden kann?
Lass die Impersonation doch einmal weg und führ es einfach aus, ohne den Admin anzugeben.
BItte antworte auch noch in dem Update-Thread Konzept für Updates von Firefox, Flash Player usw. unter Benutzerrechten