By Mell Rosandich

 

 

-------------------------------------------------------

Setting up System values

-------------------------------------------------------

 

 

<system>

<basefolderpath>C:\Users\ServerAdmin\Desktop\AppVault</basefolderpath>

<datfolderpath>C:\Users\ServerAdmin\Desktop\dats</datfolderpath>

</system>

 

basefolderpath - where all doaloaded app are stored

datfolderpath - date file location, keeps versions and errors in files

 

 

 

-------------------------------------------------------

Setting up applications

-------------------------------------------------------

 

 

Each app you want to keep updated you need a appitem node in the applist.xml (or what ever file you pass as the config).

 

 

<appitem>

<appname>7zip</appname>

<checkversionurl>http://www.7-zip.org/</checkversionurl>

<checkversionregex matchnumber="1"><![CDATA[Download 7-Zip.(.*).\(.*\) for Windows]]></checkversionregex>

<checkdownloadurl>http://www.7-zip.org/download.html</checkdownloadurl>

<checkdownloadregex matchnumber="1"><![CDATA[<A.*?href="(.*x64\.msi)".*?>]]></checkdownloadregex>

<downloadurl use="checkdownloadurl" usereg="no"></downloadurl>

<downloadurlregex  matchnumber="1"></downloadurlregex>

<saveasname useurlpart="yes"></saveasname>

<overridesavepath uncompress="no">C:\Users\ServerAdmin\Desktop\AppVault\test</overridesavepath>

<saverelativepath uncompress="no">7Zip</saverelativepath>

</appitem>

 

 

The way the script works is as follows:

 

checkversionurl - this node contains the http link to the site with the version number of the application

checkversionregex matchnumber="1"  - When the URL is pulled we regex with this expression and take the matchednumer="which match by regex" and this is how we get version

 

checkdownloadurl - A url where the donload might be

checkdownloadregex matchnumber="1"- a regex to fetch nother link to the down load matchnumber="which match by regex" to use for the dowload, can go 1 level deeper

 

downloadurl use="checkdownloadurl" - when set to use "checkdownloadurl" nodes

[or]

downloadurl usereg="no" - the URL defined here is a direct link to the files.

[or]

downloadurl use="checkdownloadurl" usereg="yes" - we now have another page with a direct download URL and must regex to get it.

downloadurlregex  matchnumber="1" - final regex to get the URL for download.

 

 

 

saveasname useurlpart="yes" - no data need will use the name of the file feched from the URL

saveasname useurlpart="no" - what ever you want to name the file

 

overridesavepath - if set will override the path where the file will be saved

saverelativepath - save to the location set in the system.basefolderpath \ appName\

 

 

 

 

Sample 1 Smartermail, direct download, version is regex

<appitem>

<appname>SmarterMail9</appname>

<checkversionurl>http://smartertools.com/smartermail/releasenotes/v9.aspx</checkversionurl>

<checkversionregex matchnumber="1"><![CDATA[Version (.*)\((.*)\)</h3>]]></checkversionregex>

<checkdownloadurl></checkdownloadurl>

<checkdownloadregex matchnumber="1"></checkdownloadregex>

<downloadurl usereg="no">http://smartertools.com/Download.aspx?Product=SmarterMail&amp;File=MSIInstaller&amp;Version=9&amp;Location=Primary</downloadurl>

<downloadurlregex  matchnumber="1"></downloadurlregex>

<saveasname useurlpart="no">Smartermail9.msi</saveasname>

<overridesavepath uncompress="no"></overridesavepath>

<saverelativepath uncompress="no">SmarterMail9</saverelativepath>

</appitem>

 

 

 

 

sample 2, notepad++, download URL changes per version. Version is regex

<appitem>

<appname>notepad</appname>

<checkversionurl>http://notepad-plus-plus.org/</checkversionurl>

<checkversionregex matchnumber="2"><![CDATA[<a.*>(.*)Current Version.*<span>(.*)</span>]]></checkversionregex>

<checkdownloadurl>http://notepad-plus-plus.org/</checkdownloadurl>

<checkdownloadregex matchnumber="1" ><![CDATA[<a.*?href="(.*)".*?>.*Current Version.*<span>(.*)</span>]]></checkdownloadregex>

<downloadurl use="checkdownloadurl" usereg="yes"></downloadurl>

<downloadurlregex  matchnumber="1"><![CDATA[<a.*?href="(.*)".*?>.* zip package</a>]]></downloadurlregex>

<saveasname useurlpart="yes"></saveasname>

