اسکریپتی که پنجرهٔ VPN را باز می‌کند و سپس ده ثانیه می‌خوابد، دارد حدس می‌زند و این حدس در هر دو جهت غلط است: یا پیش از آنکه تونل قابل استفاده شود کپی را شروع می‌کند، یا پس از آنکه کار می‌توانست آغاز شود هنوز منتظر می‌ماند. هیچ‌یک از این دو نتیجه نمی‌گوید آیا احراز هویت تمام شده است. از نتیجهٔ خودِ فرمان استفاده کنید و سپس از سرویس سؤالی بپرسید که واقعاً می‌تواند پاسخ دهد. ترتیب این دو گام همان تمام طراحی است.

فرمان واقعاً چه چیزی گزارش می‌کند

برای یک پروفایل بومی ویندوز که ابزار خط فرمان نصب‌شده آن را می‌فهمد، rasdial.exe یک ورودی نام‌دار را شماره‌گیری می‌کند و کد خروج فرایند را برمی‌گرداند. این کد تلاش شماره‌گیری را توصیف می‌کند: صفر یعنی اتصال برای آن پروفایل برقرار شد و غیرصفر یعنی در مرحله‌ای که کد مشخص می‌کند شکست خورد. آن را نتیجهٔ یک لایه بخوانید، نه نتیجهٔ کار.

این نتیجه چیزی دربارهٔ تخصیص نشانی، DNS خصوصی، مسیرهای افزوده یا اجازهٔ رسیدن به سرور مشخص نمی‌گوید. همهٔ اینها پس از شماره‌گیری موفق رخ می‌دهند و هر یک از آن‌ها هنوز می‌تواند غلط باشد. همین شکاف دلیل آن است که نماد «متصل» و کپی ناموفق این‌قدر زیاد با هم دیده می‌شوند.

نتیجه را پیش از هر کار دیگری ثبت کنید

با تأیید اینکه پروفایل برای حسابی که کار را اجرا می‌کند وجود دارد شروع کنید، نه فقط برای حسابی که با آن آزمایش می‌کنید:

Get-VpnConnection -Name "Contoso-Office"
Get-VpnConnection -Name "Contoso-Office" -AllUserConnection

سپس شماره‌گیری کنید و کد را بی‌درنگ بخوانید. PowerShell نتیجهٔ بومی را در $LASTEXITCODE فقط تا اجرای فرمان خارجی بعدی نگه می‌دارد، بنابراین یک ping ناخواسته میان شماره‌گیری و بررسی، مقداری را که می‌خواستید بخوانید نابود می‌کند. نخست آن را به متغیر خودتان اختصاص دهید و بعد تصمیم بگیرید چه کنید.

& rasdial.exe "Contoso-Office"
$dial = $LASTEXITCODE
if ($dial -ne 0) { throw "rasdial failed with $dial" }

کد را همراه متن خطای غیرمحرمانه ثبت کنید، زیرا ورودی گمشده، اعتبارنامهٔ ردشده و پایان مهلت پاسخ‌های متفاوتی می‌خواهند. جدول نتایج رایج را به گام بعدی نگاشت می‌کند.

ResultWhat it indicatesNext step
0The dial completedProbe the resource, do not start writing yet
691The credential or authentication method was rejectedFix the account or method, do not retry in a loop
623The named entry was not foundFix the profile name or its scope
Other non-zeroTransport, timeout or adapter failureRead the message, then check the path

آمادگی یعنی منبع، نه تونل

وقتی شماره‌گیری موفق شد، چیزی را که کار لازم دارد آزمایش کنید. اشتراک فایل، نقطهٔ پایانی API یا درگاه پایگاه داده آزمون آمادگی بهتری از یک وب‌سایت عمومی است، زیرا سایت عمومی از هر مسیر کارا پاسخ می‌دهد و دربارهٔ مسیر خصوصی چیزی ثابت نمی‌کند. آزمونی را انتخاب کنید که خودِ برنامه به آن وابسته است. یک اتصال TCP موفق به شما می‌گوید مسیریابی و فیلترکردن باز هستند و همین بیشترِ چیزی است که نخستین نوشتن لازم دارد:

Test-NetConnection -ComputerName files.contoso.example -Port 445

تعداد تلاش‌ها را محدود کنید و ثبت کنید کدام مرحله شکست خورد. اعتبارنامهٔ ردشده باید اسکریپت را متوقف کند، نه اینکه حلقهٔ تلاش دوباره را تغذیه کند؛ نام DNS که هنوز ظاهر نشده چند تلاش کوتاه دیگر می‌ارزد؛ درگاهی که هرگز باز نمی‌شود مشکلی در مسیریابی یا خط‌مشی بالاتر از کلاینت است.

اگر اتصال پیش از شروع کار از قبل وجود داشت، آن را به حال خود بگذارید. قطع کردن نشستی که خودتان باز نکرده‌اید کار دیگر کاربر را مختل می‌کند، پس ثبت کنید نشست از آنِ کیست و کدام پایان دادن مناسب است.

پروفایل را به حسابی که کار را اجرا می‌کند محدود کنید

یک وظیفهٔ زمان‌بندی‌شده با هویت و نشست خودش اجرا می‌شود و پروفایلی که روی میز کار شما کار می‌کند ممکن است آنجا نامرئی باشد. پیش از اعتماد به زمان‌بندی، بررسی قابل‌مشاهده بودن و شماره‌گیری را زیر حساب آن وظیفه تکرار کنید. رمز عبور را هم از خط فرمان دور نگه دارید: آرگومان‌ها برای فرایندهای دیگر دیدنی‌اند و غالباً در گزارش‌ها می‌مانند.

اگر استقرار به پیام مرورگر، ضربهٔ کارت هوشمند یا تأیید MFA نیاز دارد، آن تعامل بخشی از طراحی است و با شبیه‌سازی فشردن کلیدها نمی‌توان آن را خودکار کرد. برای آن حالت از کلاینت پشتیبانی‌شده استفاده کنید و بگذارید گام انسانی رخ دهد.

شکل اسکریپت نهایی کوتاه می‌ماند: پروفایل را بررسی کنید، شماره‌گیری کنید، کد را بخوانید، منبع را آزمایش کنید و سپس کار را شروع کنید. هر گام به پرسشی پاسخ می‌دهد که گام پیشین نمی‌توانست و هیچ‌یک از آن‌ها به خواب متکی نیست.

مقالات مرتبط