שמרו על VPN של Windows פעיל: הפעילו rasdial באירוע הניתוק
RasClient 20226 ו-20227 מסמנים נפילה; 631 פירושו שאדם עשה זאת. הפעילו rasdial בשני הראשונים, שמרו הרשאה אחת, וקראו את קוד היציאה.
Windows אינה מספקת מדיניות חיוג חוזר ללקוח ה-VPN שלה, ולכן חיבור שנופל בחצות עדיין למטה בארוחת הבוקר. משימה מתוזמנת שעוקבת אחרי הניתוק ומריצה rasdial סוגרת את הפער הזה בלי לקוח של צד שלישי. אם המשימה מתנהגת כמו מפעיל או כמו לולאה תלוי בשלושה פרטים: אילו אירועים היא מתאימה, איזו הרשאה היא יכולה לראות, ומה היא עושה עם התוצאה. אף אחד מהשלושה אינו קשה, והחמצה של כל אחד מהם היא מה שמייצר משימה שמחייגת לנצח.
למה טיימר הוא הטריגר הלא נכון
טיימר מחייג לפי לוח הזמנים שלו, בין אם המנהרה למטה ובין אם לא. זה מייצר ניסיונות שאיש לא היה צריך, וניסיון במהלך הפעלה של עבודה יכול להפריע לה. טריגר אירוע נורה רק כשהחיבור משנה מצב, וזה זול יותר וקל יותר לנימוק. האירוע נושא גם את הסיבה, והסיבה היא מה שמפריד בין כשל רשת לבין אדם שמתנתק בכוונה.
ההבחנה הזו היא ההבדל בין משימה מועילה לבין כזו שנאבקת במשתמש כל ערב. זה גם החלק שבדרך כלל חסר במתכונים שמתארים רק את הפעולה.
צמד האירועים, וזה שצריך לדכא
לקוח שירות הגישה מרחוק כותב רשומות מחזור חיים ליומן Application תחת הספק RasClient. 20226 מסמן חיבור שהסתיים, ו-20227 מסמן ניסיון שנכשל, כך שכל אחד מהם יכול להצדיק חיוג חדש. כל השאר במשימה תלוי בהתאמה מדויקת של שני המזהים האלה. הם יציבים כבר שנים, ולכן מתכונים שנבנו עליהם עדיין מסתובבים, אבל בנייה שמשנה את שם הספק או את המזהים גורמת לשאילתה להחזיר כלום. הרץ שוב את שלב ההוכחה אחרי כל עדכון תכונה במקום לחכות שהמשימה תפסיק להידלק.
יש סיום אחד שצריך להחריג. שגיאה 631 פירושה שהמשתמש ניתק את היציאה, וחיוג חוזר באותו רגע נאבק באדם שזה עתה החליף רשת בכוונה. שים את ההחרגה במסנן הטריגר ולא בסקריפט, כדי שהמשימה לא תתחיל בכלל. היא חייבת לחול על מזהה אירוע אחד בלבד, כי פרדיקט EventData מתאים רק כשהאלמנט הנקוב קיים, וסעיף משותף היה מפיל בשקט כל אירוע של המזהה האחר. קרא את שם האלמנט מרשומה אמיתית לפני שכותבים את המסנן:
Get-WinEvent -LogName Application -MaxEvents 5 -FilterXPath "*[System[Provider[@Name='RasClient'] and EventID=20226]]" | Select-Object -First 1 -ExpandProperty ToXml
ה-XML מציג את שמות ה-Data המדויקים ברשומה הזו. ErrorCode הוא האיות הרגיל, ורשומה שמשתמשת במשהו אחר דורשת החלפה של השם הזה במסנן שלמטה.
<QueryList><Query Id="0" Path="Application"><Select Path="Application">*[System[Provider[@Name='RasClient'] and (EventID=20226 or EventID=20227)]] and (EventData[Data[@Name='ErrorCode'] != '631'] or System[EventID=20227])</Select></Query></QueryList>
הדבק את זה במסנן המותאם של הטריגר, והוכח אותו כשאילתה לפני שהוא הופך לטריגר. אותו XPath רץ מ-PowerShell מול היומן החי, וזו הדרך הזולה לראות למה הוא מתאים בזמן שהיסטוריית המשימות עדיין לא מעורבת.
Get-WinEvent -LogName Application -MaxEvents 40 -FilterXPath "*[System[Provider[@Name='RasClient'] and (EventID=20226 or EventID=20227)]] and (EventData[Data[@Name='ErrorCode'] != '631'] or System[EventID=20227])" | Select-Object TimeCreated,Id,Message
טריגר שבשקט לא מתאים לשום דבר נראה בדיוק כמו משימה שרצה ונכשלת. שניהם מופיעים כ"האוטומציה לא עובדת", ואף אחד לא אומר איזה חצי חסר. בדוק קודם את פלט השאילתה, כי הוא מפריד בין שני המקרים בצעד אחד.
החיוג נכשל כי אין מי שיקליד את הסיסמה
הפעולה מריצה rasdial עם שם החיבור. כשבפרופיל אין הרשאה שמורה, החיוג נכשל מיד כי אין מי שיענה להנחיה. זו הסיבה הנפוצה ביותר לכך שמשימה שנדלקה נכון לא עושה דבר נראה לעין, ולכן בדוק אותה לפני שאתה נוגע בטריגר. חיוג ידני משורת פקודה מפריד בין בעיית הרשאה לבעיית תזמון.
שמור את ההרשאה פעם אחת תחת החשבון שהמשימה תרוץ בו, והפוך את החשבון הזה לחלק מהתכנון. משימה שרצה כ-SYSTEM לא יכולה לקרוא הרשאה שנשמרה על ידי החשבון האינטראקטיבי שלך, וגם לא משימה שרצה בתור מישהו אחר. השם חייב גם להתאים בדיוק לפרופיל, כולל כל קידומת דומיין בשדה המשתמש.
rasdial
rasdial "Office VPN"
(Start-Process rasdial -ArgumentList '"Office VPN"' -Wait -PassThru -NoNewWindow).ExitCode
הפקודה הראשונה מפרטת את השמות ש-Windows מכיר. השנייה מחייגת לפי שם בעזרת ההרשאה השמורה, והשלישית היא הצורה שפעולת PowerShell צריכה להשתמש בה, כי היא ממתינה ומחזירה ערך שהמשימה יכולה לרשום.
קרא את קוד היציאה במקום את החלון
משימה שמתחילה תהליך בלי להמתין מדווחת הצלחה ברגע שהתהליך קיים. לחיוג שעלול להיכשל שנייה אחר כך, פסק הדין הזה חסר ערך. המתנה לקוד היציאה הופכת את הפעולה לתוצאה אמיתית. היסטוריית המשימות לבדה מראה רק שתהליך התחיל, לעולם לא שמנהרה עלתה.
רשום את הערך עם חתימת זמן בכל הרצה. כשל בודד אחרי הפסקה הוא נורמלי, ואילו שלושה כשלים ברצף עם אותו קוד מצביעים על ההרשאה או על הפרופיל ולא על הרשת. הדפוס הזה הוא מה שהופך את ההיסטוריה לראויה לקריאה.
הוסף מרווח חזרה קצר כביטוח, ותהיה מפורש לגבי האופן שבו הוא מתקשר עם טריגר אירוע. חזרה כל דקה במשך חמש דקות מספקת את הניסיון השני כשהאינטרנט חזר יחד עם המנהרה, ותחת הגדרות, "אם המשימה כבר פועלת, חל הכלל הבא", המשימה רוצה "לא להפעיל מופע חדש" כדי שחזרה לא תחפוף לחיוג שעדיין בעיצומו. בלי ההגדרה הזו שני תהליכי rasdial יכולים להתחרות על אותה יציאה והשני נכשל בלי סיבה שימושית.
הוכח את נתיב השחזור
בדוק את שני הכיוונים בכוונה. התנתק ביד ואשר שלא מתרחש חיוג חוזר, ואז השבת את מתאם הרשת ואשר שהמשימה נדלקת כשהקישור חוזר. שתי הבדיקות האלה מכסות את כלל הדיכוי ואת מקרה הכשל האמיתי, ושום דבר אחר לא עושה זאת.
אחר כך קרא את היסטוריית המשימות במקום את סמל החיבור. ההיסטוריה רושמת מתי המשימה רצה, באיזה חשבון השתמשה ומה הפעולה החזירה, וזו הראיה שדרושה כשהמכונה אותה תיפול שוב בחודש הבא.