<overridesavepath uncompress="no"></overridesavepath>

<saverelativepath uncompress="yes">NotePad</saverelativepath>

</appitem>

 

 

 

 

 

 

 

----------------------------------------------

applist.xml

-----------------------

 

 

 

<applicationvault>

<system>

<basefolderpath>C:\Users\ServerAdmin\Desktop\AppVault</basefolderpath>

<datfolderpath>C:\Users\ServerAdmin\Desktop\dats</datfolderpath>

</system>

<appitem>

<appname>notepad</appname>

<checkversionurl>http://notepad-plus-plus.org/</checkversionurl>

<checkversionregex matchnumber="2"><![CDATA[<a.*>(.*)Current Version.*<span>(.*)</span>]]></checkversionregex>

<checkdownloadurl>http://notepad-plus-plus.org/</checkdownloadurl>

<checkdownloadregex matchnumber="1" ><![CDATA[<a.*?href="(.*)".*?>.*Current Version.*<span>(.*)</span>]]></checkdownloadregex>

<downloadurl use="checkdownloadurl" usereg="yes"></downloadurl>

<downloadurlregex  matchnumber="1"><![CDATA[<a.*?href="(.*)".*?>.* zip package</a>]]></downloadurlregex>

<saveasname useurlpart="yes"></saveasname>

<overridesavepath uncompress="no"></overridesavepath>

<saverelativepath uncompress="yes">NotePad</saverelativepath>

</appitem>

 

<appitem>

<appname>7zip</appname>

<checkversionurl>http://www.7-zip.org/</checkversionurl>

<checkversionregex matchnumber="1"><![CDATA[Download 7-Zip.(.*).\(.*\) for Windows]]></checkversionregex>

<checkdownloadurl>http://www.7-zip.org/download.html</checkdownloadurl>

<checkdownloadregex matchnumber="1"><![CDATA[<A.*?href="(.*x64\.msi)".*?>]]></checkdownloadregex>

<downloadurl use="checkdownloadurl" usereg="no"></downloadurl>

<downloadurlregex  matchnumber="1"></downloadurlregex>

<saveasname useurlpart="yes"></saveasname>

<overridesavepath uncompress="no">C:\Users\ServerAdmin\Desktop\AppVault\test</overridesavepath>

<saverelativepath uncompress="no">7Zip</saverelativepath>

</appitem>

 

<appitem>

<appname>SmarterMail10</appname>

<checkversionurl>http://smartertools.com/smartermail/mail-server-download.aspx</checkversionurl>

<checkversionregex matchnumber="1"><![CDATA[ SmarterMail 10.x \((.*)\)]]></checkversionregex>

<checkdownloadurl></checkdownloadurl>

<checkdownloadregex matchnumber="1"></checkdownloadregex>

<downloadurl usereg="no">http://smartertools.com/Download.aspx?Product=SmarterMail&amp;File=MSIInstaller&amp;Version=10&amp;Location=Primary</downloadurl>

<downloadurlregex  matchnumber="1"></downloadurlregex>

<saveasname useurlpart="no">Smartermail10.msi</saveasname>

<overridesavepath uncompress="no"></overridesavepath>

<saverelativepath uncompress="no">SmarterMail10</saverelativepath>

</appitem>

 

<appitem>

<appname>SmarterMail9</appname>

<checkversionurl>http://smartertools.com/smartermail/releasenotes/v9.aspx</checkversionurl>

<checkversionregex matchnumber="1"><![CDATA[Version (.*)\((.*)\)</h3>]]></checkversionregex>

<checkdownloadurl></checkdownloadurl>

<checkdownloadregex matchnumber="1"></checkdownloadregex>

<downloadurl usereg="no">http://smartertools.com/Download.aspx?Product=SmarterMail&amp;File=MSIInstaller&amp;Version=9&amp;Location=Primary</downloadurl>

<downloadurlregex  matchnumber="1"></downloadurlregex>

<saveasname useurlpart="no">Smartermail9.msi</saveasname>

<overridesavepath uncompress="no"></overridesavepath>

<saverelativepath uncompress="no">SmarterMail9</saverelativepath>

</appitem>

 

<appitem>

<appname>SmarterMail8</appname>

<checkversionurl>http://smartertools.com/smartermail/releasenotes/v8.aspx</checkversionurl>

<checkversionregex matchnumber="1"><![CDATA[Version (.*)\((.*)\)</h3>]]></checkversionregex>

<checkdownloadurl></checkdownloadurl>

<checkdownloadregex matchnumber="1"></checkdownloadregex>

