סדר בפרופילים

20 ביולי 2008

תגיות:
תגובה אחת

דרך מעניינת לעשות סדר בפרופילים, להמיר את ה Roaming Profiles למאין שילוב של Roaming Profile ו- Redirection של תיקיות מסוימות. המטרה של כל העניין היא להפעיל quota על הנתונים שנשמרים ע"י המשתמשים בעבודת על גבי חוות ה Citrix\TS.

מצב קיים

כל המשתמשים עובדים עם Roaming Profile היושב על גבי ה storage המרכזי של הארגון (netapp), אין מחיקת פרופילים ביציאה ואין הגבלה על גודל הפרופיל.

הבעיה

הפרופילים גודלים בלי שליטה. נעשה נסיון להפעיל את ההגדרה של Limit Profile Size ב GPO, אבל ההגדרה דרך ה GPO היא בעיתית, ואני אסביר.
ניקח לדוגמא שהגבלתי את הפרופילים ל 10mb, כל עוד הוא ב session, המשתמש יוכל להוסיף לפרופיל שלו כל כמות מידע שהוא רק רוצה, הוא רק  ייקבל הודעה כאשר הוא יחרוג מההגבלה הנ"ל, בנוסף לכך, הוא לא יהיה מסוגל לעשות logoff מה session כל עוד הוא עובר את ההגבלה. אבל, יש כאן דרך להתחכמות (וכידוע לכולנו, המשתמשים רכשו לעצמם שם לא רע בתחום הזה עם השנים), נגיד ובאמת המשתמש רושם לפרופיל שלו מעבר להגבלה שמוגדרת לו ב GPO – למשל מעתיק קובץ של 40mb ל Desktop – הוא באמת יקבל הודעה שהוא חרג מההגבלה שלו וכמובן שלא יהיה מסוגל לבצע logoff, אבל הוא כן יוכל לעשות disconnect מה session שלו, לחכות את פרק הזמן שבו ה session ינותק מהשרת ולהכנס בחזרה. כמובן שהפרופיל שלו יכיל את כל המידע (כולל המידע מעבר להגבלה) והוא יוכל לכתוב עוד חומר נוסף, ולחזור כמובן על הקומבינה בפעם הבאה.
אבל אם נעזוב לרגע את זה שאפשר לאכוף את ההגבלה, מה שיותר מפריע זה שכל עוד המשתמש נמצא ב session הוא יכול לכתוב כמה שהוא רק רוצה לתיקיית הפרופיל שלו. כאמור, זה רק מתריע ומונע logoff.

הגדרת הפיתרון

