macOS-如何编写脚本卸载 macOS 系统扩展

如何编写脚本卸载 macOS 系统扩展

macOS 上的现代系统扩展通常通过应用程序包安装。它们可以捆绑在与其关联的应用程序中(例如Microsoft Defender ATP),也可以与提供系统扩展的主应用程序一起捆绑在特定应用程序中(例如Sophos Anti-VirusCisco AnyConnect)。

例如,Cisco AnyConnect 的网络系统扩展是通过与主 AnyConnect 应用程序位于Cisco AnyConnect Socket Filter.app同一Cisco子文件夹中的应用程序提供的。在此应用程序内,您将看到系统扩展包本身,位于:Applications``Contents/Library/SystemExtensions

Cisco AnyConnect 系统扩展

在终端中,您可以使用以下命令查看已安装的系统扩展的状态systemextensionsctl list

1
2
3
4
5
% systemextensionsctl list
1 extension(s)
--- com.apple.system_extension.network_extension
enabled active teamID bundleID (version) name [state]
* * DE8Y96K9QP com.cisco.anyconnect.macos.acsockext (4.9.06037/4.9.06037) Cisco AnyConnect Socket Filter Extension [activated enabled]

如果已启用系统扩展,则无法使用类似 的命令将其删除rm。如果删除关联的应用程序,系统扩展仍将保持激活状态。

有一个用于卸载系统扩展的命令,但它目前要求禁用 SIP:

1
2
3
4
% systemextensionsctl uninstall DE8Y96K9QP
At this time, this tool cannot be used if System Integrity Protection is enabled.
This limitation will be removed in the near future.
Please remember to re-enable System Integrity Protection!

希望这个问题能够像对话中所承诺的那样尽快得到解决。

显然,开发人员可以在其应用程序中内置系统扩展的停用功能,这样就可以在重新启动时将其删除。例如,思科已向-deactivateExt应用程序添加了停用它的参数:

1
% sudo /Applications/Cisco/Cisco\ AnyConnect\ Socket\ Filter.app/Contents/MacOS/Cisco\ AnyConnect\ Socket\ Filter -deactivateExt

这将打开一个窗口,要求输入管理员密码来执行停用操作:

系统扩展密码对话框

提供密码后,运行以下命令时系统扩展显示终止systemextensionsctl list

1
2
3
4
5
% systemextensionsctl list
1 extension(s)
--- com.apple.system_extension.network_extension
enabled active teamID bundleID (version) name [state]
DE8Y96K9QP com.cisco.anyconnect.macos.acsockext (4.9.06037/4.9.06037) Cisco AnyConnect Socket Filter Extension [terminated waiting to uninstall on reboot]

重启后,该项目就消失了。

如果您的供应商的卸载程序没有内置系统扩展的停用功能,而您确实运行了他们的卸载程序,您可能会进入没有与已激活的系统扩展关联的应用程序的状态。我发现在这种情况下删除系统扩展的唯一方法是重新启动进入恢复模式/操作系统,禁用 SIP,重新启动进入系统,然后使用上述命令。然后,再次启动进入恢复以重新启用 SIP(因为在 Big Sur 中,这似乎不再可能从主启动系统中实现)。哎呀。

通过 GUI 删除系统扩展

如果您将提供系统扩展的应用程序拖到垃圾箱/垃圾桶,则会出现一个对话框,指示系统扩展将被删除。还需要管理员密码才能完成删除,但至少不需要恢复模式。

系统扩展删除警告 Sophos

我认为 Apple 实施的这种系统扩展删除方法存在错误,因为您似乎必须删除应用程序包本身才能获取对话框,从而启动系统扩展的批准删除。如果您删除任何父文件夹(例如应用程序所在的SophosCisco文件夹),则不会出现对话框,并且系统扩展不会被停用,让您处于上述状态。

这在应用程序中尤其明显Sophos Scan,因为这个应用程序实际上并不是提供系统扩展的应用程序。相反,该应用程序中的一个应用程序正在执行此操作:

Sophos 系统扩展

因此,如果您将其拖到/Applications/Sophos/Sophos Scan.app废纸篓,系统扩展不会发生任何变化。您必须/Applications/Sophos/Sophos Scan.app/Contents/MacOS/SophosScanD.app先将其拖到废纸篓。

如何帮助您的用户并以编程方式进行删除

在托管环境中,我们希望让用户和管理员尽可能轻松地安全、完全地删除应用程序,而不会让系统处于混乱状态。当然,为上述系统扩展删除的 GUI 方法提供文档是可能的,但为了降低出错的可能性,最好尽可能多地编写脚本。这就是 AppleScript 发挥作用的地方。

AppleScript 早于 OS X,AppleScript 命令通常比最接近的 UNIX 命令更类似于 GUI 过程。AppleScript 包含一种删除应用程序的方法,我们可以使用它来模拟将应用程序拖到废纸篓的 GUI 过程。

例如,这里我们通过osascriptUNIX 命令调用 AppleScript 命令来删除 Microsoft Defender ATP (包括系统扩展):

1
2
3
4
5
% osascript \
-e 'tell application "Finder"' \
-e activate \
-e 'move application file "Microsoft Defender ATP" of folder "Applications" of startup disk to trash' \
-e 'end tell'

请注意,多行 AppleScript 由一系列标志表示-e

这里我们要删除文件夹内的 Cisco AnyConect 网络扩展Cisco

1
2
3
4
5
% osascript \
-e 'tell application "Finder"' \
-e activate \
-e 'move application file "Cisco AnyConnect Socket Filter" of folder "Cisco" of folder "Applications" of startup disk to trash' \
-e 'end tell'

在我的测试中,这些命令应该以 的形式运行sudo,这意味着它可以从管理工具运行。

由于您正在使用tell application命令,隐私偏好设置策略控制就会发挥作用,因此您可能需要将管理工具对 Finder 的访问列入白名单,以防止出现另一个对话框窗口。

这些命令会调出相同的对话框,就像在 GUI 中将应用程序拖到垃圾箱一样,但至少您能够确保删除正确的应用程序包以触发系统扩展的删除,并且您可以确保卸载程序脚本中事件的正确顺序,以确保没有系统扩展被孤立。

为了完成,下面是删除两个 Sophos 系统扩展的命令:

1
2
3
4
5
6
7
8
9
10
11
% osascript \
-e 'tell application "Finder"' \
-e activate \
-e 'move application file "Sophos Network Extension" of folder "Sophos" of folder "Applications" of startup disk to trash' \
-e 'end tell'

% osascript \
-e 'tell application "Finder"' \
-e activate \
-e 'move application file "SophosScanD" of folder "MacOS" of folder "Contents" of application file "Sophos Scan" of folder "Sophos" of folder "Applications" of startup disk to trash' \
-e 'end tell'

请注意,如果应用程序内有应用程序,则必须调用application file而不是folder来表示父应用程序包。此外,.app的名称中 是可选的application file,您可以添加或省略它。

结论

在当前版本的 macOS 中,系统扩展的删除有点麻烦。命令的输出systemextensionsctl uninstall表明将来会变得更容易,并且可能还有其他尚未发现的方法(至少我还没有发现)。但与此同时,如果您想尽可能确保包含系统扩展的应用程序的卸载尽可能顺利,请考虑使用 AppleScript 的move application file to trash方法。


macOS-如何编写脚本卸载 macOS 系统扩展
https://dnacore.github.io/post/63bb2411-bc08-430b-ad25-5ed7d2939c92.html
作者
DNACore
发布于
2024年8月13日
更新于
2024年8月13日
许可协议