<downloadurl usereg="no">http://smartertools.com/Download.aspx?Product=SmarterMail&amp;File=MSIInstaller&amp;Version=8&amp;Location=Primary</downloadurl>

<downloadurlregex  matchnumber="1"></downloadurlregex>

<saveasname useurlpart="no">Smartermail8.msi</saveasname>

<overridesavepath uncompress="no"></overridesavepath>

<saverelativepath uncompress="no">SmarterMail8</saverelativepath>

</appitem>

</applicationvault>

 

 

 

 

 

########################################################################

# Hostgator Application Repository Updater

# Version .1

# Created by: Mell Rosandich

########################################################################

 

 

 

Param([string]$config,[string]$debug)

#define the options and check for valid options.

if( $config.length -lt 1 ){Write-Host "-config not set switching  to dev location. C:\Users\ServerAdmin\Desktop\applist.xml";$config="C:\Users\ServerAdmin\Desktop\applist.xml";}

if( $debug.length -lt 1 ){Write-Host "-debug not set. for more information use -debug 1, -debug -2";$debug = "0";}

if($debug -ne "0" -and $debug -ne "1" -and $debug -ne "2"){$debug = "0";}

if( Test-Path $config ){

try{

[xml]$DummyTest = Get-Content $config

}

catch{

#if we hit this then there is an error in the file

#could be bad formated XML

Write-Host "The config path you specified was not a well formed XML file."

exit;

}

}

else

{

Write-Host "The config path you specified doesn't exsist"

exit;

}

#Global Scoped vars

$global:basefolderpath

$global:datfolderpath

$global:debugoutput = $debug

 

 

function get-filehashmd5($fileIn) {

if($global:debugoutput -gt 1){write-host "function: get-filehashmd5 File:"  $file}

$file = get-item -literalpath $fileIn

$hashstring = new-object System.Text.StringBuilder

$stream = $file.OpenRead()

if ($stream) {

foreach ($byte in $Provider.ComputeHash($stream)) {

[Void] $hashstring.Append($byte.ToString("X2"))

}

$stream.Close()

}

 

if($global:debugoutput -gt 0){write-host "File Hash: " $hashstring.ToString()}

return  " " + $hashstring.ToString()

}#get-filehashmd5

 

#This will extract the verision number from the website you just need to pass the URL and a regexp to match the text and a match number

function pullURLRegMatch( [string]$inURL , [regex]$inReg, [int]$inMatchNumber){

if($global:debugoutput -gt 1){write-host "function: pullURLRegMatch URL:"  $inURL  ", RegExp: " $inReg  ", Match: "  $inMatchNumber}

[String]$result = $null

$wc = new-object System.Net.WebClient

$result = $wc.Downloadstring( $inURL)

[regex]$pattern =  $inReg

if ($result -match $pattern)

{

return  $matches[$inMatchNumber].trim()

}

return "not found"

}

 

 

#returns Hash if downloaded 0 if fail

function getFileFromURL([string]$inURL,[string]$inSavePath, [string]$doUncompress){

if($global:debugoutput -gt 1){write-host "function: getFileFromURL URL:"  $inURL  ", SavePath: "  $inSavePath }

$RetVal = 1

$isValidPath = Test-Path $inSavePath

if($isValidPath){

Remove-Item $inSavePath

}

else

{

New-Item $inSavePath -type file -value "temp" -Force

Remove-Item $inSavePath

}

write-host "Started Downaloding"

try{

$webclient = New-Object System.Net.WebClient

$webclient.DownloadFile($inURL,$inSavePath)

}catch{return 0}

if($global:debugoutput -gt 0){write-host "Saved to: " $inSavePath}

write-host "End download"

if($global:debugoutput -gt 0){write-host "Uncompress: " $doUncompress}

$RetVal = get-filehashmd5( $inSavePath)

if($global:debugoutput -gt 0){write-host "getFileFromURL: Return Val: " $RetVal}

return $RetVal

}

 

 

function checkDatFilLocalVersion( [string]$AppName )

