【问题标题】:PS1 uninstallation script in SCCMSCCM 中的 PS1 卸载脚本
【发布时间】:2015-11-05 01:51:37
【问题描述】:

我是一个 nub 脚本编写者,我正在尝试编写一个非常简单的脚本来 taskkill 2 个程序,然后卸载其中的 1 个。

我在 Powershell 中编写它并将其卡在 SCCM 中进行部署......但是每次我部署它时,它都没有运行最后一行来卸载程序。

代码如下:

# Closing Outlook instance
#
taskkill /IM outlook.exe /F
#
# Closing Linkpoint instance
#
taskkill /IM LinkPointAssist.exe /F
#
# Uninstalling Linkpoint via uninstall string if in Program Files
#
MsiExec.exe /X {DECDCD14-DEF6-49ED-9440-CC5E562FDC41} /qn
#
# Uninstalling Linkpoint via WmiObject if installed manually in AppData
Get-WmiObject -class win32_product -Filter "Name like '%Linkpoint%'" | ForEach-Object { $_.Uninstall()}
#
Exit

有人可以帮忙吗? SCCM 说脚本完成没有错误,我知道它能够执行它,因为 taskkills 工作......但它没有卸载程序。

提前感谢您的任何意见。

【问题讨论】:

  • 您需要等待MsiExec 完成吗? (默认情况下,当启动 GUI 应用程序时——比如MsiExec——命令行工具不会等待。)
  • 我没有。 msiexec 实际上是在尝试卸载相同的软件,但以不同的方式安装(编程文件而不是 appdata)并且通常会立即卸载。你认为我需要在某处添加暂停吗?我忘了补充一件事,这个脚本在本地运行良好。
  • instantaneously 对您来说可能是这样,但对于一台永恒的计算机......就像 PSH 试图在 MsiExec 进程完全启动之前执行以下行一样。使用Start-Process 获取您可以等待的进程的引用。
  • 理查德,感谢您到目前为止的帮助。我在link 之后在系统下本地运行脚本,看看我是否可以使用 Get-WmiObject win32_product 找到 Linkpoint,但它甚至没有出现......我怀疑这是因为它已安装到用户的 %appdata %...但是由于我正在推动 SCCM,我认为除了在 System 下运行之外没有其他方法...您是否知道解决方法或其他方法?
  • 我所知道的唯一可以作为系统运行的工具是 SysInternal 的psexec。但是,我会首先包含完整的日志记录(或者可能使用脚本运行):在应用解决方法之前确定您遇到了正确的问题。

标签: powershell scripting sccm


【解决方案1】:

因此,SCCM 正在运行此脚本,并且脚本中的任何内容都不会引发错误。

如果您想抛出一个错误,SCCM 可以返回以了解部署的进展情况,您需要添加一个额外的步骤。

$result = Get-WmiObject -class win32_product -Filter "Name like '%Linkpoint%'" | ForEach-Object { $_.Uninstall()}

   if ($result.ReturnValue -ne 0){
 [System.Environment]::Exit(1603)
}else
{
[System.Environment]::Exit(0)
}

【讨论】:

    【解决方案2】:

    我在 SO 和 SF 上看到了很多此类问题:有人在为应用程序、脚本或 ConfigMgr 的意外行为而苦苦挣扎,而关于我可以对他们的环境做出的假设的信息很少。在那个阶段,通常需要几天的互动才能将问题缩小到可以解决的程度。

    我希望这个答案可以作为未来此类问题的参考。 OP 的第一个问题应该是“你违反了这 9 条原则中的哪一条?”您可以将其视为一种用于 ConfigMgr 应用程序打包的 Joel Test


    改进 ConfigMgr 应用程序包的九个步骤

    我发现使用 ConfigMgr 可靠地安装和卸载应用程序需要严格遵守一系列原则。我很难学会这些原则。如果您很难弄清楚为什么应用程序无法在 ConfigMgr 下正常运行,那么您很可能会对以下问题之一回答“否”。

    1。您是否在测试整个生命周期?

    为了希望可靠地管理应用程序,您需要测试应用程序的整个生命周期。这是我测试的序列:

    • 检测:确保检测脚本结果是否定的
    • 安装:使用安装脚本安装应用程序
    • 检测:确保检测脚本运行时结果为正
    • 卸载:使用您的卸载脚本进行卸载

    我反复运行这个序列,对每个步骤进行调整,直到整个序列正常工作。

    2。您是否首先独立于 ConfigMgr 进行测试?

    使用 ConfigMgr 测试应用程序的生命周期很慢,并且有自己的失败方式可以掩盖应用程序包的问题。因此,目标是能够独立于但等效于 ConfigMgr 客户端来测试应用程序的安装、检测和卸载。为了实现该目标,您最终需要为每个应用程序提供三个单独的脚本:

    • Install-Application.bat - 安装脚本的入口点
    • Detect-Application.ps1 - 检测应用是否安装的脚本
    • Uninstall-Application.bat - 卸载脚本的入口点

    这三个脚本中的每一个都可以由您或 ConfigMgr 客户端直接调用。对于作为系统安装的应用程序,您需要使用 psexec -s 在与 ConfigMgr (caveat) 相同的上下文中调用脚本。

    3。你知道上下文吗?

    根据调用它们的上下文,安装程序的行为可能会有很大不同。您需要考虑应用程序是为用户安装的,还是为系统安装的。如果是为系统安装的,当你独立于 ConfigMgr 进行测试时,使用psexec -s 来调用你的脚本。

    4。您了解用户交互吗?

    安装程序can also behave rather differently depending on whether a user can interact with it。要将脚本作为具有用户交互的系统进行测试,请使用psexec -i -s

    5。您是否将 ConfigMgr 与测试的上下文和用户交互相匹配?

    一旦您拥有完整的生命周期,请确保为上下文(为用户与系统安装)和交互(用户是否可以与应用程序交互)选择正确的相应选项。如果您不这样做,ConfigMgr 客户端将安装与您测试的方式不同的应用程序,因此您真的不能指望成功。

    6。您是否知道应用程序检测上下文不匹配的可能性?

    检测脚本运行的上下文取决于应用程序是部署到用户还是系统。这意味着in some cases the installation and detection contexts won't matched。编写检测脚本时请记住这一点。

    7。您是否构建了脚本以使退出代码正常工作?

    ConfigMgr 需要从您的安装和卸载脚本中查看退出代码才能执行正确的操作。安装程序发出失败信号或需要使用退出代码重新启动。为了让退出代码到达 ConfigMgr 客户端,您需要确保安装和卸载脚本的结构正确。

    8。您是否使用 PowerShell 脚本进行检测?

    ConfigMgr 有一个很好的用户界面,用于检查文件是否存在、注册表项等,作为是否安装应用程序的代理。该方案的问题在于,无法独立于并等效于 ConfigMgr 客户端来测试应用程序检测。如果您想测试独立于 ConfigMgr 客户端的应用程序生命周期(相信我,您希望如此),您的所有检测都必须使用 PowerShell 脚本进行。

    9。您是否正确构建了 PowerShell 检测脚本?

    ConfigMgr 用来解释 PowerShell 检测脚本的输出的规则是晦涩难懂的。谢天谢地,they are documented

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-17
      • 2017-01-25
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多