我对PowerShell相当陌生,但我非常想弄明白。 以下是我想要做的事情的总结:
函数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机器不具备的依赖项,导致问题。