想要一种使用 PowerShell 将不同字符串拆分为多个部分的通用方法
Would like a universal way to split different strings into multiple parts using PowerShell
我正在研究一种从注册表中读取软件的 UninstallStrings 的方法。然后我尝试执行这些字符串来卸载软件。
当我打印出包含字符串信息的变量时,它会正确打印整个字符串(带有参数),但我无法 运行 这些字符串。
这个问题有多个部分。
一些安装字符串的格式如下
c:\file path\blah\app.exe /uninstall
"c:\file path\blah\app.exe" /uninstall
c:\file path\blah\app.exe --uninstall
'c:\file path\blah\app.exe' /uninstall
我想做的是找出能够以 "universal" 方式 运行 卸载程序的最佳方法。
有没有办法有效地做到这一点?
我尝试以两种不同的方式执行字符串。
& $uninstaller
和
Start-Process -FilePath cmd.exe -ArgumentList '/c', $uninstaller -Wait
它们似乎都不起作用。没有错误,但它们似乎没有 运行 因为当我检查应用程序时它仍然安装。
我尝试了几种拆分文本的方法。
$Uninstaller.split("/")[0]
$Uninstaller.split("/",2)[1]
$($Uninstaller) | Invoke-Expression
$Uninstaller.Substring(0,$Uninstaller.lastIndexOf('.exe '))
$Uninstaller.split('^(*?\.exe) *')
提前致谢!
想通了。也许有更好的方法,但这似乎对我有用。
CLS
$Software = "OneDrive"
$Filter = "*" + $Software + "*"
$Program = $ProgUninstall = $FileUninstaller = $FileArg = $NULL
try
{
if (Test-Path -Path "HKLM:\SOFTWARE\WOW6432Node")
{
$programs = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction Stop
}
$programs += Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction Stop
$programs += Get-ItemProperty -Path "Registry::\HKEY_USERS\*\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction SilentlyContinue
}
catch
{
Write-Error $_
break
}
foreach($Program in $Programs)
{
$ProgDisplayName = $Program.DisplayName
$ProgUninstall = $Program.UninstallString
if($ProgDisplayName -like $Filter)
{
if($ProgUninstall -like "msiexec*")
{
$FileUninstaller = $ProgUninstall.split(" ")[0]
$FileArg = ($($ProgUninstall).split(" ",2)[1])
}
else
{
if(($ProgUninstall -like '"*"*') -or ($ProgUninstall -like "'*'*"))
{
#String has quotes, don't need to do anything
}
else
{
if($NULL -ne $ProgUninstall)
{
#String doesn't have quotes so we should add them
$ProgUninstall = '"' + ($ProgUninstall.Replace('.exe','.exe"'))
}
}
#Let's grab the uninstaller and arguments
$FileUninstaller = $ProgUninstall.split('"')[1]
$FileArg = $ProgUninstall.split('"')[-1]
}
#Debug
#$FileUninstaller
#$FileArg
#Run the Uninstaller
Start-Process $FileUninstaller -ArgumentList $FileArg -wait -ErrorAction SilentlyContinue
}
}
这对于 msi 安装非常有效:
get-package *whatever* | uninstall-package
这是一个非 msi 静默卸载示例,但您必须添加“/S”或任何静默卸载选项:
get-package notepad++* |
% { & $_.Meta.Attributes['UninstallString'] /S }
尝试以下测试脚本,其中简单的控制台应用程序 CliParser.exe
仅回显命令行参数(用 C 编写,受启发 here)。在名称 CliParser noPause.exe
中使用了带有 space 的精确副本;它表明 . $Uninstaller $UninsParams
即使路径 $Uninstaller
包含 space(s).
也应该有效
无需使用Start-Process -FilePath cmd.exe …
;只需将点源运算符应用为 . $Uninstaller $UninsParams
…
$lines
集合包含几乎具有代表性的卸载字符串语法模式(取自我的 Windows 10):
$lines = @'
MsiExec.exe /X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF}
"D:\Program Files (x86)\Virtual Russian Keyboard\unins000.exe"
"C:\Windows10Upgrade\Windows10UpgraderApp.exe" /Uninstall
C:\Windows\SysWOW64\msiexec.exe /package {CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE} /uninstall {815F0BC1-7E54-300C-9ACA-C9460FDF6F78} /qb+ REBOOTPROMPT=""
C:\Program Files (x86)\InstallShield Installation Information\{8833FFB6-5B0C-4764-81AA-06DFEED9A476}\Setup.exe -runfromtemp -removeonly
"C:\WINDOWS\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Driver
%windir%\system32\sdbinst.exe -u "C:\WINDOWS\AppPatch\CustomSDB\{9f4f4a9b-eec5-4906-92fe-d1f43ccf5c8d}.sdb"
'@ -split [System.Environment]::NewLine
$FakeUninstaller = "D:\bat\CLIParser noPause.exe"
foreach ( $line in $lines ) {
# $line
$aux = $line -split @('\.exe'),2,[System.StringSplitOptions]::None
$Uninstaller = (cmd /c echo $($aux[0].TrimStart('"').TrimStart("'") + '.exe')).Trim('"')
$UninsParams = $aux[1].TrimStart('"').TrimStart("'").Trim().split(' ',[System.StringSplitOptions]::RemoveEmptyEntries)
". $Uninstaller $UninsParams"
. $FakeUninstaller $UninsParams | Where-Object { $_ -notlike "param 0 = *" }
}
输出:D:\PShell\SO023960.ps1
. MsiExec.exe /X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF}
param 1 = /X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF}
. "D:\Program Files (x86)\Virtual Russian Keyboard\unins000.exe"
. C:\Windows10Upgrade\Windows10UpgraderApp.exe /Uninstall
param 1 = /Uninstall
. C:\Windows\SysWOW64\msiexec.exe /package {CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE} /uninstall {815F0BC1-7E54-300C-9ACA-C9460FDF6F78} /qb+ REBOOTPROMPT=""
param 1 = /package
param 2 = {CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE}
param 3 = /uninstall
param 4 = {815F0BC1-7E54-300C-9ACA-C9460FDF6F78}
param 5 = /qb+
param 6 = REBOOTPROMPT=""
. "C:\Program Files (x86)\InstallShield Installation Information\{8833FFB6-5B0C-4764-81AA-06DFEED9A476}\Setup.exe" -runfromtemp -removeonly
param 1 = -runfromtemp
param 2 = -removeonly
. C:\WINDOWS\SysWOW64\RunDll32.exe "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Driver
param 1 = C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL,UninstallPackage
param 2 = Display.Driver
. C:\WINDOWS\system32\sdbinst.exe -u "C:\WINDOWS\AppPatch\CustomSDB\{9f4f4a9b-eec5-4906-92fe-d1f43ccf5c8d}.sdb"
param 1 = -u
param 2 = C:\WINDOWS\AppPatch\CustomSDB\{9f4f4a9b-eec5-4906-92fe-d1f43ccf5c8d}.sdb
我正在研究一种从注册表中读取软件的 UninstallStrings 的方法。然后我尝试执行这些字符串来卸载软件。
当我打印出包含字符串信息的变量时,它会正确打印整个字符串(带有参数),但我无法 运行 这些字符串。 这个问题有多个部分。
一些安装字符串的格式如下
c:\file path\blah\app.exe /uninstall
"c:\file path\blah\app.exe" /uninstall
c:\file path\blah\app.exe --uninstall
'c:\file path\blah\app.exe' /uninstall
我想做的是找出能够以 "universal" 方式 运行 卸载程序的最佳方法。 有没有办法有效地做到这一点?
我尝试以两种不同的方式执行字符串。
& $uninstaller
和
Start-Process -FilePath cmd.exe -ArgumentList '/c', $uninstaller -Wait
它们似乎都不起作用。没有错误,但它们似乎没有 运行 因为当我检查应用程序时它仍然安装。
我尝试了几种拆分文本的方法。
$Uninstaller.split("/")[0]
$Uninstaller.split("/",2)[1]
$($Uninstaller) | Invoke-Expression
$Uninstaller.Substring(0,$Uninstaller.lastIndexOf('.exe '))
$Uninstaller.split('^(*?\.exe) *')
提前致谢!
想通了。也许有更好的方法,但这似乎对我有用。
CLS
$Software = "OneDrive"
$Filter = "*" + $Software + "*"
$Program = $ProgUninstall = $FileUninstaller = $FileArg = $NULL
try
{
if (Test-Path -Path "HKLM:\SOFTWARE\WOW6432Node")
{
$programs = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction Stop
}
$programs += Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction Stop
$programs += Get-ItemProperty -Path "Registry::\HKEY_USERS\*\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction SilentlyContinue
}
catch
{
Write-Error $_
break
}
foreach($Program in $Programs)
{
$ProgDisplayName = $Program.DisplayName
$ProgUninstall = $Program.UninstallString
if($ProgDisplayName -like $Filter)
{
if($ProgUninstall -like "msiexec*")
{
$FileUninstaller = $ProgUninstall.split(" ")[0]
$FileArg = ($($ProgUninstall).split(" ",2)[1])
}
else
{
if(($ProgUninstall -like '"*"*') -or ($ProgUninstall -like "'*'*"))
{
#String has quotes, don't need to do anything
}
else
{
if($NULL -ne $ProgUninstall)
{
#String doesn't have quotes so we should add them
$ProgUninstall = '"' + ($ProgUninstall.Replace('.exe','.exe"'))
}
}
#Let's grab the uninstaller and arguments
$FileUninstaller = $ProgUninstall.split('"')[1]
$FileArg = $ProgUninstall.split('"')[-1]
}
#Debug
#$FileUninstaller
#$FileArg
#Run the Uninstaller
Start-Process $FileUninstaller -ArgumentList $FileArg -wait -ErrorAction SilentlyContinue
}
}
这对于 msi 安装非常有效:
get-package *whatever* | uninstall-package
这是一个非 msi 静默卸载示例,但您必须添加“/S”或任何静默卸载选项:
get-package notepad++* |
% { & $_.Meta.Attributes['UninstallString'] /S }
尝试以下测试脚本,其中简单的控制台应用程序 CliParser.exe
仅回显命令行参数(用 C 编写,受启发 here)。在名称 CliParser noPause.exe
中使用了带有 space 的精确副本;它表明 . $Uninstaller $UninsParams
即使路径 $Uninstaller
包含 space(s).
无需使用Start-Process -FilePath cmd.exe …
;只需将点源运算符应用为 . $Uninstaller $UninsParams
…
$lines
集合包含几乎具有代表性的卸载字符串语法模式(取自我的 Windows 10):
$lines = @'
MsiExec.exe /X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF}
"D:\Program Files (x86)\Virtual Russian Keyboard\unins000.exe"
"C:\Windows10Upgrade\Windows10UpgraderApp.exe" /Uninstall
C:\Windows\SysWOW64\msiexec.exe /package {CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE} /uninstall {815F0BC1-7E54-300C-9ACA-C9460FDF6F78} /qb+ REBOOTPROMPT=""
C:\Program Files (x86)\InstallShield Installation Information\{8833FFB6-5B0C-4764-81AA-06DFEED9A476}\Setup.exe -runfromtemp -removeonly
"C:\WINDOWS\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Driver
%windir%\system32\sdbinst.exe -u "C:\WINDOWS\AppPatch\CustomSDB\{9f4f4a9b-eec5-4906-92fe-d1f43ccf5c8d}.sdb"
'@ -split [System.Environment]::NewLine
$FakeUninstaller = "D:\bat\CLIParser noPause.exe"
foreach ( $line in $lines ) {
# $line
$aux = $line -split @('\.exe'),2,[System.StringSplitOptions]::None
$Uninstaller = (cmd /c echo $($aux[0].TrimStart('"').TrimStart("'") + '.exe')).Trim('"')
$UninsParams = $aux[1].TrimStart('"').TrimStart("'").Trim().split(' ',[System.StringSplitOptions]::RemoveEmptyEntries)
". $Uninstaller $UninsParams"
. $FakeUninstaller $UninsParams | Where-Object { $_ -notlike "param 0 = *" }
}
输出:D:\PShell\SO023960.ps1
. MsiExec.exe /X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF} param 1 = /X{FFC6E93A-B9AD-3F20-9B06-EE20E24AAEAF} . "D:\Program Files (x86)\Virtual Russian Keyboard\unins000.exe" . C:\Windows10Upgrade\Windows10UpgraderApp.exe /Uninstall param 1 = /Uninstall . C:\Windows\SysWOW64\msiexec.exe /package {CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE} /uninstall {815F0BC1-7E54-300C-9ACA-C9460FDF6F78} /qb+ REBOOTPROMPT="" param 1 = /package param 2 = {CFEF48A8-BFB8-3EAC-8BA5-DE4F8AA267CE} param 3 = /uninstall param 4 = {815F0BC1-7E54-300C-9ACA-C9460FDF6F78} param 5 = /qb+ param 6 = REBOOTPROMPT="" . "C:\Program Files (x86)\InstallShield Installation Information\{8833FFB6-5B0C-4764-81AA-06DFEED9A476}\Setup.exe" -runfromtemp -removeonly param 1 = -runfromtemp param 2 = -removeonly . C:\WINDOWS\SysWOW64\RunDll32.exe "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Driver param 1 = C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL,UninstallPackage param 2 = Display.Driver . C:\WINDOWS\system32\sdbinst.exe -u "C:\WINDOWS\AppPatch\CustomSDB\{9f4f4a9b-eec5-4906-92fe-d1f43ccf5c8d}.sdb" param 1 = -u param 2 = C:\WINDOWS\AppPatch\CustomSDB\{9f4f4a9b-eec5-4906-92fe-d1f43ccf5c8d}.sdb