如果工作站未连接到网络,则关机脚本不会运行

如果工作站未连接到网络,则关机脚本不会运行

我要求每次关闭系统时都运行批处理脚本,无论计算机是否连接到网络。 (对于这个问题来说,这应该不重要,但是有问题的脚本会清除机器的打印队列。

但是,当我使用下面这种方法时,我无法在 PC 离线的情况下运行该脚本。

我还要补充一点,有问题的 PC 运行的是 Windows 10 Pro x64(版本 1809)。域控制器运行的是 Windows Server 2008 R2,这也是我运行的地方gpedit.msc

我目前所做的:

  • 创建了一个活动目录 组策略对象使用机器关机脚本。
  • 将脚本添加到系统卷
  • 确认该 GPO 确实已下载到相关工作站的硬盘上,因此应该可以离线访问。
  • GPO 中指定的路径是相对的,而不是绝对的。

我希望发生的事:

  • 当 PC 关闭时,ClearPrintQueue.bat无论 PC 当前是否有网络连接,脚本都会运行。

实际情况:

  • 当 PC 关闭时,ClearPrintQueue.bat仅当 PC 当前可以达到系统卷通过网络共享。

细节:

我所做的就是创建一个组策略对象在域中并将其链接到包含相关机器的测试 OU。

我编辑了 GPO 并导航至计算机配置->政策->Windows 设置->脚本(启动/关闭)->关闭

关机属性如下所述:

关机属性

点击显示文件... (Show Files...)资源管理器打开后显示文件夹\\example.com\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}\Machine\Scripts\Shutdown

该文件夹和文件 ClearPrintQueue.bat 的内容如下:

PS C:\> Get-ChildItem "\\example.com\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}\Machine\Scripts\Shutdown"


    Directory: \\example.com\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}\Machine\Scripts\Shutdown


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2019-04-23     15:00             71 ClearPrintQueue.bat


PS C:\> Get-Content "\\example.com\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}\Machine\Scripts\Shutdown\ClearPrintQueue.bat"
net stop spooler
del %systemroot%\System32\spool\printers\* /Q /F /S
PS C:\>

当调查本地 PC 时,我发现该脚本确实被复制到 PC 的本地 GPO 存储中:

PS C:\> Get-ChildItem -Recurse -Force -File "C:\Windows\System32\GroupPolicy\DataStore\0\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}"  


    Directory: C:\Windows\System32\GroupPolicy\DataStore\0\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}                            


Mode                LastWriteTime         Length Name                           
----                -------------         ------ ----                           
-a----       2019-04-23     15:00             59 gpt.ini                        


    Directory: C:\Windows\System32\GroupPolicy\DataStore\0\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}\Machine\Scripts            


Mode                LastWriteTime         Length Name                           
----                -------------         ------ ----                           
-a-h--       2019-04-23     15:00            118 scripts.ini                    


    Directory: C:\Windows\System32\GroupPolicy\DataStore\0\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}\Machine\Scripts\Shutdown   


Mode                LastWriteTime         Length Name                           
----                -------------         ------ ----                           
-a----       2019-04-23     15:00             71 ClearPrintQueue.bat            


PS C:\>

通过调查PC 的本地磁盘,我们发现scripts.iniClearPrintQueue.bat

PS C:\> Get-Content "C:\Windows\System32\GroupPolicy\DataStore\0\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}\Machine\Scripts\scripts.ini"                                                                              

[Shutdown]                                                                      
0CmdLine=ClearPrintQueue.bat                                                    
0Parameters=                                                                    
PS C:\> Get-Content "C:\Windows\System32\GroupPolicy\DataStore\0\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}\Machine\Scripts\Shutdown\ClearPrintQueue.bat"                                                             
net stop spooler                                                                
del %systemroot%\System32\spool\printers\* /Q /F /S                             
PS C:\>

即计算机拥有实际运行关机脚本所需的一切,而无需连接网络。但是,我观察到,当缺少网络连接时,脚本似乎无法运行。

使用数据包捕获和进一步调查WireShark进一步似乎证明 PC 确实从 SYSVOL 共享中拉出了脚本(为什么!它就在磁盘上...)时间戳对应于计算机关闭的时间。

Wireshark 数据包捕获显示了关机时脚本如何从磁盘中拉出

可能的解决方法:

我还没有测试过一种可能的解决方法,即手动指定脚本的绝对路径,C:\Windows\System32\GroupPolicy\DataStore\0\SysVol\example.com\Policies\{1B61F884-9D14-4065-8265-F04FFDE41683}\Machine\Scripts\Shutdown\ClearPrintQueue.bat而不是仅指定ClearPrintQueue.bat相对路径。但这似乎很不靠谱,而且似乎不是它“应该”的工作方式。在我走这条路之前,我很想看看是否有人有更好的主意。

我为什么要这么做:

我有一些移动用户,他们喜欢意外地使用错误的打印机进行打印,然后这些打印件在每个工作站本地排队,随后当 PC 连接到该打印机所在的站点时,打印机会输出大量纸张。VPN 软件在“用户”级别运行,因此当关机时 VPN 软件很可能没有运行。

我试图通过关机时清除打印队列来缓解这种情况,以便旧的打印作业不会永远停留在队列中。

答案1

这是设计使然。微软从来没有说过启动/关闭脚本会在计算机离线时执行。

您找到的本地缓存不是为了离线处理,而是为了避免客户端压垮域控制器。您可以在此处找到有关此特定点的更多详细信息:组策略核心协议:GPO 版本的缓存

此外,组策略脚本扩展要求客户端必须能够验证脚本的来源。如下图所示,GP 服务器(域控制器)是组策略脚本扩展的核心:

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gpscr/ms-gpscr_files/image001.png

为了解决您的问题,我建议您尝试以下方法:

通过组策略首选项(Computer Configuration -> Preferences -> Control Panel -> Scheduled Tasks)创建一个计划任务并创建一个New Scheduled Task (at Least Windows 7),将任务配置为以运行System,添加以下触发器:On disconnect from user session

然后,创建另一个首选项(“文件”而不是“计划任务”),将脚本复制到计算机上的安全本地路径中(用户不得在此文件中写入以避免权限提升)。如果需要,您可以使用其他东西来复制文件,但不要忘记在计划任务首选项中引用它。

相关内容