לאחר מחשבה מעמיקה (אני רוצה refill לוויינשטפן בבקשה) החלטנו לפצל את הפרופיל לשני חלקים מרכזיים. Desktop, My Documents, Favorites, Cookies, אותן תיקיות שלמשתמש יש אינטרקציה ישירה איתן, כלומר, כל הכתיבות לתיקיות הנ"ל נעשות ע"י המשתמש ולא ע"י תהליכים השקופים לו (טוב נו, חוץ מה Cookies). אותן ארבעת התיקיות ישבו ב share משלהם על גבי ה storage בו יוגדר quota (ב netapp) ויהיו מוגדרות ב redirection לפרופיל, ישבו ב netapp\ctx_redirect\\. תצורה זו לא תאפשר למשתמש לחרוג מהגדרת ה quota שלו גם אם הוא ב session.
כל שאר חלקי הפרופיל (application data, ntuser.dat וכו') ימשיכו לעבוד כ roaming profile (אשר קטן בצורה דרסטית עקב ה redirection של ארבעת התיקיות הנ"ל) במקום חדש, netapp\ctx_profiles\\.

מה תכלס עשינו

במצב ההתחלתי כל ה Roaming profiles ישבו ב Share הבא: netapp\ctx_profiles\\ ומתחת ישבו התיקיות של כל משתמש. כמובן, שהיסטורית סרר שם בלגן לא קטן (פרופילים ישנים, גדולים מדי, דפוקים ועוד).
כדי להגדיר את חלוקת הפרופיל לתצורה החדשה, הגדרנו את ההגדרות הבאות ב GPO (יצרנו חדש, אשר יכיל רק את ההגדרות האלה):

User Configuration–>Windows Settings–>Folder Redirection
כאמור, מיפוי של Desktop ו- My Documents ל- netapp\ctx_redirect\username\\.

מכיוון שתיקיית Favorites ו- Cookies לא כלולות בתיקיות הניתנות ל redirection ב default הינו צריכים להוסיף Policy Template בו הוספנו את התיקיות Cookies ו- Favorites:

CLASS USER
   CATEGORY "Citrix Redirection"
   CATEGORY "System"
    POLICY "+ User Shell Folders"
            KEYNAME "Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders"
             PART "————————————————————————–" TEXT
            END PART

            PART "Cookies" EDITTEXT
                VALUENAME "Cookies"
                DEFAULT "%USERPROFILE%\Cookies"
                REQUIRED
                #if VERSION >= 2
                EXPANDABLETEXT
                #endif
            END PART

            PART "Favorites" EDITTEXT
                VALUENAME "Favorites"
                DEFAULT "%USERPROFILE%\Favorites"
                REQUIRED
                #if VERSION >= 2
                EXPANDABLETEXT
                #endif
            END PART

     END POLICY ; + User Shell Folders
   END CATEGORY ; System
END CATEGORY ; Citrix Extension

כמובן, שגם התי התיקיות האלה הופנו ל netapp\ctx_redirect\username\\.

את הקישור לתיקיית ה Roaming Profiles החדשה עשינו ע"י הפוליסי הבא:

Computer Configuration–>Administrative Templates–>Windows Components–>Terminal Services–>Set path for TS Roaming Profiles: \\netapp\ctx_profiles\username

מכיוון שרצינו מעבר חלק של המשתמשים בין התצורה הישנה (Roaming profile פשוט) לתצורה החדשה (שילוב של Redirection ו- Roaming profile) הינו צריכים להעתיק את התיקיות הרלוונטיות מה Roaming Profile הקיים לתיקיות החדשות, כאמור, Desktop, Favorites, Cookies, My Documents ל- netapp\ctx_redirect\username\\ וכל שאר הפרופיל ל- netapp\ctx_profiles\username\\.
כל זה נעשה ע"י הסקריפט הבא:

 

<package>
            <job id="Sessions">
                        <comment>
                        </comment>
                        <runtime>
                                    <description>
                                    </description>
                                    <example>
                    </example>
                        </runtime>
                        <reference object="MetaFrameCOM.MetaFrameFarm"/>
                        <script language="VBScript">
           Dim theFarm, aSession, SessionState, users

            SessionState = Array("Unknown", _
                                 "Active", _
                                 "Connected", _
                                 "Connecting", _
                                 "Shadowing", _
                                 "Disconnected", _
                                 "Idle", _
                                 "Listening", _
                                 "Resetting", _
                                 "Down", _
                                 "Init")

            '
            ' Create MetaFrameFarm object
            '
                Set fs = WScript.CreateObject("Scripting.filesystemobject")
                Set users = fs.opentextfile("c:\users.txt",1)

            Set theFarm = CreateObject("MetaFrameCOM.MetaFrameFarm")
            if Err.Number <> 0 Then
                WScript.Echo "Can't create MetaFrameFarm object"
                WScript.Echo "(" & Err.Number & ") " & Err.Description
                WScript.Echo ""
                WScript.Quit Err.Number
            End if

            '
            ' Initialize the farm object.
            '

            theFarm.Initialize(MetaFrameWinFarmObject)
            if Err.Number <> 0 Then
                WScript.Echo "Can't  Initialize MetaFrameFarm object"
                WScript.Echo "(" & Err.Number & ") " & Err.Description
                WScript.Echo ""
                WScript.Quit Err.Number
            End if

            '
            ' Are you Citrix Administrator?
            '

            if theFarm.WinFarmObject.IsCitrixAdministrator = 0 then
                WScript.Echo "You must be a Citrix admin to run this script"
                WScript.Echo ""
                WScript.Quit 0
            End If

            '
            ' Print out the farm name.
            '

            WScript.Echo "MetaFrame Farm Name: " & theFarm.FarmName
            WScript.Echo ""

            '
            ' Display all sessions in the farm.
            '

            WScript.Echo "All sessions in the farm (" & Now & ")"
            WScript.Echo "————————————————"

                Do
                b_temp = false             
                u_temp = users.ReadLine
                For Each aSession In theFarm.Sessions

                if Err.Number <> 0 Then
                    WScript.Echo "Can't enumerate sessions"
                    WScript.Echo "(" & Err.Number & ") " & Err.Description
                    WScript.Echo ""
                    WScript.Quit Err.Number
                End if        

                                                If u_temp = aSession.username Then
                                                            b_temp = True
                                                End if
            Next
        If not b_temp Then
            wscript.echo u_temp & " are not logged in"
            Call Find_folder(u_temp)
                                    'Return = WshShell.Run(ROBO, 0, true)
        End If
        loop While users.AtEndOfStream <> true


Function Find_folder (user)
            Set fs = WScript.CreateObject("Scripting.filesystemobject")
            Set objFolder = fs.GetFolder("\\netapp\ctx_profiles\")
            Set colSubfolders = objFolder.Subfolders
            Set WshShell = WScript.CreateObject("WScript.Shell")
            For Each objSubfolder In colSubfolders

                        If InStr(objSubfolder.name, user)And NOT InStr(objSubfolder.name, (user & ".TESTDOMAIN")) Then
                                    date1 = objSubfolder.DateLastModified
                                    folder1 = objSubfolder.name
                                    'WScript.echo objSubfolder.name & "  "  & objSubfolder.DateLastModified
                                    'WScript.Echo InStr(objSubfolder.name, user)
                        End If
                        If InStr(objSubfolder.name, (user & ".TESTDOMAIN")) = 1 Then
                                    date2 = objSubfolder.DateLastModified
                                    folder2 = objSubfolder.name
                                    'WScript.echo " blabla " & objSubfolder.name & "  "  & objSubfolder.DateLastModified
                                    'WScript.Echo InStr(objSubfolder.name, (user & ".TESTDOMAIN"))
                        End If
            Next
            If date1>date2 Then
                        WScript.Echo user & "  " & date1 & "without TESTDOMAIN"
                        rob = "c:\robocopy.exe \\netapp\ctx_profiles\" & folder1 & " \\netapp\ctx_profiles\" & user & ".TESTDOMAIN /E /SEC /XD dirs desktop Favorites ""My Documents"" Cookies"
                        return = WshShell.run(rob , 0, True)
                        return = WshShell.run("c:\robocopy.exe \\netapp\ctx_profiles\" & folder1 & "\Desktop \\netapp\ctx_riderect\" & user & ".TESTDOMAIN\Desktop /E /COPYALL" , 0, True)
                        return = WshShell.run("c:\robocopy.exe \\netapp\ctx_profiles\" & folder1 & "\Favorites \\netapp\ctx_riderect\" & user & ".TESTDOMAIN\Favorites /E /COPYALL" , 0, True)
                        return = WshShell.run("c:\robocopy.exe \\netapp\ctx_profiles\" & folder1 & "\Cookies \\netapp\ctx_riderect\" & user & ".TESTDOMAIN\Cookies /E /COPYALL" , 0, True)
                        return = WshShell.run("c:\robocopy.exe ""\\netapp\ctx_profiles\" & folder1 & "\My Documents"" ""\\netapp\ctx_riderect\" & user & ".TESTDOMAIN\My Documents"" /E /COPYALL" , 0, True)
            End If
            If date2>date1 Then
                        WScript.Echo user & "  " &  date2 & " TESTDOMAIN"
                        rob = "c:\robocopy.exe \\netapp\ctx_profiles\" & folder2 & " \\netapp\ctx_profiles\" & user & ".TESTDOMAIN /E /COPYALL /XD dirs desktop Favorites ""My Documents"" Cookies"
                        return = WshShell.run(rob , 0, True)
                        return = WshShell.run("c:\robocopy.exe \\netapp\ctx_profiles\" & folder2 & "\Desktop \\netapp\ctx_riderect\" & user & ".TESTDOMAIN\Desktop /E /COPYALL" , 0, True)
                        return = WshShell.run("c:\robocopy.exe \\netapp\ctx_profiles\" & folder2 & "\Favorites \\netapp\ctx_riderect\" & user & ".TESTDOMAIN\Favorites /E /COPYALL" , 0, True)
                        return = WshShell.run("c:\robocopy.exe \\netapp\ctx_profiles\" & folder2 & "\Cookies \\netapp\ctx_riderect\" & user & ".TESTDOMAIN\Cookies /E /COPYALL" , 0, True)
                        return = WshShell.run("c:\robocopy.exe ""\\netapp\ctx_profiles\" & folder2 & "\My Documents"" ""\\netapp\ctx_riderect\" & user & ".TESTDOMAIN\My Documents"" /E /COPYALL" , 0, True)
            End If
End Function
                        </script>
            </job>
</package>

 

הסבר קצר על מה קורה כאן בכלל, הסקריפט עובר על כל השורות בקובץ users.txt המכיל את המשתמשים אשר עשו logoff מהחווה.
כל משתמש הרשום בקובץ נבדק האם הוא כרגע נמצא ב login בחווה, אם לא, נעשת העתקה של התיקיות המדוברות למיקומים החדשים. לא מבוצעת שום העתקה אם המשתמש ב login.
מכיוון שחלק מהמשתמשים מחזיקים ב Roaming Profile עם סיומת שם הדומיין (כל אלה שקיבלו את ההגדרה מה GPO) וחלק בלי סיומת (כאלה שמקבלים את ההגדרה מה AD) הינו צריכים למצוא את הפרופיל המעודכן ביותר (בגלל זה ההשוואה בין date1 לבין date2).

אחרי פעולת הסקריפט, הנתיבים החדשים יהיו מעודכנים עם הנתונים הרלוונטיים של המשתמשים, מה שיאפשר החלפה חלקה של ה GPO לתצורה החדשה.

*תודה למושי על ההשקעה.

 

הוסף תגובה
facebook linkedin twitter email

להגיב על ג'וני לבטל

האימייל לא יוצג באתר. שדות החובה מסומנים *

תגובה אחת