SYSTEM 任务会在哪个电话簿里查找 VPN 配置文件?
任务以某个账户身份运行,而原生 VPN 配置文件默认属于单个用户,除非创建为所有用户共用。在重建任何东西之前,请先比较这两个存储。
你的 VPN 配置文件就在“设置”里,但计划任务仍然报告找不到连接。其实什么都没坏:Windows 原生 VPN 存储默认按用户隔离,除非配置文件以“所有用户”方式创建;而任务是以其 principal 指定的账户运行的。通常,任务读取的电话簿里从来没有你的配置文件。两条命令和一项任务设置就足以证明这一点,值得在任何人重建连接之前先跑一遍。
两个存储保存着同一个配置文件名称
原生 Windows VPN 配置文件存放在创建它的那个账户的存储里。全局存储是另一本电话簿,只有在提升权限的会话中用“所有用户”开关创建配置文件时才会写入。两者可以保存同名的配置文件,而且谁也不是对方的视图。
从同一个会话读取这两个存储,并比较它们返回的名称。该开关选择全局存储,读取它通常需要提升权限的会话:
Get-VpnConnection | Select-Object Name, ServerAddress, TunnelType
Get-VpnConnection -AllUserConnection | Select-Object Name, ServerAddress, TunnelType
如果第一条命令列出了该配置文件,而第二条没有,那么任何凭据改动都帮不了以另一个账户运行的任务,因为问题在于成员身份,而不是身份验证。如果两者都列出了它,那么存储不是原因,下一节适用。仅这一次比较就能关掉一半这类工单。记下是哪个存储给出了结果、你是在哪个账户下执行的检查,因为缺少这两个事实,答案毫无意义。
先读任务的 principal,再读它的凭据
打开任务并读取 principal,因为它决定了任务能看到哪个存储。以 SYSTEM 运行的任务并不是你的账户多了些权限:它有自己独立的配置文件,也无法访问你登录时创建的那个按用户隔离的电话簿。服务账户的行为完全相同。
无论是否登录都运行的选项也会改变这一点,因为此时任务没有可借用凭据的交互式会话。让操作把 whoami 写进文件,然后去读结果,而不是假设它。
你自己终端里的诊断说明不了这个问题,因为它只显示你的账户能看到什么。要在任务的标识下执行比较,用你为此准备的任何已批准流程。从管理员控制台粘贴出来的输出是另一份数据,并不更有特权。如果不存在这样的流程,任务就必须自己记录答案,这正是最后一节要搭建的。
找到配置文件不等于登录成功
所有用户共用的配置文件会让配置在更大范围内可见。它不会带走创建它的账户所保存的密码,也不会把存储在你用户配置文件里的私钥交给另一个账户。可见性和可用的凭据是两项独立的测试,通过第一项并不能说明第二项。
如果任务现在能找到配置文件却在身份验证时失败,那是进步,这个阶段应当写进记录。把证书移到计算机存储,或者通过部署自带的机制提供密钥,而不是再次重建连接名称。重建只会产生同样的失败,只是时间戳更新。Microsoft 记录了 cmdlet 开关所选的两个范围。
非交互式挑战就是这一阶段背后的陷阱。PIN 提示或一次性验证码,没有桌面的任务无法应答,所以一个手动拨号完美无缺的配置文件,在自动化下可能根本不可用。
任务记录需要的四个字段
把决定结果的值放在同一处,因为其中三项通常被留成隐含状态。记录需要四行:
- 操作路径:任务运行的脚本或可执行文件,而不是对另一个账户会解析成别处的快捷方式。
- 配置文件名称:精确字符串,因为两个存储可能保存同名却指向不同服务器的配置文件。
- Principal:任务运行所用的账户,以及它是否有交互式会话。
- 身份验证方法:该 principal 实际能完成什么,例如计算机存储中的证书,而不是你用户配置文件里的密钥。
这四行回答了工单真正在问的问题:自动化用的是哪份配置。它们也能在任务下一次重建时留存下来,那时最初的作者已不在旁边解释这个名字为何重要。没有它们,同样的失败会在下一次部署后回来,并再次耗掉同样的工时。
定位任务走到了哪一步
给操作加上检测,而不是从上次运行结果去猜。一个短包装脚本把标识、它可见的存储和拨号结果记在一处:
whoami
Get-VpnConnection -AllUserConnection | Select-Object Name, ServerAddress
rasdial "Office"
schtasks /query /tn "VPN Connect" /v /fo LIST
拨号命令会打印自己的错误,通常比笼统的任务失败更清楚。查询会把 principal 和最后的结果代码并排返回,所以标识和结果能在一屏里看到。这两个事实决定了下一步是改存储还是改凭据。
最后,把用户登录后才连接的任务与设备隧道或受支持的登录前工作流区分开。共用一份配置文件对这两者都不是设计,而 principal 字段才告诉你建的是三者中的哪一种。如果连接必须在登录前就存在,那么按用户隔离的配置文件存储就是修错了层。