JumpingProfiles:JPProfileRefresh
Aus znilwiki
Ein Kunde löscht bei Problemen von Mitarbeitern immer die JPUser.dat.
Da wir über die GroupLogin.dat und GroupInit.dat Vorseinstellungen für die Programme verteilen merken die Benutzer davon auch nicht viel, alles startet wie gewohnt.
Nun gabe es aber leider 2 Benutzergruppen die häufiger Probleme hatten - und der Admin dort dementsprechend häufiger deren JPUser.dat gelöscht hat.
Leider konnte ich den Admin nicht davon überzeugen mal eine Ursachenforschung zu betreiben - früher kam es 10 mal im Monat vor, seit JP nur noch 1 mal, da war er schon glücklich.
Diese beiden Benutzergruppen nutzen leider Programme die unmengen an Einstellungen in der Registry machen - Ansichten, welche Spalten in Tabellen angezeigt werden sollen und so weiter.
Da darin viel Arbeit steckt hat der Admin bisher immer die Registry-Schlüssel dieser Anwendung per Hand aus der JPUser.dat kopiert und im Anschluss wieder zurück in die neue JPUser.dat kopiert.
Er bat mich das ganze mal zu vereinfachen - und deshalb gibt es nun die JP_ProfilRefresher.exe
Beschreibung
- Commandline Programm welchen man eine
JPUser.datübergibt - Die
JPUser.datwird geleert, es bleiben also nur noch der Header der Datei übrig - Das Programm liest alle Textdateien auf das Muster JP_ProfilRefresher*.txt passen ein (man beachte den * !)
- Alle in diesen Textdateien aufgeführten Schlüssel werden wieder in die
JPUser.datzurück geschrieben - Eine Kopie der Original
JPUser.datwird alsJPUser.dat.OLDim gleichen Verzeichnis abgelegt
Download
Download: JP_ProfileRefresher.zip
Aufruf
- Kopiert die
JP_ProfilRefresher.exeund dieJP_ProfilRefresher.txtan eine Ort euer wahl - bearbeitet die
JP_ProfilRefresh.txtund fügt dort die Registry-Schlüssel ein die erhalten bleiben sollen, z.B.
HKEY_CURRENT_USER\Software\VB and VBA Program Settings\INPLAST\
- Ein Schlüssel pro Zeile!
- Es wird ein "Text in Text" Vergleich gemacht. Ihr könntet also auch nur
\VB and VBA Program Settings\
- angeben - Nutzung auf eigene Gefahr!
- Es werden nur Schlüssel beachtet - keine Werte! Also nur die "Ordner", nicht die "Dateien"!
- Öffnet eine Eingabeaufforderung
- Aufruf ist
JP_ProfilRefresher.exe JPUser.dat JP_ProfilRefresher.exe \\server\freigabe\testbenutzer\JumpingProfile\JPUser.dat JP_ProfilRefresher.exe D:\Profile\testbenutzer\JumpingProfile\JPUser.dat
- Alternativ könnt Ihr auch eine
JPUser.datper Drag&Drop auf dieJP_ProfilRefresher.exeziehen.<r>
Bequemer Einsatz in der Praxis
In der Praxis betraf es nur einige wenige Benutzer welche diese Sonderbehandlung brauchten ... wie mache es jetzt für den Admin möglichst einfach?
- Erstellt eine Freigabe / Ordner in welcher Ihr folgende Dateien ableget
- Die
JP_ProfilRefresher.exe - Eine
JP_ProfilRefresher-Anwendungsname.txtfür jede Anwendung die eine solche Sonderbehandlung haben soll
- Die
Beispiel:
\\server\freigabe\JP$\JP_ProfileRefresh\ |- JP_ProfileRefresher.exe |- JP_ProfileRefresher-INPLAST.txt +- JP_ProfileRefresher-XAP.txt
Die beiden JP_ProfileRefresher-*.txt> enthalten die jeweiligen Registry-Schlüssel die erhalten bleiben sollen.
In JumpingProfiles haben nun 2 JP-Gruppen:
JP_INPLAST JP_XAP
beide Gruppen bekommen nun eine FileOperation.dat mit folgendem Inhalt (Pfade und Dateiname anpassen!):
============================================================
; File: FileOperation.dat
;============================================================
;
; Comment: File system operation
;
; Format: [<Profile version>:<Environment>]
; #<Element>
; Operation = COPY | CREATE | DELETE
; Event = FIRST | LOGIN | LOGOUT | LAST
; EventScope = GLOBAL | MACHINE | ENVIRONMENT | VERSION
; Replace = NEVER | ALWAYS | LATEST | DATE
; Date = <Date> (YYYY-MM-DD {HH:MM:SS})
; Recursion = ON | OFF
; Source = <Source>
; Destination = <Destination>
; Filter = <Filter>
;
;============================================================
[Header]
JP version = 4.6.0.0
JPManagerCore version = 4.6.0.0
JPManager module version = 4.6.0.0
[DEFAULT]
#Copy JP_ProfileRefresh.exe for Inplast
Operation = COPY
Event = LOGIN
Replace = LATEST
Source = \\server\JP$\JP_ProfileRefresh\JP_ProfileRefresher.exe
Destination = \\server\Profiles$\%USERNAME%\JumpingProfile\
#Copy JP_ProfileRefresh.txt for Inplast
Operation = COPY
Event = LOGIN
Replace = LATEST
Source = \\server\JP$\JP_ProfileRefresh\JP_ProfileRefresher-INPLAST.txt
Destination = \\server\Profiles$\%USERNAME%\JumpingProfile\
Die FileOperation.dat könnt Ihr natürlich auch einfach im JP-Manager erstellen:
- 
Was wird nun passieren?
Wenn sich Benutzer dieser beiden Gruppen anmelden wird diesen die JP_ProfileRefresher.exe sowie die notwendigen Textdateien mit den Schlüsseln in ihr persönliches JumpingProfile Verzeichnis kopiert - also dorthin wo auch schon die JPUser.dat liegt.
Nach eine Anmeldung sieht es in dem Verzeichnis also z.B. so aus:
Wenn der Admin nun die JPUser.dat löschen will, sieht er die vorhandene JP_ProfileRefresher.exe.
Und dann zieht er die Datei JPUser.dat einfach per Drag&Drop auf die JP_ProfileRefresher.exe -> Fertig!
Ergebnis:
Das ganze kann man auch hier einbauen: JPProfileReset - Benutzer kann selbst sein Profil zurück setzen
Das Skript was wir dort verwenden hat den eventuellen Aufruf der JP_ProfileRefresher.exe bereits eingbaut.
Da eine Sicherheitskopie mit der Endung .OLD angelegt wird kann JPProfileReset sogar den Ursprungszustand wieder herstellen.
Quellcode JP_ProfileRefresher
Wieder einmal in AutoIt geschrieben:
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=Icon256-32.ico
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_Description=Oktober 2014 Bernhard Linz
#AutoIt3Wrapper_Res_Fileversion=1.0.2.25
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_Language=1031
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <array.au3>
#Include <string.au3>
Opt('MustDeclareVars', 1)
Dim $sFilename ; Dateiname inklusive Pfad zur JPUser.dat
Dim $aJPProfileRefresherLines[1] ; Hier stehen die Zeilen aus den JP_ProfileRefresher*.txt drin
Dim $hJPProfileRefresherTXT ; Zeiger auf die JP_ProfileRefresher*.txt
Dim $hJPProfileRefresherTXTSearch ; Suchzeiger auf alle JP_ProfileRefresher*.txt Dateien im aktuellen Verzeichnis
Dim $sJPProfileRefresherFile ; Konkrete Dateinamen der gefundenen JP_ProfileRefresher*.txt Dateien
Dim $sTempLine ; die eingelesenen Zeilen werden hier temporär gespeichert
Dim $bReadTheLines = False ; Boolean - wird zum Leerzeilen überspringen genutzt
Dim $hSourceFile ; Zeiger auf die JPUser.dat
Dim $hTargetFile ; Zeiger auf die neue Version der JPUser.dat
Dim $bWriteToTarget ; Boolean - wenn False werden die eingelesenden Zeilen nicht geschrieben
Dim $iTimerstart ; Startzeit der Filterung
Dim $iTimerend ; Endzeit der Filterung
Dim $iLineCounter = 0 ; Zeilenzählen - als Status geben wir alle 100 Zeilen einen Punkt aus
; 10 20 30 40 50 60 70 80
; 12345678901234567890123456789012345678901234567890123456789012345678901234567890
Dim $sHelp = '+------------------------------------------------------------------------------' & @CRLF & _
'| JP_ProfileRefresher.exe - Version ' & FileGetVersion(@ScriptName) & @CRLF & _
'+------------------------------------------------------------------------------' & @CRLF & _
'| 2014 von Bernhard Linz für http://znil.net - Kontakt: Bernhard@znil.net' & @CRLF & _
'+------------------------------------------------------------------------------' & @CRLF & _
@CRLF & _
'Vorgeschichte:' & @CRLF & _
'--------------' & @CRLF & _
'Dient dazu eine JPUser.dat in einen "Fast wie gelöscht" Zustand zu bringen' & @CRLF & _
'Hntergund ist das die 99% Universallösung bei Problemen das Löschen oder' & @CRLF & _
'Umbenennen der JPUser.dat ist - wenn der Benutzer sich etwas verkonfiguriert' & @CRLF & _
'hat oder ähnliches (Die Admins löschen eigentlich viel zu schnell, aber macht' & @CRLF & _
'die Sache schön einfach).' & @CRLF & _
'Schlecht ist wenn eine Anwendung mehrere hundert bis tausend Schlüssel für die' & @CRLF & _
'vom Benutzer gemachten Einstellungen speichert wie Sortierfolge, Spaltenbreiten' & @CRLF & _
'oder auch Ansichten etc. - diese muss er dann nämlich alle wieder neu machen' & @CRLF & _
'sofern die Einstellungen nicht einfach per GroupInit.dat vorgegeben werden' & @CRLF & _
'können (was die bessere Lösung wäre aber beim Kunden nicht in Frage kam' & @CRLF & _
'-------------------------------------------------------------------------------' & @CRLF & _
@CRLF & _
'Funktionsweise:' & @CRLF & _
'---------------' & @CRLF & _
'Statt die ganze JPUser.dat einfach zu löschen, filtern wir nur alle Schlüssel' & @CRLF & _
'aus - bis auf diejenigen die erhalten bleiben sollen - Ähnlich der Funktion der' & @CRLF & _
'FadeOut.dat, nur umgekehrt - wir geben an welche Schlüssel noch übrig bleiben' & @CRLF & _
'statt der Schlüssel die gelöscht werden sollen. Quelle ist eine'& @CRLF & _
' JP_ProfileRefresher.txt' & @CRLF & _
'im gleichen Verzeichnis wie dieses Script. In dieser Textdatei steht pro Zeile' & @CRLF & _
'ein Registry-Schlüssel der erhalten werden soll. (Schlüssel, nicht Werte =' & @CRLF & _
'"Verzeichnisse, nicht Dateien!")' & @CRLF & _
'Alternativ sind auch mehrere Quellen möglich, deren Name muss aber jeweils mit' & @CRLF & _
'"JP_ProfileRefresher" beginnen und mit ".txt" enden, z.B.' & @CRLF & _
'JP_ProfileRefresher-XAP.txt und JP_ProfileRefresher-INPLAST.txt -> beide Dateien' & @CRLF & _
'werden eingelesen und berücktsichtigt! Die Anzahl ist nicht begrenzt.' & @CRLF & _
'-------------------------------------------------------------------------------' & @CRLF & _
@CRLF & _
'Aufruf:' & @CRLF & _
'-------' & @CRLF & _
@ScriptName & ' [Pfad][Dateinname]' & @CRLF & _
@CRLF & _
'Beispiel:' & @CRLF & _
@ScriptName & ' D:\Profiles\Benutzer\JumpingProfile\JPUser.dat' & @CRLF & _
@CRLF & _
'Beispiel für eine Batchverarbeitung: (Forfiles ist in jedem Windows enthalten)' & @CRLF & _
@CRLF & _
'Forfiles /P "D:\PF" /S /M JPUser.dat /C "cmd /c D:\JP_ProfileRefresher.exe @path"' & @CRLF & _
@CRLF & _
' "D:\PF" steht für den Pfad zu den Benutzerprofilen, Forfiles kann nicht mit' & @CRLF & _
' UNC Pfaden umgehen (ggf. als Netzlaufwerk mounten)' & @CRLF & _
@CRLF & _
' Das Beispiel verarbeitet alle JPUser.dat in allen Verzeichnissen' & @CRLF & _
' unterhalb von "D:\PF"' & @CRLF & _
@CRLF & _
'+------------------------------------------------------------------------------' & @CRLF & _
'| JP_ProfileRefresher.exe ist FREEWARE! Kopieren, weitergeben ausdrücklich erlaubt!' & @CRLF & _
'| Die jeweils aktuelleste Version und Anleitungen findet Ihr unter:' & @CRLF & _
'| http://znil.net/index.php?title=ZnilTools:JP_ProfileRefresher.exe' & @CRLF & _
'+------------------------------------------------------------------------------' & @CRLF
; Prüfen ob ein Parameter angegeben wurde - sonst beenden
If $CmdLine[0] = 0 Then
ConsoleWrite(_ANSI2OEM("FEHLER - Keine Datei angegeben, /? für Hilfe" & @CRLF))
Exit 0
EndIf
;Prüfen ob wir die Hilfe ausgeben sollen
If $CmdLine[1] = "/?" Then
ConsoleWrite(_ANSI2OEM($sHelp))
Exit 0
EndIf
; Holen wir uns den Dateinamen - oder was auch immer da steht
$sFilename = $CmdLine[1]
ConsoleWrite("STATUS - Verarbeite Datei " & $sFilename)
ConsoleWrite(@CRLF & "=> JP_ProfileRefresher => 2014 znil.net <=" & @CRLF)
; Holen wir uns die Schlüssel die ausgefiltert werden sollen
ConsoleWrite("STATUS - Lese JP_ProfileRefresher.txt Dateien ein .....")
;$hJPProfileRefresherTXTSearch = FileFindFirstFile(@ScriptDir & "\JP_ProfileRefresher*.txt")
;while 1
; $hJPProfileRefresherTXT = FileFindNextFile($hJPProfileRefresherTXTSearch)
; If @error Then ExitLoop
; MsgBox(0,"",$hJPProfileRefresherTXT)
;WEnd
;Exit
$aJPProfileRefresherLines[0] = 0
$hJPProfileRefresherTXTSearch = FileFindFirstFile(@ScriptDir & "\JP_ProfileRefresher*.txt")
While 1
$sJPProfileRefresherFile = FileFindNextFile($hJPProfileRefresherTXTSearch)
If @error Then ExitLoop
ConsoleWrite(_ANSI2OEM("Lese Datei ein: " & $sJPProfileRefresherFile) & @CRLF)
$hJPProfileRefresherTXT = FileOpen(@ScriptDir & "\" & $sJPProfileRefresherFile,0)
If $hJPProfileRefresherTXT = -1 Then
ConsoleWrite(_ANSI2OEM("FEHLER - Konnte " & $sJPProfileRefresherFile & " nicht öffnen") & @CRLF)
Exit 1
EndIf
While 1
$sTempLine = FileReadLine($hJPProfileRefresherTXT)
If @error <> -1 Then
If $sTempLine <> "" Then
$aJPProfileRefresherLines[0] = $aJPProfileRefresherLines[0] + 1
_ArrayAdd($aJPProfileRefresherLines,$sTempLine)
EndIf
Else
ExitLoop
EndIf
WEnd
FileClose($hJPProfileRefresherTXT)
ConsoleWrite(_ANSI2OEM("fertig (Es snd nun " & $aJPProfileRefresherLines[0] & " Einträge insgesamt)" & @CRLF))
WEnd
; Filtern!
ConsoleWrite("STATUS - Filtere Datei ")
$iTimerstart = TimerInit()
$hSourceFile = FileOpen($sFilename,0)
If $hSourceFile = -1 Then
ConsoleWrite(_ANSI2OEM(@CRLF & "FEHLER - Konnte " & $sFilename & "nicht öffnen" & @CRLF))
Exit 1
EndIf
$hTargetFile = FileOpen($sFilename & ".temp.txt",2)
$bWriteToTarget = True
While 1
$sTempLine = FileReadLine($hSourceFile)
If @error <> -1 Then ;123456789012345678
If StringLeft($sTempLine,18) = "HKEY_CURRENT_USER\" Then
$bWriteToTarget = False
EndIf
If $bWriteToTarget = False Then
For $i = 1 To $aJPProfileRefresherLines[0]
If StringInStr($sTempLine,$aJPProfileRefresherLines[$i]) > 0 Then
$bWriteToTarget = True
EndIf
Next
EndIf
If $bWriteToTarget = True Then
FileWriteLine($hTargetFile,$sTempLine)
EndIf
$iLineCounter = $iLineCounter + 1
If $iLineCounter > 99 Then
ConsoleWrite(".")
$iLineCounter = 0
EndIf
Else
ExitLoop
EndIf
WEnd
FileClose($hSourceFile)
FileClose($hTargetFile)
$iTimerend = TimerDiff($iTimerstart) / 1000
ConsoleWrite(" fertig, Laufzeit " & StringRegExpReplace($iTimerend,"(\d*)\.(\d{2})(\d*)","$1,$2") & " sec" & @CRLF)
ConsoleWrite(_ANSI2OEM("Lösche eventuell vorhandene JPUser.dat.OLD") & @CRLF)
FileDelete($sFilename & ".OLD")
ConsoleWrite("Tausche JPUser.dat aus ....")
FileMove($sFilename, $sFilename & ".OLD",1)
FileMove($sFilename & ".temp.txt",$sFilename,1)
ConsoleWrite("fertig" & @CRLF & @CRLF)
Exit 0
; ###################################################################################
; _ANSI2OEM löst das Problem mit dem Umlauten und anderen Sonderzeichen. Es wandelt Text so um das er korrekt in der DOS-Box dargestellt wird
; So können hier im Quellcode auch Umlaute verwendet werden (in den Textausgaben) und diese werden dann korrekt dargestellt
; Dank an Xenobiologist von AutoIt.de für diese Lösung: http://www.autoit.de/index.php?page=Thread&threadID=9461&highlight=ANSI2OEM
Func _ANSI2OEM($text)
$text = DllCall('user32.dll', 'Int', 'CharToOem', 'str', $text, 'str', '')
Return $text[2]
EndFunc ;==>_ANSI2OEM


