Author Posts

November 12, 2017 at 12:54 pm

Hi All

First time poster so bear with me I am slowly moving over to powershell but still in the early stages understanding it.

I have a batch script that removes msi/exe programs based on the 25th character of each line in a text file (uninstall-database.txt), I decided it was time to rewrite it but there's one part of it I am struggling with no matter what I do I can't seem to figure it out.

:: search for msi/exe uninstall strings and uninstall silently
for /f "tokens=* delims=[]{}" %%u in (uninstall-database.txt) do (
set applist=%%u
call :uninstallprocess
)

goto uninstalldone

:uninstallprocess
set firstchar=%applist:~0,1%
if %firstchar%==# goto commented
set appname=%applist:~0,25%
set firststringchar=%applist:~25,1%

:commented
exit /b

if %firststringchar%=={ goto msiuninstall
if %firststringchar%==[ goto exeuninstall

:msiuninstall
set msistring=%applist:~25,38%
msiexec /x%msistring% /qn /norestart
exit /b

:exeuninstall
set exestring=%applist:~26,-1%
%exestring%
exit /b

:uninstalldone

Format of the uninstall-database.txt...

# Comments have # at the beginning
25 chars for app name and then an msi string like this {C18FD2DC-D1FE-338B-A046-E83D5BF19C6E}
25 chars for app name and then an exe string like this ["C:\windows\SysWOW64\Adobe\Shockwave 12\uninstaller.exe"]

November 12, 2017 at 1:08 pm

Well, this forum isn't really about writing a script for you or to migrate your old batch scripts, but we're happy to try and answer questions! Did you have a specific question about Powershell code you wrote you wanted to start with?

I would recommend for you to start learning the basics of Powershell. I am sure as you progress you will come along commands and methods to replace what you have in your batch script.

Here you can find some great sources to start with:

Beginner Sites and Tutorials

Good luck and have a lot of fun

November 12, 2017 at 2:13 pm

The rest of it I have managed to change over all ok except this part and it seems like it's to complicated for me to just jump into so I don't know where to start and nothing I find on the web seems to fit with what I am doing. I currently only have this...

foreach($line in Get-Content ".\list.txt") {
    
    if($line.StartsWith("#"))
    {
    write-host comment
    }

    elseif($line.StartsWith("["))
    {
    write-host msi
    }

    elseif($line.StartsWith("{"))
    {
    write-host exe
    }
}

I guess I need help with the whole checking the 25th character instead of the first, I just need someone to point me in the right direction or give me an example of how I would do this.

November 12, 2017 at 9:10 pm

I am not really following your effort here.
Are you checking the whole 25 char string or just char 25?
Your snippet above shows you checking the beginning of the string.

The are a few ways to parse a string whether form a CSV, variable, etc. For complicated strings, RegEx is often the most prudent approach, but if you are not familiar and patient, RegEx can be frustrating.

Of course you can use the approach you started with, just be sure you fully look into string matching approaches that are possible.

Here are a few papers to help you with that.

PowerShell Problem Solver: PowerShell String Parsing with Substrings
'petri.com/powershell-string-parsing-with-substring'

Windows PowerShell String Theory
'technet.microsoft.com/en-us/library/2008.09.windowspowershell.aspx'

ConvertFrom-String: Example-based text parsing
'blogs.msdn.microsoft.com/powershell/2014/10/31/convertfrom-string-example-based-text-parsing'

Use the new PowerShell cmdlet Convert-String to parse email addresses
'blogs.technet.microsoft.com/ashleymcglone/2016/09/13/use-the-new-powershell-cmdlet-convert-string-to-parse-email-addresses'

About Parsing
'docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing?view=powershell-5.1'

PowerShell: Working With Regular Expressions (regex)
'social.technet.microsoft.com/wiki/contents/articles/4310.powershell-working-with-regular-expressions-regex.aspx'

November 12, 2017 at 11:46 pm

OK, as postanote already mentioned there are several approaches possible. One could be something like this:

$InputData = '25 chars for app name and then an msi string like this {C18FD2DC-D1FE-338B-A046-E83D5BF19C6E}',
'25 chars for app name and then an exe string like this ["C:\windows\SysWOW64\Adobe\Shockwave 12\uninstaller.exe"]',
'25 chars for app name and then an exe string like this ["C:\windows\SysWOW64\Adobe\Shockwave 13\uninstaller.exe"]',
'25 chars for app name and then an msi string like this {C18FD2DC-D1FE-338B-A046-E83D5BF29C6E}',
'25 chars for app name and then an msi string like this {C18FD2DC-D1FE-338B-A046-E83D5BF39C6E}',
'25 chars for app name and then an exe string like this ["C:\windows\SysWOW64\Adobe\Shockwave 14\uninstaller.exe"]',
'25 chars for app name and then an exe string like this ["C:\windows\SysWOW64\Adobe\Shockwave 15\uninstaller.exe"]'

$InputData | 
    ForEach-Object {
        $_ -match '(.*)(\{.*\}|\[.*\])' | Out-Null
	    [PSCustomObject]@{
		    Text = $Matches[1]
		    InstallString = $Matches[2]
	    }
    }

BTW: Every time you use Write-Host a puppy will die. 😉 Please do not use Write-Host. At least not in scripts and especially not here in the forum.

November 13, 2017 at 7:04 am

So far I have managed to get this, which seems to output the right strings although I have not tested properly yet.

foreach($line in Get-Content ".\uninstall-database.txt") {
    $stringchar = $line[25]
    $string = $line[25..200] -join ''

    If ($stringchar -eq "[") {
    $string = $string.Substring(1,$string.Length-2)
    "$string"
}

    elseIf ($stringchar -eq "{") {
    $parameters = "/x$string /qn /noreboot" 
    "Start-Process -FilePath C:\Windows\System32\msiexec.exe $parameters"
}

    }

Have I done anything really dumb or have you guys got any suggestions?