我对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机器不具备的依赖项,导致问题。