Aktionen

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


1 Beschreibung

  • Commandline Programm welchen man eine JPUser.dat übergibt
  • Die JPUser.dat wird 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.dat zurück geschrieben
  • Eine Kopie der Original JPUser.dat wird als JPUser.dat.OLD im gleichen Verzeichnis abgelegt




2 Download

Download: JP_ProfileRefresher.zip



3 Aufruf

  • Kopiert die JP_ProfilRefresher.exe und die JP_ProfilRefresher.txt an eine Ort euer wahl
  • bearbeitet die JP_ProfilRefresh.txt und 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.dat per Drag&Drop auf die JP_ProfilRefresher.exe ziehen.<r>




4 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.txt für jede Anwendung die eine solche Sonderbehandlung haben soll

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:
JPProfileRefresher-001.png - JPProfileRefresher-002.png


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:

JPProfileRefresher-003.png


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:

JPProfileRefresher-004.png


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.



5 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




6 Kommentare


Kommentar hinzufügen
znilwiki freut sich über alle Kommentare. Sofern du nicht anonym bleiben möchtest, trage deinen Namen oder deine Email-Adresse ein oder melde dich an. Du kannst das Feld auch einfach leer lassen.