In einem modernen Unternehmen werden häufig serverbasierte Profile und/oder Ordnerumleitungen für die persönlichen, PC-basierten, Daten der BenutzerInnen eingesetzt.
Dieses hat den Vorteil, dass auf den lokalen PCs keine Daten vorhanden sind und somit die Gefahr des Datenverlustes bei Ausfall, Diebstahl, Elementare Gefährdungen, etc. minimiert wird.
Wenn nun allerdings der Umstieg auf Windows 7 ansteht, wird einem bei Tests sehr schnell auffallen, dass die XP Profile nicht mit den W7 Profilen gemischt werden können und man somit, bei Anmeldung an Windows 7, nur ein temporäres Profil zugewiesen bekommt bzw. im schlimmsten Fall das XP Profil zerschiesst.
Dieses Problem tritt auf, da zu einem die Registry (betrifft serverbasierte Profile) andere Einträge aufweist, sowie die Verzeichnisstruktur (z.B. Ordnerumleitungen) seit Windows Vista eine andere ist.
Kurzer Exkurs zu den beiden Möglichkeiten:
Da beide Lösungen jeweils Vor- und Nachteile bieten, sollte genau geprüft werden, welche von beiden genutzt oder wie beide kombiniert werden sollten.
Typisch wird das serverbasierte Profil in Kombination mit Ordnerumleitung von Desktop und Eigene Dateien genutzt, so hat man eine effiziente Lösung mit geringem Impact auf die Datensicherheit und Gesamt Performance
Zurück zum Thema, bei der Umstellung von Windows XP auf Windows 7 gibt es natürlich nicht nur die Profile/persönlichen Daten zu beachten, sondern es gilt auch Dinge zu prüfen, wie z.B.:
In meinem Anwendungsfall kommen keine serverbasierten Profile zum Einsatz, das hat zur Folge, das Daten wie z.B. Favoriten, Wörterbücher, Signaturen (falls nicht automatisiert, siehe dazu meine vorherigen Einträge), Dokumente nur lokal auf den PCs abgelegt werden.
Es gibt nun zwei Wege um dieses "Dilema" zu lösen.
Der eine Weg ist eine organisatorische Lösung, d.h. die BenutzerInnen werden informiert, dass ab sofort alle Daten auf dem Home Laufwerk gespeichert bzw. dort hin verschoben werden sollen, der andere Weg ist eine technische Lösung in Form eines Skripts, dass diese Aufgabe selbstständig erledigt.
Um die größtmögliche Akzeptanz mit Effizienz zu kombinieren, habe ich mich für einen gemischten Weg entschieden, d.h. es gibt eine Dienstanweisung, die sagt, dass alles Zukünftige nur noch auf dem Home-Laufwerk gespeichert werden soll (+ Ordnerumleitungen), sowie zwei Skripte zur Sicherung und Wiederherstellung wurden von mir geschrieben.
Da natürlich, aus Gründen des Datenschutz, kein Zugriff auf die Home-Laufwerke der BenutzerInnen besteht, kommt keine serverbasierte Sicherung der Daten in Frage, sondern eine Lösung, die durch den Benutzer entweder manuell oder automatisch gestartet wird.
Entschieden habe ich mich für die automatische Lösung mit Hilfe des Login-Skripts, somit wird bei Login eine Sicherung der konfigurierten Pfade durchgeführt, Nachteil: die Sicherung kann unvollständig sein. Ich habe mich bewusst für das Login-Skript entschieden, da BenutzerInnen beim Herunterfahren des PCs häufig den Bildschirm als Erstes ausschalten und somit Bildschirmmeldungen nicht mehr sehen können (natürlich wäre auch eine automatisierte E-Mail aus dem Skript heraus möglich, allerdings werden diese auch gern ignoriert..)
Folgende Features unterstützt das Sicherungs-Skript (durch Anpassung der Pfade und der Version kann das Skript auch als normales Sicherungsskript bei PC-Wechsel genutzt werden!):
Hier der Code
Dieses hat den Vorteil, dass auf den lokalen PCs keine Daten vorhanden sind und somit die Gefahr des Datenverlustes bei Ausfall, Diebstahl, Elementare Gefährdungen, etc. minimiert wird.
Wenn nun allerdings der Umstieg auf Windows 7 ansteht, wird einem bei Tests sehr schnell auffallen, dass die XP Profile nicht mit den W7 Profilen gemischt werden können und man somit, bei Anmeldung an Windows 7, nur ein temporäres Profil zugewiesen bekommt bzw. im schlimmsten Fall das XP Profil zerschiesst.
Dieses Problem tritt auf, da zu einem die Registry (betrifft serverbasierte Profile) andere Einträge aufweist, sowie die Verzeichnisstruktur (z.B. Ordnerumleitungen) seit Windows Vista eine andere ist.
Kurzer Exkurs zu den beiden Möglichkeiten:
Serverbasierte Profile
Das serverbasierte Profil beinhaltet das gesamte Profil eines Benutzer-Accounts, inkl. Registry und %USERPROFILE% (genauere Informationen dazu gibt es bei Microsoft und zwar hier). Die Daten werden auf den lokalen PC geschrieben und gelesen, d.h. es findet eine Synchronisation zwischen PC und Server statt.
Vorteil(e):
- Alle Daten sind vollständig auf dem Server => Vermeidung von Datenverlusten
- Alle Daten sind vollständig auf dem Client => Offline Arbeit möglich
- Verzögerung beim Anmelden, da das gesamte Profil vom Server heruntergeladen, also synchronisiert wird, je nach Bandbreite und Auslastung des Servers kann dieses zu unangenehmen Verzögerungen und eingeschränktem Produktionsausfall führen. Beispiel: die Anmeldung dauert 5 Minuten mit einem serverbasierten Profil und 1 Minute mit lokalem Profil, in einem Arbeitsjahr würde sich das Ganze zu 14,7 Stunden summieren und somit pro BenutzerIn zu fast 2 Tagen Produkionsausfall per anno führen würde
- Synchronisation der Daten erst bei Abmeldung, bei Ausfall des PCs sind die letzten Änderungen nicht gesichert, Abmeldung wird ebenfalls verzögert
- Höhere Grundlast auf den Servern/Storage und Netzwerk zu Stoßzeiten (Beginn, Mittagspause, Feierabend)
Ordnerumleitungen
Ordnerumleitungen können über Gruppenrichtlinien konfiguriert werden und bieten eine einfache Möglichkeit zur Umleitung von Ordnern auf andere Systeme, gerne für Ordner wie Eigene Dateien oder Desktop genutzt, damit die Anmeldezeit verringert, aber die Gefährdung durch Datenverlust dennoch minimiert.
Vorteil(e):
- Konfigurierte sind vollständig auf dem Server => Vermeidung von Datenverlusten
- Keine Verzögerung beim An- und Abmelden
- Höhere Grundlast auf den Servern/Storage und Netzwerk, da Live gearbeitet wird
- Keine Offline-Arbeit möglich
Da beide Lösungen jeweils Vor- und Nachteile bieten, sollte genau geprüft werden, welche von beiden genutzt oder wie beide kombiniert werden sollten.
Typisch wird das serverbasierte Profil in Kombination mit Ordnerumleitung von Desktop und Eigene Dateien genutzt, so hat man eine effiziente Lösung mit geringem Impact auf die Datensicherheit und Gesamt Performance
Zurück zum Thema, bei der Umstellung von Windows XP auf Windows 7 gibt es natürlich nicht nur die Profile/persönlichen Daten zu beachten, sondern es gilt auch Dinge zu prüfen, wie z.B.:
- Der wichtigste Punkt: Software-Kompabilität zu Windows 7, inkl. Architektur (Test durch IT, Fachabteilung)
- Upgrade der Domänen-Controller (Achtung, abhängige Authentifizierungsdienste bedenken, z.B. SSPI, NTLMv1) zur Nutzung der neuen GPO Features
- Schulung, Schulung und Schulung => erhöht Akzeptanz der Mitarbeiter, selten gilt: Neu ist immer besser ;-)
- Planung, Planung und Planung: Test, Logistik (Wie, wo, wann und durch wen wird installiert), Rollout (Etagenweise, Abteilungsweise, ...), Transparenz (Was funktioniert wie, Wann passiert was) => Akzeptanz der Mitarbeiter
In meinem Anwendungsfall kommen keine serverbasierten Profile zum Einsatz, das hat zur Folge, das Daten wie z.B. Favoriten, Wörterbücher, Signaturen (falls nicht automatisiert, siehe dazu meine vorherigen Einträge), Dokumente nur lokal auf den PCs abgelegt werden.
Es gibt nun zwei Wege um dieses "Dilema" zu lösen.
Der eine Weg ist eine organisatorische Lösung, d.h. die BenutzerInnen werden informiert, dass ab sofort alle Daten auf dem Home Laufwerk gespeichert bzw. dort hin verschoben werden sollen, der andere Weg ist eine technische Lösung in Form eines Skripts, dass diese Aufgabe selbstständig erledigt.
Um die größtmögliche Akzeptanz mit Effizienz zu kombinieren, habe ich mich für einen gemischten Weg entschieden, d.h. es gibt eine Dienstanweisung, die sagt, dass alles Zukünftige nur noch auf dem Home-Laufwerk gespeichert werden soll (+ Ordnerumleitungen), sowie zwei Skripte zur Sicherung und Wiederherstellung wurden von mir geschrieben.
Da natürlich, aus Gründen des Datenschutz, kein Zugriff auf die Home-Laufwerke der BenutzerInnen besteht, kommt keine serverbasierte Sicherung der Daten in Frage, sondern eine Lösung, die durch den Benutzer entweder manuell oder automatisch gestartet wird.
Entschieden habe ich mich für die automatische Lösung mit Hilfe des Login-Skripts, somit wird bei Login eine Sicherung der konfigurierten Pfade durchgeführt, Nachteil: die Sicherung kann unvollständig sein. Ich habe mich bewusst für das Login-Skript entschieden, da BenutzerInnen beim Herunterfahren des PCs häufig den Bildschirm als Erstes ausschalten und somit Bildschirmmeldungen nicht mehr sehen können (natürlich wäre auch eine automatisierte E-Mail aus dem Skript heraus möglich, allerdings werden diese auch gern ignoriert..)
Folgende Features unterstützt das Sicherungs-Skript (durch Anpassung der Pfade und der Version kann das Skript auch als normales Sicherungsskript bei PC-Wechsel genutzt werden!):
- Außenstandorte werden unterstützt => wenn ein bestimmtes Default Gateway gesetzt ist, wird keine Sicherung durchgeführt
- Konfigurierbares Home-Laufwerk
- Sicherung nur, wenn Betriebssystem Windows XP
- Sicherung nur, wenn Computername ein bestimmtes Muster hat (z.B: PCXP00001)
- Meldung bei Überschreitung der konfigurierbaren Größe
- Rekursive Sicherung von Ordner, bei Ausschluss von Dateien größer als X (z.B. Outlook Ordner ohne pst-file)
- Meldung, wenn Dateien in einem Ordner gefunden werden, die zu Tag X (Datum/Meldung konfigurierbar, abhängig vom Default Gateway) erledigt sein müssen
- Start/Stop von Prozessen
- Error-Handling
- Default Sicherungspfade: Desktop (250 MB), Eigene Dateien (250 MB), Outlook (pst file bis 100 MB), MS Office, OpenOffice (Textbausteine, Wörterbücher)
Hier der Code
'##################################################### ' Sicherungsscript ' Author: Oliver Skibbe oliskibbe (at) gmail.com ' Date: 2013-09-17 '##################################################### ' Constants ' Windows Version Const Win2k = "5.0" Const WinXP = "5.1" Const Win2k3 = "5.2" Const WinVista = "6.0" Const Win7 = "6.1" Const Win2k8 = "6.1" ' Stuff Const Target = "INV" Const HomeDrive = "Z:\" ' max transferred bytes ' 100 MB Const maxDefaultSize = 104857600 ' 250 MB Const maxDesktopSize = 262144000 Const maxOwnFilesSize = 262144000 TargetVersion = WinXP ' Objects Set WshShell = WScript.CreateObject("WScript.Shell") Set objFSO = CreateObject("Scripting.FileSystemObject") Set objWMIService = GetObject("winmgmts:\\localhost\root\cimv2") ' Get Windows Version Set colOperatingSystem = objWMIService.ExecQuery("Select Version from Win32_OperatingSystem") For Each objOperatingSystem In colOperatingSystem Version = objOperatingSystem.Version Next ' Get Default GW Set colNetworkConfiguration = objWMIService.ExecQuery("Select DefaultIPGateway from Win32_NetworkAdapterConfiguration Where IPEnabled = TRUE") For Each objNetworkConfiguration in colNetworkConfiguration If Not IsNull(objNetworkConfiguration.DefaultIPGateway) Then DefaultGateway = Join(objNetworkConfiguration.DefaultIPGateway, ",") End If Next ' Quit if target pc name is not XXX or uses other Version than Windows 7 strComputerName = WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%") If InStr(1, strComputerName, Target, VbTextCompare) = 0 Then WScript.Quit Else ' If computer name is valid, check OS version If Not Mid(Version,1,3) = TargetVersion Then WScript.Quit End If End If ' end check valid target pc ' quit if hannover gw ip => no backup If DefaultGateway = "10.10.1.1" Then Wscript.Quit End If ' quit if Foobar town gw ip => no backup If DefaultGateway = "10.16.1.1" Then Wscript.Quit End If ' Quit if home drive is not available / writable or wrong type CheckDrive(HomeDrive) ' Helper vars strProgramFiles = WshShell.ExpandEnvironmentStrings("%PROGRAMFILES%") strProfileDir = WshShell.ExpandEnvironmentStrings("%USERPROFILE%") strAppDataDir = WshShell.ExpandEnvironmentStrings("%APPDATA%") strLocalDir = strProfileDir + "\Lokale Einstellungen\Anwendungsdaten" ' Source dirs SourceDesktop = strProfileDir & "\Desktop" SourceFavorites = strProfileDir & "\Favoriten" SourceOwnFiles = strProfileDir + "\Eigene Dateien" SourceOOfficeBase = strAppDataDir + "\OpenOffice.org\3\user" SourceRoamingMSOfficeBase = strAppDataDir + "\Microsoft" SourceLocalMSOfficeBase = strLocalDir + "\Microsoft" ' Target dirs TargetBase = HomeDrive + "\Sicherung" TargetDesktop = TargetBase + "\Desktop" TargetOwnFiles = TargetBase + "\Eigene Dateien" TargetFavorites = TargetBase + "\Favoriten" TargetOOffice = TargetBase + "\OpenOffice" TargetRoamingMSOffice = TargetBase + "\Roaming\MSOffice" TargetLocalMSOffice = TargetBase + "\Local\MSOffice" ' create backup folder if not exists If Not objFSO.FolderExists(TargetBase) Then objFSO.CreateFolder TargetBase End If ' End check folder WshShell.Popup "Die Sicherung der eigenen Dateien wurde gestartet", 2 '''' Desktop '''' BackupFolder SourceDesktop, TargetDesktop, "Desktop", maxDesktopSize, False '''' Own files '''' BackupFolder SourceOwnFiles, TargetOwnFiles, "Eigene Dateien", maxOwnFilesSize, False '''' Favorites '''' BackupFolder SourceFavorites, TargetFavorites, "Favoriten", maxDefaultSize, False '''' OpenOffice '''' BackupFolder SourceOOfficeBase + "\autotext", TargetOOffice + "\autotext", "OOffice Textbausteine", maxDefaultSize, False BackupFolder SourceOOfficeBase + "\wordbook", TargetOOffice + "\wordbook", "OOffice Wörterbuch", maxDefaultSize, False '''' Microsoft Office '''' BackupFolder SourceRoamingMSOfficeBase + "\Templates", TargetRoamingMSOffice + "\Templates", "MS Office Templates", maxDefaultSize, False BackupFolder SourceRoamingMSOfficeBase + "\Signatures", TargetRoamingMSOffice + "\Signatures", "MS Office Signatures", maxDefaultSize, False BackupFolder SourceRoamingMSOfficeBase + "\Document Building Blocks", TargetRoamingMSOffice + "\Document Building Blocks", "MS Office Textbausteine", maxDefaultSize, False '''' Outlook folder without pst (via file size) '''' BackupFolderRecursiveExcludeMaxSize SourceRoamingMSOfficeBase + "\Outlook", TargetRoamingMSOffice + "\Outlook", "Outlook", maxDefaultSize, False BackupFolderRecursiveExcludeMaxSize SourceLocalMSOfficeBase + "\Outlook", TargetLocalMSOffice + "\Outlook", "Outlook", maxDefaultSize, False '''' Auftragsdaten '''' ' Message if files are available (could be just in addition to a due time) CheckFileCountInFolder "C:\Auftragsdaten\Daten", "Auftragsdaten", 1 ' Target Size Output Set objFolder = objFSO.GetFolder(TargetBase) ' returns byte TargetSize = objFolder.Size WshShell.Popup "Die Sicherung der eigenen Dateien wurde beendet. Es wurden " + ConvertSize(TargetSize) + " auf Ihr Laufwerk " + HomeDrive + " übertragen", 3 ' End of Main ''' Functions ' control processes Function ProcessControl(proc, state, CheckState) If state = "stop" Then ' stop process cmd = "taskkill.exe /F /IM " + proc Else ' start process cmd = proc End If ' end start / stop state ExitCode = WshShell.run (cmd, 1, true) If CheckState = True Then If ExitCode > 0 Then MsgBox "Fehler beim " + state + " von " + proc, vbCritical WScript.Quit End If ' end exit code End If ' end check state End Function ' Pretty output for bytes Function ConvertSize(Size) Do While InStr(Size,",") CommaLocate = InStr(Size,",") Size = Mid(Size,1,CommaLocate - 1) & _ Mid(Size,CommaLocate + 1,Len(Size) - CommaLocate) Loop Suffix = " B" If Size >= 1024 Then suffix = " KB" If Size >= 1048576 Then suffix = " MB" If Size >= 1073741824 Then suffix = " GB" If Size >= 1099511627776 Then suffix = " TB" Select Case Suffix Case " KB" Size = Round(Size / 1024, 1) Case " MB" Size = Round(Size / 1048576, 1) Case " GB" Size = Round(Size / 1073741824, 1) Case " TB" Size = Round(Size / 1099511627776, 1) End Select ConvertSize = Size & Suffix End Function ' return due dates e.g. till something will be done, see CheckFileCountInFolder Function RolloutDate(DefaultGateway) ' Default Rollout = "Offen" Set objRolloutDates = CreateObject("Scripting.Dictionary") ' Foobar town objRolloutDates.Add "10.16", "05.09" ' Hannover objRolloutDates.Add "10.10", "Offen" For Each RolloutDate In objRolloutDates If InStr(1, DefaultGateway, RolloutDate, VbTextCompare) > 0 Then RolloutDate = objRolloutDates(RolloutDate) Exit Function End If Next End Function ' Copy Folder Function BackupFolder(Source, Target, Label, maxSize, Required) ' check if source exists If objFSO.FolderExists(Source) Then ' create target folder If Not objFSO.FolderExists(Target) Then CreateFolderRecursive Target End If ' End check folder Set objFolder = objFSO.GetFolder(Source) ' returns byte FolderSize = objFolder.Size ' copy if folder size is less than ~XXX Megabyte.. If FolderSize < maxSize Then objFSO.CopyFolder Source, Target Else MsgBox(Label + " ist zu groß: " + ConvertSize(FolderSize) + ". Bitte löschen Sie unnötige Dateien oder verschieben Sie diese auf Ihr Laufwerk H:\. Falls diese Schritte nicht helfen, wenden Sie sich bitte an die Hotline") End If ' end of size Else If Required = True Then MsgBox(Label + " (" + Source + ") wurde nicht gefunden, muss aber vorhanden sein!") WScript.Quit End If End If End Function ' Copy File Function BackupFile(Source, Filename, Target, Label, maxSize, Required) FullPath = Source + "\" + Filename ' check if source exists If objFSO.FileExists(FullPath) Then ' create target folder If Not objFSO.FolderExists(Target) Then CreateFolderRecursive Target End If ' End check folder Set objFile = objFSO.GetFile(FullPath) ' returns byte FileSize = objFile.Size ' copy if folder size is less than ~XXX Megabyte.. If FileSize < maxSize Then objFSO.CopyFile FullPath, Target + "\" + Filename Else MsgBox(Label + " ist zu groß: " + ConvertSize(FileSize) + ". Bitte löschen Sie diese Datei oder verschieben Sie diese auf Ihr Laufwerk H:\. Falls diese Schritte nicht helfen, wenden Sie sich bitte an die Hotline") End If ' end of size Else If Required = True Then MsgBox(Label + " (" + Source + ") wurde nicht gefunden, muss aber vorhanden sein!") WScript.Quit End If End If End Function ' check if x file(s) exist in given path Function CheckFileCountInFolder(Path, Label, maxFiles) FileCount = 0 If objFSO.FolderExists(Path) Then Set objFolder = objFSO.GetFolder(Path) Set colFiles = objFolder.Files For Each objFile In colFiles FileCount = FileCount + 1 Next If maxFiles > 0 And FileCount >= maxFiles Then MsgBox( Cstr(FileCount) + " Datei(en) in " + Label + " vorhanden, bitte bis zum " + Chr(34) + RolloutDate(DefaultGateway) + Chr(34) + " abarbeiten / entfernen oder bei der IT-Hotline melden!") End If End If ' end FileExists End Function ' Copy Folder Function BackupFolderRecursiveExcludeMaxSize(Source, Target, Label, maxSize, Required) ' check if source exists If objFSO.FolderExists(Source) Then ' create target folder If Not objFSO.FolderExists(Target) Then CreateFolderRecursive Target End If ' End check folder Set objFolder = objFSO.GetFolder(Source) Set Files = objFolder.Files For Each File in Files If Not InStr(1, File.Name, "outlook.ost", VbTextCompare) > 0 Then If File.Size < maxSize Then File.Copy(Target + "\" + File.Name) Else MsgBox(Label + " ist zu groß: " + ConvertSize(File.Size) + ". Bitte löschen Sie diese Datei oder verschieben Sie diese auf Ihr Laufwerk H:\. Falls diese Schritte nicht helfen, wenden Sie sich bitte an die Hotline") End If End If Next Else If Required = True Then MsgBox(Label + " (" + Source + ") wurde nicht gefunden, muss aber vorhanden sein!") WScript.Quit End If End If End Function ' Check target drive Function CheckDrive(Drive) If objFSO.DriveExists(Drive) Then Set DriveState = objFSO.GetDrive(Drive) ' Check home drive If Not DriveState.IsReady = True Then ErrorText = "Laufwerk " + Drive + " ist nicht erreichbar, bitte starten Sie den PC neu!" ErrorOccured = True Else ' 0: unkown, 1: Removable, 2: Fixed, 3: Network, 4: CD-Rom, 5: RAM-Disk If Not DriveState.DriveType = 1 And Not DriveState.DriveType = 2 And Not DriveState.DriveType = 3 Then ErrorText = Drive + ": ist kein gültiger Laufwerkstyp, mögliche Typen: Netzwerk, Festplatte, Wechseldatenträger" ErrorOccured = True End If ' end check valid drive type End If Else ErrorText = "Laufwerk " + Drive + " existiert nicht, bitte starten Sie den PC neu!" ErrorOccured = True End If ' End Drive exists If ErrorOccured = True Then MsgBox(ErrorText) WScript.Quit End If End Function Function CreateFolderRecursive(FullPath) Set oFs = WScript.CreateObject("Scripting.FileSystemObject") arr = split(FullPath, "\") path = "" For Each dir In arr If path <> "" Then path = path & "\" path = path & dir If oFs.FolderExists(path) = False Then oFs.CreateFolder(path) Next End Function ' EOF
Das Skript sollte angepasst, getestet und im NETLOGON Verzeichnis abgelegt werden, anschließend kann es im Login-Skript verankert werden und sichert ab diesem Zeitpunkt automatisch bei jeder Anmeldung die Daten.
Zum Download
Bei Fragen bitte melden!
Keine Kommentare:
Kommentar veröffentlichen