I'm trying to write a powershell script that looks for certain programs and if it doesn't find them, installs them. I'm using chocolatey to do this and it seems to work pretty well. Here's what I have so far:
if (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal
.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
$tempdir = Get-Location
$tempdir = $tempdir.tostring()
$FirstAppToMatch = '*Google Earth*'
$SecondAppToMatch = '*Google Chrome*'
$ThirdAppToMatch = '*FireFox*'
$FourthAppToMatch = '*Notepad++*'
$FifthAppToMatch = '*Adobe Reader*'
$SixthAppToMatch = '*Office*'
$msiFile = $tempdir+"\microsoft.interopformsredist.msi"
$msiArgs = "-qb"
function Get-InstalledApps
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $FirstAppToMatch}
If ($result -eq $null) {
(cinst googleearthpro -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $SecondAppToMatch}
If ($result -eq $null) {
(cinst googlechrome -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $ThirdAppToMatch}
If ($result -eq $null) {
(cinst firefox -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $FourthAppToMatch}
If ($result -eq $null) {
(cinst notepadplus -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $FifthAppToMatch}
If ($result -eq $null) {
(cinst adobereader -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
{
if ([IntPtr]::Size -eq 4) {
$regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
}
else {
$regpath = @(
'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
}
Get-ItemProperty $regpath | .{process{if($_.DisplayName -and
$_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate,
DisplayVersion, UninstallString |Sort DisplayName
}
$result = Get-InstalledApps | where {$_.DisplayName -like $SixthAppToMatch}
If ($result -eq $null) {
(cinst office365business -y)
}
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
So I have 2 issues. The first is that everything after the first "write-host" gets displayed. I know I can hide the window but I don't want to do that for the purposes of testing and debugging my code. I tried encapsulating all the write-host commands with { } but it still showed all the code, as in, when the script runs, I see all of the commands shown in the PS window. If this was batch I would just @echo off but I'm not sure how to do that in powershell.
The second problem is it's messy. It works but it's messy. I feel like I should be able to condense this code down some, I'm just not sure how. In this case, I need it to iterate over each "App" and then install a different program if that particular "App" isn't found on the system. So it looks for google earth, and if it doesn't find it, it runs the command to install it...then it loops back to the next app...doesn't find it, and runs a different command to install that one and so on. I've hit a wall with this one though. I've been looking at for loops and arrays to try to see if I could find a better way to do it other than listing each command over and over like I am here, but it seems that for loops and for-each loops are meant to do the same thing to each element in the array. In this case, I need it to do something different, i.e run a different command, or not, based on the app it's looking for.
Any tips or advice would be greatly appreciated. Thanks in advance.