Я новичок в PowerShell, но очень стараюсь в этом разобраться. Вот краткое изложение того, что я хочу сделать:
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
============================================
Последняя строка вызывает два дополнительных сценария 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 {}
и 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"} }
Я получаю всевозможные странные ошибки, и я даже не уверен, что вышеперечисленное может работать. Я получил большую часть этого от techibee.com, здесь: http://techibee.com/powershell/powershell-uninstall-software-on-remote-computer/1400
Есть способ сделать это попроще? Я немного выдергиваю волосы !! В противном случае я мог бы RDP до 400 компьютеров, остановить процесс и удалить ... но я действительно, очень, очень не хочу этого делать.
Хотя это технически возможно, вероятно, есть способ лучше.
И, говоря о лучших способах решения этой проблемы, вы можете сделать это в объекте групповой политики с несколькими строками кода в качестве сценария запуска или завершения работы, как я с этим справляюсь. С помощью еще нескольких строк кода вы можете зарегистрировать результаты проверки наличия этой вещи и / или ее удаления, что, несомненно, будет полезно для ваших усилий по обеспечению соответствия.
Если связанный с 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, что вызывает проблемы. .