{

if($global:debugoutput -gt 1){write-host "function: checkDatFilLocalVersion AppName:"  $AppName}

$DT = [DateTime]::Now

$FilePath = $global:datfolderpath + "\" + $AppName + ".xml"

write-host "File Path: " + $FilePath

$isValidPath = Test-Path $FilePath

if( $isValidPath ){

[xml]$LocalAppInfo = Get-Content $FilePath

$LocalAppInfo.application.lastchecked = [string]$DT

$LocalAppInfo.Save($FilePath)

return $LocalAppInfo.application.version

}

else

{

#lets make a blank xml cos this app is new.

$BlankAppInfoXML = "<application>`n`t<name>"+$AppName+"</name>`n`t<filename>"+$AppName+"</filename>`n`t<filemd5>0</filemd5>`n`t<version>0</version>`n`t<lastchecked></lastchecked>`n`t<lastupdated></lastupdated>`n`t<errors>`n`t`t" + '<error time="'+$DT+'">no application.xml (created this file)</error>' + "`n`t</errors>`n</application>"

New-Item $FilePath -type file -value $BlankAppInfoXML

return 0

}

}

function updateApplicationXML(  [string]$AppName, [string]$FileNameSavedAs, [string]$versionFromURL, [string]$FileHashMD){

if($global:debugoutput -gt 1){write-host "function: updateApplicationXML AppName:"  $AppName  ", FileName:"  $FileNameSavedAs  ", versionFromURL:"  $versionFromURL  ", fileHash:"  $FileHashMD }

$DT = [DateTime]::Now

$FilePath = $global:datfolderpath + "\" + $AppName + ".xml"

[xml]$LocalAppInfo = Get-Content $FilePath

$LocalAppInfo.application.version = $versionFromURL

$LocalAppInfo.application.filename = $FileNameSavedAs

$LocalAppInfo.application.lastupdated = [string]$DT

$LocalAppInfo.application.lastchecked = [string]$DTc

$PIECES=$FileHashMD.split(" ")

$NUMBEROFPIECES=$PIECES.Count

$NewHash=$PIECES[$NumberOfPieces-1]

$LocalAppInfo.application.filemd5 = $NewHash

$LocalAppInfo.Save($FilePath)

}

 

[xml]$ApplicatList = Get-Content $config

$global:basefolderpath = $ApplicatList.applicationvault.system.basefolderpath

$global:datfolderpath  = $ApplicatList.applicationvault.system.datfolderpath

$Provider = new-object System.Security.Cryptography.MD5CryptoServiceProvider

 

foreach( $appitem in $ApplicatList.applicationvault.appitem)

