Windows는 VPN 클라이언트에 대한 재연결 정책을 제공하지 않으므로 자정에 끊긴 연결은 아침 식사 때도 끊긴 상태입니다. 끊김을 감시하고 rasdial을 실행하는 예약 작업은 서드파티 클라이언트 없이 그 틈을 메웁니다. 작업이 운영자처럼 동작할지 루프처럼 동작할지는 세 가지 세부 사항에 달려 있습니다: 어떤 이벤트와 일치시키는지, 어떤 자격 증명을 볼 수 있는지, 결과로 무엇을 하는지입니다. 세 가지 모두 어렵지 않으며, 그중 하나라도 빠지면 영원히 다이얼하는 작업이 됩니다.

타이머가 잘못된 트리거인 이유

타이머는 터널이 끊겼든 아니든 자체 일정에 따라 다이얼합니다. 그러면 아무도 필요로 하지 않은 시도가 생기고, 작업 세션 중의 시도는 그 세션을 방해할 수 있습니다. 이벤트 트리거는 연결이 상태를 바꿀 때만 실행되므로 더 저렴하고 따져 보기 쉽습니다. 이벤트는 이유도 함께 전달하며, 그 이유가 네트워크 장애와 의도적으로 연결을 끊은 사람을 구분합니다.

그 구분이 유용한 작업과 매일 저녁 사용자와 싸우는 작업의 차이입니다. 또한 동작만 설명하는 레시피에서 흔히 빠지는 부분이기도 합니다.

이벤트 쌍, 그리고 억제해야 할 것

Remote Access Service 클라이언트는 RasClient 공급자 아래 Application 로그에 수명 주기 레코드를 씁니다. 20226은 종료된 연결을, 20227은 실패한 시도를 표시하므로 둘 다 새 다이얼을 정당화할 수 있습니다. 작업의 나머지 전부는 이 두 식별자를 정확히 일치시키는 데 달려 있습니다. 이들은 수년간 안정적이어서 그것에 기반한 레시피가 여전히 돌아다니지만, 공급자나 식별자의 이름을 바꾸는 빌드는 쿼리가 아무것도 반환하지 않게 만듭니다. 기능 업데이트마다 작업이 실행을 멈추기를 기다리지 말고 증명 단계를 다시 실행하세요.

제외해야 할 종료가 하나 있습니다. 오류 631은 사용자가 포트를 끊었다는 뜻이며, 그 순간의 재다이얼은 방금 의도적으로 네트워크를 바꾼 사람과 싸우게 됩니다. 제외는 스크립트가 아니라 트리거 필터에 넣어 작업이 아예 시작되지 않게 하세요. 이는 이벤트 ID 하나에만 적용되어야 합니다 — EventData 조건자는 지정된 요소가 존재할 때만 일치하므로, 공유 절은 다른 ID의 모든 이벤트를 조용히 버리게 되기 때문입니다. 필터를 쓰기 전에 실제 레코드에서 요소 이름을 읽으세요:

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 프로세스가 같은 포트를 두고 경쟁하고 두 번째는 유용한 이유 없이 실패합니다.

복구 경로를 증명하세요

두 방향을 의도적으로 시험하세요. 직접 연결을 끊고 재다이얼이 일어나지 않는지 확인한 다음, 네트워크 어댑터를 사용하지 않도록 설정하고 링크가 돌아올 때 작업이 실행되는지 확인하세요. 이 두 시험이 억제 규칙과 실제 실패 사례를 모두 다루며, 다른 무엇도 그렇게 하지 않습니다.

그다음에는 연결 아이콘이 아니라 작업 기록을 읽으세요. 기록은 작업이 언제 실행되었는지, 어떤 계정을 사용했는지, 동작이 무엇을 반환했는지 남기며, 다음 달에 같은 컴퓨터가 다시 끊길 때 필요한 증거가 바로 그것입니다.

관련 글