终止进程,然后卸载应用程序——我可以使用 PowerShell 通过 txt 文件对超过 400 台计算机执行此操作吗?

终止进程,然后卸载应用程序——我可以使用 PowerShell 通过 txt 文件对超过 400 台计算机执行此操作吗?

我对 PowerShell 还很陌生,但我非常想弄清楚。以下是我想要做的事情的总结:

  • 400 台计算机,其中物理位置不超过 5 台,通过 VPN 连接,速度较慢
  • 所有操作系统都只有一个版本(但适用于 Windows XP 和 Windows 7)的单一应用程序,由于合规性要求,需要将其删除
  • 我尝试过使用类似下面的方法,但收效甚微:
函数终止进程{

    参数(
    [参数(强制=$true,来自管道的值=$true)]
    [字符串]$公司名称)
    开始 {$processname = Read-Host “我想要终止的进程名称”}
    过程 {
 $result = Get-WmiObject -Class win32_Process -Filter “name='$processname'” -ComputerName (Get-Content computer.txt) | ForEach-Object { $_.Terminate() }
 如果 ($result.ReturnValue -eq 0 )  
         { Write-Output“$($processname) 终止于 $($compname)”}
     else { Write-Output“无法终止$($compname) 上的$($processname)”}         

                }
结束{Write-Output“脚本...结束”}

}

开始-睡眠 -s 60

获取内容 Computers.txt | .\Get-InstalledSoftware.ps1 | 其中 {$_.AppName -match “SoftwareName” } | .\Uninstall-InstalledSoftware.ps1

============================================

最后一行调用了两个额外的 powershell 脚本。

Get-InstalledSoftware.ps1 是:

[cmdletbinding()]            

[cmdletbinding()]            
参数(            
 [参数(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]            
 [string[]]$ComputerName = $env:computername            


开始 {            
 $UninstallRegKey="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\卸载"             
}            

过程 {            
 foreach($ComputerName 中的 $Computer) {            
  详细写入“正在 $Computer 上工作”            
  如果(测试连接-计算机名称$计算机-计数1-ea 0){            
   $HKLM = [microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computer)            
   $UninstallRef = $HKLM.OpenSubKey($UninstallRegKey)            
   $应用程序 = $UninstallRef.GetSubKeyNames()            

   foreach ($App 在 $Applications 中) {            
    $AppRegistryKey = $UninstallRegKey + "\\" + $App            
    $AppDetails = $HKLM.OpenSubKey($AppRegistryKey)            
    $AppGUID = $App            
    $AppDisplayName = $($AppDetails.GetValue("显示名称"))            
    $AppVersion = $($AppDetails.GetValue("显示版本"))            
    $AppPublisher = $($AppDetails.GetValue("发布者"))            
    $AppInstalledDate = $($AppDetails.GetValue("安装日期"))            
    $AppUninstall = $($AppDetails.GetValue("卸载字符串"))            
    如果 (!$AppDisplayName) { 继续 }            
    $OutputObj = 新对象-类型名称 PSobject             
    $OutputObj | 添加成员-成员类型 NoteProperty-名称 ComputerName-值 $Computer.ToUpper()            
    $OutputObj | 添加成员-MemberType NoteProperty-名称 AppName-值$AppDisplayName            
    $OutputObj | 添加成员-MemberType NoteProperty-名称 AppVersion-值$AppVersion            
    $OutputObj | 添加成员-MemberType NoteProperty-名称 AppVendor-值$AppPublisher            
    $OutputObj | 添加成员-成员类型 NoteProperty -名称 InstalledDate -值 $AppInstalledDate            
    $OutputObj | 添加成员-MemberType NoteProperty-名称 UninstallKey-值$AppUninstall            
    $OutputObj | 添加成员-MemberType NoteProperty-名称 AppGUID-值$AppGUID            
    $OutputObj# | 选择计算机名称、驱动器名称            
   }            
  }            
 }            
}            

结尾 {}

和 Uninstall-InstalledSoftware.ps1:

[cmdletbinding()]            

参数(            

 [参数(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
 [字符串]$ComputerName = $env:计算机名称,
 [参数(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
 [字符串]$AppGUID

 尝试 {
  $returnval = ([WMICLASS]“\\$computerName\ROOT\CIMV2:win32_process”)。创建(“msiexec `/x$AppGUID `/qn”)
 } 抓住 {
  write-error“无法触发卸载。请查看错误消息”
  $_
  出口
 }
 开关 ($($returnval.returnvalue)){
  0 { “卸载命令已成功触发” }
  2 { “您没有足够的权限在 $Computer 上触发命令” }
  3 { “您没有足够的权限在 $Computer 上触发命令” }
  8 { “发生未知错误” }
  9 {“未找到路径”}
  9 {“无效参数”}
 }

我遇到了各种奇怪的错误,我甚至不确定上面的方法是否有效。我从 techibee.com 上找到了大部分错误信息,如下所示: http://techibee.com/powershell/powershell-uninstall-software-on-remote-computer/1400

有没有更简单的方法可以做到这一点?我有点抓狂了!!否则我可以通过 RDP 连接到 400 台计算机,终止进程并卸载...但我真的真的真的不想这么做。

答案1

虽然这在技术上是可行的,但可能有更好的方法来实现它。

说到更好的解决方法,您可以在 GPO 中使用几行代码作为启动或关闭脚本来执行此操作,这就是我处理此问题的方法。再多几行代码,您就可以记录检查此东西是否存在和/或卸载它的结果,这无疑对您的合规性工作大有裨益。

如果出于某种原因无法使用 GPO 链接的启动/关闭脚本,我认为我会使用 PSExec 来终止从文件读取的计算机列表上的进程,然后使用适当的语言编写卸载脚本。例如,在我看来,这在 VB 中要容易得多。

a=WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{2318C2B1-4965-11d4-9B18-009027A5CD4F}\UninstallString")

If a<>"" Then

WshShell.Run(a&" /S"),1,True
i=i+1

end if

(再见了 Google 工具栏,这个例子是我几年前写的或复制的。可能也是复制的。我比较懒。)

在没有调试您复制的 PS 脚本的情况下,我想指出您可能正在运行不同的 PS 版本,安装/加载了不同的 PS 模块和/或您的 XP 机器可能没有安装某些依赖项,从而导致问题。

相关内容