PowerShell: Maintain Chocolatey Applications

This current version has some bugs… Review these other codes for some ideas on fixing…

# maintainChocoApps.ps1

$apps=@(
    @{appName='Google Chrome';chocoAppname='googlechrome';stableVersion='89.0.4389.128';targetModels='Latitude 5420','Latitude E5440'}
)
$privateRepo='kimconnectrepo'
$privateRepoUrl='https://choco.kimconnect.com/chocolatey'
$priority=0

function maintainChocoApps{
  param(
    $apps,
    $privateRepo,
    $privateRepoUrl,
    $priority
  )

  # Set private repo source if it doesn't exist
  function addRepo{
    param(
      $privateRepoName,
      $privateRepoUrl,
      $priority=1
    )

    function testUrl($url){
      $HTTP_Request = [System.Net.WebRequest]::Create($url)
      $HTTP_Response = $HTTP_Request.GetResponse()
      $HTTP_Status = [int]$HTTP_Response.StatusCode
      If ($HTTP_Status -eq 200) {
          $valid=$true
      }Else {
        $valid=$false
      }
      If (!($HTTP_Response -eq $null)){ $HTTP_Response.Close()}
      return $valid
    }
    # Install Chocolatey from the Intranet private repo
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12  
    if (!(Get-Command choco.exe -ErrorAction SilentlyContinue)){
      Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))}
    $privateRepo="'$privateRepoName' -s '$privateRepoUrl' --priority=$priority"  
    $sources=choco source list
    $privateRepoExists=$sources -match $privateRepoName     
    $urlReachable=testUrl $privateRepoUrl
    if (!$privateRepoExists){
        invoke-expression "choco source add -n=$privateRepo"
    }elseif($privateRepoExists){
      write-host "Private repo $privateRepoName already exists on $env:computername." -foregroundcolor green
    }
    return $urlReachable
  }  
  $repoReachable=addRepo $privateRepo $privateRepoUrl $priority
  if(!$repoReachable){
    write-warning "$env:computername currently cannot reach $privateRepo. Program cannot continue"
    return $false
  }

  # Gather computer info
  $computerModel=(Get-WmiObject -Class:Win32_ComputerSystem).Model
  $validInternalSource=choco source list|?{$_ -like "$privateRepo*"}

  # Install Chocolatey from the Intranet private repo
  if (!(Get-Command choco.exe -ErrorAction SilentlyContinue)){
    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))}
  function uninstallApp($appName){
    $alternativeMethod=$false
    try{
      $app = Get-WmiObject -Class Win32_Product | Where-Object{$_.Name -eq $appName}
      $app.Uninstall()
    }catch{
      write-warning $_
      $alternativeMethod=$true
    }
    if($alternativeMethod){
      try{
        $uninstallStrings = (Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall|
        Get-ItemProperty|Where-Object {$_.DisplayName -match $appName}).UninstallString
        ForEach ($uninstallString in $uninstallStrings) {
                $uninstallCommand = $uninstallString.Replace('{',' ').Replace('}',' ')+'ACCEPT=YES /qr+'
                write-host "Attempting alternative method of invoking: $uninstallCommand"
                Invoke-Expression $uninstallCommand
        }
        return $true
      }catch{
        return $false
      }
    }else{
      return $true
    }
  }

  foreach($app in $apps){
    $chocoAppname=$app.chocoAppname
    $appName=$app.appName
    $stableVersion=$app.stableVersion
    $affected=$app.targetModels|?{$computerModel -like "$_*"}
    if($affected){    
      $appwizInstance=Get-Package -Provider Programs -IncludeWindowsInstaller -Name $appName
      $appwizVersion=$appwizInstance.Version
      # $installedApps=Get-CimInstance -ClassName win32_InstalledWin32Program -ErrorAction Stop|select Name,Version
      # $appwizAppExists=.{$matchApp=$installedApps|?{$_.Name -like "*$appName*" }
      #                     if($matchApp){$matchApp}else{$false}
      #                   }
      # $appwizVersion=if($appwizAppExists){$appwizAppExists.Version}else{$false}  
      $appWizVersionMismatch=if($appwizVersion){[version]$appwizVersion -ne [version]$stableVersion}else{$True}
      if($appWizVersionMismatch){
        $appwizRemoved=uninstallApp $appName
      }

      $chocoAppInstalled=choco list -localonly|?{$_ -like "$chocoAppname*"}
      $chocoAppVersion=if($chocoAppInstalled){[regex]::match($chocoAppInstalled,'(\d{1,}\.{0,})+').groups[0].value}else{$false}
      $chocoVersionMismatch=if($chocoAppVersion){[version]$chocoAppVersion -gt [version]$stableVersion}else{$true}
      if(!$chocoAppInstalled){
          if($validInternalSource){
              choco install $chocoAppname --version $stableVersion -force --source=$internalSource -y
          }else{
              choco install $chocoAppname --version $stableVersion -force -y --ignore-checksums
          }
      }elseif($chocoVersionMismatch){
        choco uninstall $chocoAppname
        if($validInternalSource){
            choco install $chocoAppname --version $stableVersion -force --source=$internalSource -y
        }else{
            choco install $chocoAppname --version $stableVersion -force -y --ignore-checksums
        }
      }else{
          write-host "GoogleChrome version $chocoAppVersion is ok."
      }
    }else{
        write-host "This computer $computerModel is not affected."
    }
  }
}

maintainChocoApps $apps $privateRepo $privateRepoUrl $priority

Leave a Reply

Your email address will not be published. Required fields are marked *