Kill processo, em seguida, desinstalar o aplicativo - Posso fazer isso com o PowerShell, mais de 400 computadores, a partir de um arquivo txt?

1

Sou relativamente novo no PowerShell, mas estou tentando entender isso. Aqui está a soma do que eu quero fazer:

  • 400 computadores, com não mais que 5 em um local físico, conectados por velocidades bastante baixas em toda a VPN
  • Todos têm um único aplicativo com uma única versão (mas no Windows XP e no Windows 7) que precisa ser removido devido a requisitos de conformidade
  • Eu tentei usar algo como o abaixo, com pouco sucesso:
function Terminate-Process { 

    param( 
    [Parameter(Mandatory=$true,valuefrompipeline=$true)] 
    [string]$compname) 
    begin {$processname = Read-Host "Process Name I Want To Kill"} 
    process { 
 $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) terminated on $($compname) "} 
     else { Write-Output "could not terminate $($processname) on $($compname) "}         

                } 
end{Write-Output "Script ...END"}

}

Start-Sleep -s 60

Get-Content Computers.txt | .\Get-InstalledSoftware.ps1 | Where {$_.AppName -match “SoftwareName” } | .\Uninstall-InstalledSoftware.ps1

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

A última linha chama dois scripts adicionais do PowerShell.

Get-InstalledSoftware.ps1 é:

[cmdletbinding()]            

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

)            

begin {            
 $UninstallRegKey="SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"             
}            

process {            
 foreach($Computer in $ComputerName) {            
  Write-Verbose "Working on $Computer"            
  if(Test-Connection -ComputerName $Computer -Count 1 -ea 0) {            
   $HKLM   = [microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computer)            
   $UninstallRef  = $HKLM.OpenSubKey($UninstallRegKey)            
   $Applications = $UninstallRef.GetSubKeyNames()            

   foreach ($App in $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"))            
    if(!$AppDisplayName) { continue }            
    $OutputObj = New-Object -TypeName PSobject             
    $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper()            
    $OutputObj | Add-Member -MemberType NoteProperty -Name AppName -Value $AppDisplayName            
    $OutputObj | Add-Member -MemberType NoteProperty -Name AppVersion -Value $AppVersion            
    $OutputObj | Add-Member -MemberType NoteProperty -Name AppVendor -Value $AppPublisher            
    $OutputObj | Add-Member -MemberType NoteProperty -Name InstalledDate -Value $AppInstalledDate            
    $OutputObj | Add-Member -MemberType NoteProperty -Name UninstallKey -Value $AppUninstall            
    $OutputObj | Add-Member -MemberType NoteProperty -Name AppGUID -Value $AppGUID            
    $OutputObj# | Select ComputerName, DriveName            
   }            
  }            
 }            
}            

end {}

e Uninstall-InstalledSoftware.ps1:

[cmdletbinding()]            

param (            

 [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
 [string]$ComputerName = $env:computername,
 [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
 [string]$AppGUID
)            

 try {
  $returnval = ([WMICLASS]"\$computerName\ROOT\CIMV2:win32_process").Create("msiexec '/x$AppGUID '/qn")
 } catch {
  write-error "Failed to trigger the uninstallation. Review the error message"
  $_
  exit
 }
 switch ($($returnval.returnvalue)){
  0 { "Uninstallation command triggered successfully" }
  2 { "You don't have sufficient permissions to trigger the command on $Computer" }
  3 { "You don't have sufficient permissions to trigger the command on $Computer" }
  8 { "An unknown error has occurred" }
  9 { "Path Not Found" }
  9 { "Invalid Parameter"}
 }

Recebo todos os tipos de erros estranhos, e nem tenho certeza de que o problema acima possa funcionar. Eu recebi a maior parte do techibee.com, aqui: link

Existe uma maneira mais simples de fazer isso? Eu estou puxando meu cabelo um pouco !! Caso contrário, eu poderia RDP para 400 computadores, matar o processo e desinstalar ... mas eu realmente, realmente, não quero fazer isso.

    
por stantonsays 12.08.2012 / 20:17

1 resposta

1

Embora isso seja tecnicamente possível, provavelmente há uma maneira melhor de fazer isso.

E falando de melhores maneiras de fazer isso, Você poderia fazer isso em um GPO com algumas linhas de código como um script de inicialização ou desligamento, que é como eu lido com isso. Com mais algumas linhas de código, você poderia registrar os resultados da verificação da presença dessa coisa e / ou desinstalá-la, o que, sem dúvida, seria útil em seus esforços de conformidade.

Se um script de inicialização / desligamento vinculado a GPO não é uma opção por qualquer motivo, acho que eu usaria o PSExec para eliminar o processo em uma lista de computadores lidos do arquivo e depois fazer o script da desinstalação em um idioma apropriado. Parece-me que isso é muito mais fácil no VB, por exemplo.

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

(Adeus Google Toolbar, nesse exemplo que eu escrevi ou copiei alguns anos atrás. Copiado, provavelmente. Eu sou um pouco preguiçoso.)

Sem depurar o script PS que você copiou, eu diria que você pode estar executando uma versão PS diferente, módulos PS instalados / carregados e / ou pode haver algumas dependências que suas máquinas XP não possuem no lugar isso está causando problemas.

    
por 14.08.2012 / 23:44