{

Write-Host "Checking Application:" $appitem.appname

#Write-Host $appitem.checkversionurl

#Write-Host $appitem.checkversionregex."#cdata-section"

#Write-Host $appitem.saverelativepath."#text"

$RelativePathAdd = ""

if($appitem.saverelativepath."#text" -ne $null){

$RelativePathAdd = $appitem.saverelativepath."#text" + "\"

if($global:debugoutput -gt 0){write-host "Set Relative Path part to:" $RelativePathAdd}

}

$doUncompress = "no"

$versionFromURL = pullURLRegMatch $appitem.checkversionurl  $appitem.checkversionregex."#cdata-section"  $appitem.checkversionregex."matchnumber"

$versionFromDAT = checkDatFilLocalVersion $appitem.appname

if($global:debugoutput -gt 0){write-host "Version From URL:" $versionFromURL "Version From Local XML:" $versionFromDAT }

write-host "Site Version: " $versionFromURL

if( $versionFromURL -ne $versionFromDAT ){

if($global:debugoutput -gt 0){write-host "Stepping into Version Different logic"}

if($appitem.checkdownloadurl -ne ""){

$downloadlink = pullURLRegMatch $appitem.checkdownloadurl  $appitem.checkdownloadregex."#cdata-section"  $appitem.checkdownloadregex."matchnumber"

write-host "Versions are differnt"

if($global:debugoutput -gt 0){write-host "Stepping into CheckDownLoad URL  logic"}

if($appitem.downloadurl."use" -eq "checkdownloadurl"){

if($global:debugoutput -gt 0){write-host "Stepping into CheckDownLoad URL 'Use' checkdownloadurl logic"}

if($appitem.downloadurl."usereg" -eq "yes"){

if($global:debugoutput -gt 0){write-host "Stepping into downloadURL  'Use' regex=yes logic"}

$FullURL = $appitem.checkdownloadurl+$downloadlink

$Directdownloadlink = pullURLRegMatch $FullURL  $appitem.downloadurlregex."#cdata-section"  $appitem.downloadurlregex."matchnumber"

 

if( $appitem.saveasname."useurlpart" -eq "yes" ){

$DlFilename = $Directdownloadlink.split("/")

$FileNameSavedAs = $DlFilename[$DlFilename.length-1]

if($global:debugoutput -gt 0){write-host "Save As Name: using URL parts"}

}

else

{

$FileNameSavedAs = $appitem.saveasname."#text"

if($global:debugoutput -gt 0){write-host "Save As Name: using saveasname from config"}

}

if($appitem.overridesavepath."#text" -ne $null){

$FullSavePath = $appitem.overridesavepath."#text" + '\' + $FileNameSavedAs

if($global:debugoutput -gt 0){write-host "Save Path: using override path: " $FullSavePath}

$doUncompress = $appitem.overridesavepath."uncompress"

}

else

{

$FullSavePath = $global:basefolderpath + '\' + $RelativePathAdd + $FileNameSavedAs

if($global:debugoutput -gt 0){write-host "Save Path: using Relative path: " $FullSavePath}

$doUncompress = $appitem.saverelativepath."uncompress"

}

$filedlMdHash = getFileFromURL $Directdownloadlink $FullSavePath $doUncompress

write-host "File Path:" $FullSavePath

if( $filedlMdHash -ne 0 ){

#Update App XML

updateApplicationXML  $appitem.appname $FileNameSavedAs $versionFromURL $filedlMdHash

}

else

{

Write-host "Error Saving Download"

}

}

else

{

#We didn't use regex to get the link, it was grabed in the first regex attempt

if($global:debugoutput -gt 0){write-host "Stepping into downloadURL  'Use' regex=no logic"}

write-host "Direct Link " $downloadlink

if( $appitem.saveasname."useurlpart" -eq "yes" ){

$DlFilename = $downloadlink.split("/")

$FileNameSavedAs = $DlFilename[$DlFilename.length-1]

if($global:debugoutput -gt 0){write-host "Save As Name: using URL parts"}

}

else

{

$FileNameSavedAs = $appitem.saveasname."#text"

if($global:debugoutput -gt 0){write-host "Save As Name: using saveasname from config"}

}

if($appitem.overridesavepath."#text" -ne $null ){

$FullSavePath = $appitem.overridesavepath."#text" + '\' + $FileNameSavedAs

if($global:debugoutput -gt 0){write-host "Save Path: using override path: " $FullSavePath}

$doUncompress = $appitem.overridesavepath."uncompress"

}

else

{

$FullSavePath = $global:basefolderpath + '\' + $RelativePathAdd  + $FileNameSavedAs

if($global:debugoutput -gt 0){write-host "Save Path: using Relative path: " $FullSavePath}

$doUncompress = $appitem.saverelativepath."uncompress"

}

$filedlMdHash = getFileFromURL $downloadlink $FullSavePath $doUncompress

write-host "File Path:" $FullSavePath

if( $filedlMdHash -ne 0 ){

#Update App XML

updateApplicationXML  $appitem.appname $FileNameSavedAs $versionFromURL $filedlMdHash

}

else

{

Write-host "Error Saving Download"

}

}

}

}#end if $appitem.checkdownloadurl -ne ""

else

{

#This is a direct download from a staic URL

if($global:debugoutput -gt 0){write-host "Stepping into downloadURL  direct link download"}

if( $appitem.saveasname."useurlpart" -eq "yes" )

{

$DlFilename = $downloadlink.split("/")

$FileNameSavedAs = $DlFilename[$DlFilename.length-1]

if($global:debugoutput -gt 0){write-host "Save As Name: using URL parts"}

}

else

{

$FileNameSavedAs = $appitem.saveasname."#text"

if($global:debugoutput -gt 0){write-host "Save As Name: using saveasname from config"}

}

if($appitem.overridesavepath."#text" -ne $null){

$FullSavePath = $appitem.overridesavepath + '\' + $FileNameSavedAs

if($global:debugoutput -gt 0){write-host "Save Path: using override path: " $FullSavePath}

$doUncompress = $appitem.overridesavepath."uncompress"

}

else

{

$FullSavePath = $global:basefolderpath + '\'  + $RelativePathAdd + $FileNameSavedAs

if($global:debugoutput -gt 0){write-host "Save Path: using Relative path: " $FullSavePath}

$doUncompress = $appitem.saverelativepath."uncompress"

}

$filedlMdHash = getFileFromURL $appitem.downloadurl."#text" $FullSavePath $doUncompress

write-host "File Path:" $FullSavePath

if( $filedlMdHash -ne 0 ){

#Update App XML

updateApplicationXML  $appitem.appname $FileNameSavedAs $versionFromURL $filedlMdHash

}

else

{

Write-host "Error Saving Download"

}

}

}

else

{

write-host $appitem.appname is up to date: Nothing done.

}

write-host "-------------------------------------------------------------------------------------"

}