杀死进程,然后卸载应用程序 – 我可以做到这一点PowerShell,超过400台电脑,从TXT文件?

我对PowerShell相当陌生,但我非常想弄明白。 以下是我想要做的事情的总结:

  • 400台计算机,在物理位置不超过5个,通过VPN的速度相当差
  • 所有的应用程序都只有一个版本(但在Windows XP和Windows 7上),由于合规要求,这些应用程序需要删除
  • 我尝试过使用类似下面的东西,很less成功:
函数Terminate-Process { 

    参数( 
     [参数(强制性= $真,valuefrompipeline = $真)] 
     [string] $ COMPNAME) 
    开始{$ processname =读主机“进程名称我想杀”) 
    过程{ 
  $ result = Get-WmiObject -Class win32_Process -Filter“name ='$ processname'”-ComputerName(Get-Content computers.txt)|  ForEach-Object {$ _。Terminate()} 
  if($ result.ReturnValue -eq 0)  
          {Write-Output“$($ processname)在$($ compname)上终止”}} 
      else {Write-Output“无法在$($ compname)上终止$($ processname)”}         

                 } 
 end {Write-Output“Script ... END”}

 }

开始睡眠 -  60

 Get-Content Computers.txt |  。\ Get-InstalledSoftware.ps1 | 其中{$ _。AppName -match“SoftwareName”} |  \卸载,InstalledSoftware.ps1

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

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

Get-InstalledSoftware.ps1是:

 [列出CmdletBinding()]            

 [列出CmdletBinding()]            
参数(            
  [参数(ValueFromPipeline = $真,ValueFromPipelineByPropertyName = $真)]            
  [string []] $ ComputerName = $ env:computername            

 )            

开始 {            
  $ UninstallRegKey = “SOFTWARE \\ \\微软的Windows \\ \\ CURRENTVERSION卸载”             
 }            

过程{            
  foreach($ ComputerName中的$ Computer){            
  写详细“在$计算机上工作”            
   if(Test-Connection -ComputerName $ ComputerCount 1 -ea 0){            
    $ HKLM = [microsoft.win32.registrykey] :: OpenRemoteBaseKey('LocalMachine',$ computer)            
    $ UninstallRef = $ HKLM.OpenSubKey($ UninstallRegKey)            
    $ Applications = $ UninstallRef.GetSubKeyNames()            

    foreach($ App中的$ Applications){            
     $ AppRegistryKey = $ UninstallRegKey +“\\”+ $ App            
     $ AppDetails = $ HKLM.OpenSubKey($ AppRegistryKey)            
     $ AppGUID = $ App            
     $ AppDisplayName = $($ AppDetails.GetValue(“DisplayName”))            
     $ AppVersion = $($ AppDetails.GetValue(“DisplayVersion”))            
     $ AppPublisher = $($ AppDetails.GetValue(“Publisher”))            
     $ AppInstalledDate = $($ AppDetails.GetValue(“InstallDate”))            
     $ AppUninstall = $($ AppDetails.GetValue(“UninstallString”))            
    如果(!$ AppDisplayName){继续}            
     $ OutputObj = New-Object -TypeName PSobject             
     $ OutputObj | 添加成员-MemberType NoteProperty -Name ComputerName -Value $ Computer.ToUpper()            
     $ OutputObj | 添加成员-MemberType NoteProperty -Name AppName -Value $ AppDisplayName            
     $ OutputObj | 添加成员-MemberType NoteProperty -Name AppVersion -Value $ AppVersion            
     $ OutputObj | 添加成员-MemberType NoteProperty -Name AppVendor -Value $ AppPublisher            
     $ OutputObj | 添加成员-MemberType NoteProperty -Name InstalledDate -Value $ AppInstalledDate            
     $ OutputObj | 添加成员-MemberType NoteProperty -Name UninstallKey -Value $ AppUninstall            
     $ OutputObj | 添加成员-MemberType NoteProperty  - 名称AppGUID -Value $ AppGUID            
     $ OutputObj#| selectComputerName,DriveName            
    }            
   }            
  }            
 }            

结束 {}

和Uninstall-InstalledSoftware.ps1:

 [列出CmdletBinding()]            

参数(            

  [参数(ValueFromPipeline = $真,ValueFromPipelineByPropertyName = $真)]
  [string] $ ComputerName = $ env:computername,
  [参数(ValueFromPipeline = $真,ValueFromPipelineByPropertyName = $ true时,强制性= $真)]
  [string] $ APPGUID
 )            

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

我得到各种奇怪的错误,我甚至不知道上面甚至可以工作。 我从techibee.com获得了大部分内容,请访问: http ://techibee.com/powershell/powershell-uninstall-software-on-remote-computer/1400

有一个更简单的方法来做到这一点? 我拉我的头发了一下! 否则,我可以RDP到400台电脑,杀死进程和卸载…但我真的,真的,真的不想这样做。

虽然这在技术上是可行的,但是可能有更好的方法去做。

说到更好的方法,你可以在一个GPO中用几行代码作为启动或closures脚本来完成,这就是我如何处理这个问题的。 再用几行代码,你可以logging检查这个东西的存在和/或卸载它的结果,这对你的合规工作无疑是有用的。

如果GPO链接的启动/closures脚本不是出于任何原因的选项,我想我会使用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工具栏,这个例子是我几年前写的或者是复制的,可能是复制的,我很懒)。

如果没有debugging您复制的PS脚本,我会指出您可能正在运行不同的PS版本,安装/加载了不同的PS模块,或者可能存在一些XP机器不具备的依赖项,导致问题。