<# .SYNOPSIS Downloads Update packages from specified sources, and updates the Software Repository. .NOTES File Name : USUS.ps1 Author : Jason Lorsung (jason@ususcript.com) Last Update : 2015-12-10 Version : 2.1 Release (2.1) .EXAMPLE USUS.ps1 -ConfigFile "D:\Data\Config.xml" .FLAGS -ConfigFile Use this to specify a Config.XML file for the script to use -DebugEnable Use this to enable Debug output -AddPackage Use this to search USUScript.com for a package and add it -ReplaceExtras Use this to enable extras fields from new packages to override old packages -SkipSoftwareUpdates Use this to skip updating software on this run #> param([Parameter(Mandatory=$True)][string]$ConfigFile, [switch]$DebugEnable, [string]$AddPackage, [switch]$ReplaceExtras, [switch]$SkipSoftwareUpdates) #Get current date and time [string]$Timestamp = $(get-date -f "yyyy-MM-dd HH:mm") #Functions Function Generate-URL ($BitCount, $CurrentVersion, $Package, $WebClient) { IF ($BitCount -eq "32") { IF (!($Package.DownloadURL32)) { IF (($Package.URLGenerator32.URLGenerator).Count -ne 0) { $URLGenerator = "" $Package.URLGenerator32.URLGenerator | ForEach { $URLGenerator = $URLGenerator + "`r`n" + $_ } $URLGenerator = [scriptblock]::Create($URLGenerator) $VersionURL = Invoke-Command -scriptblock {param($CurrentVersion, $WebClient)& $URLGenerator} -ArgumentList $CurrentVersion,$WebClient IF (!($VersionURL -like "Error*") -Or !($VersionURL -like "Exception*")) { IF ($VersionURL.Count -eq 2) { $DownloadURL = $VersionURL[0] [string]$LatestVersion = $VersionURL[1] $LatestVersion = $LatestVersion.Trim() return $DownloadURL, $LatestVersion } ELSEIF ($VersionURL -ne $Null) { $DownloadURL = $VersionURL return $DownloadURL, "No Version Retrieved" } } ELSE { Write-Debug "Error occurred while retrieving URL for package $PackageName The error was $VersionURL" Continue } } } ELSE { $DownloadURL = $Package.DownloadURL32 return $DownloadURL, "No Version Retrieved" } } ELSEIF ($BitCount -eq "64") { IF (!($Package.DownloadURL64)) { IF (($Package.URLGenerator64.URLGenerator).Count -ne 0) { $URLGenerator = "" $Package.URLGenerator64.URLGenerator | ForEach { $URLGenerator = $URLGenerator + "`r`n" + $_ } $URLGenerator = [scriptblock]::Create($URLGenerator) $VersionURL = Invoke-Command -scriptblock {param($CurrentVersion, $WebClient)& $URLGenerator} -ArgumentList $CurrentVersion,$WebClient IF (!($VersionURL -like "Error*") -Or !($VersionURL -like "Exception*")) { IF ($VersionURL.Count -eq 2) { $DownloadURL = $VersionURL[0] [string]$LatestVersion = $VersionURL[1] $LatestVersion = $LatestVersion.Trim() return $DownloadURL, $LatestVersion } ELSEIF ($VersionURL -ne $Null) { $DownloadURL = $VersionURL return $DownloadURL, "No Version Retrieved" } } ELSE { Write-Debug "Error occurred while retrieving URL for package $PackageName The error was $VersionURL" Continue } } } ELSE { $DownloadURL = $Package.DownloadURL64 return $DownloadURL, "No Version Retrieved" } } } Function Get-FtpDirectory{ Param($uri,$cred) [System.Net.FtpWebRequest]$request = [System.Net.WebRequest]::Create($uri) $request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectory $request.Credentials = $cred.GetNetworkCredential() $response = $request.GetResponse() Receive-Stream $response.GetResponseStream() } Function Get-LatestInstaller ($CurentVersion, $DownloadURL, $LatestVersion, $Package, $templocation) { IF ($Package.IsMSI) { IF ($DownloadURL -ne $Null) { IF ($LatestVersion -eq $Null -Or (!($LatestVersion)) -Or $LatestVersion -eq "") { Get-NewInstaller $DownloadURL $templocation [string]$LatestVersion = MSI-Version $templocation IF ($LatestVersion -like "Error*" -Or $LatestVersion -like "Exception*") { Write-Debug $LatestVersion Continue } $LatestVersion = $LatestVersion.Trim() return $LatestVersion } ELSE { IF ($CurrentVersion -ne $LatestVersion) { Get-NewInstaller $DownloadURL $templocation return $LatestVersion } return $LatestVersion } } } ELSE { IF ($DownloadURL) { IF ($LatestVersion -eq $Null -Or (!($LatestVersion)) -Or $LatestVersion -eq "") { Get-NewInstaller $DownloadURL $templocation [string]$LatestVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($templocation).FileVersion $LatestVersion = $LatestVersion.Trim() IF ($LatestVersion -eq $Null -Or $LatestVersion -eq "") { $LatestVersion = (Get-Item $templocation).Length $LatestVersion = $LatestVersion.Trim() } return $LatestVersion } ELSE { IF ($CurrentVersion -ne $LatestVersion) { Get-NewInstaller $DownloadURL $templocation IF ($ForceDownload) { [string]$LatestVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($templocation).FileVersion $LatestVersion = $LatestVersion.Trim() return $LatestVersion } return $LatestVersion } return $LatestVersion } } } } Function Get-NewInstaller([string]$url, [string]$templocation) { TRY { $WebClient.DownloadFile($url,$templocation) } CATCH [System.Net.WebException] { Start-Sleep 30 TRY { $WebClient.DownloadFile($url,$templocation) } CATCH [System.Net.WebException] { Write-Debug "Could not download installer from $url. Please check that the web server is reachable. The error was:" Write-Debug $_.Exception.ToString() Write-Debug "`r`n" } } IF (!(Test-Path $templocation)) { Return $Null, $Null } } Function Get-SoftwareVersion ($BitCount, $CurrentInstaller, $Package, $Software) { IF ($Package.DownloadURL32 -Or $Package.DownloadURL64 -Or $Package.URLGenerator32 -Or $Package.URLGenerator64) { IF ((!($Software.Versions32) -And ($BitCount -eq "32")) -Or (!($Software.Versions64) -And ($BitCount -eq "64"))) { IF ($Package.IsMSI) { IF (!(Test-Path $CurrentInstaller)) { $CurrentVersion = "0" } ELSE { [string]$CurrentVersion = MSI-Version $CurrentInstaller IF ($CurrentVersion -like "Error*" -Or $CurrentVersion -like "Exception*") { Return $CurrentVersion } $CurrentVersion = $CurrentVersion.Trim() IF ($BitCount -eq "32") { $Versions = $SoftwareMaster.CreateElement("Versions32") $Software.AppendChild($Versions) | Out-Null $SoftwareMaster.Save($SoftwareMasterFile) } ELSEIF ($BitCount -eq "64") { $Versions = $SoftwareMaster.CreateElement("Versions64") $Software.AppendChild($Versions) | Out-Null $SoftwareMaster.Save($SoftwareMasterFile) } $version = $SoftwareMaster.CreateElement("version") $Versions.AppendChild($version) | Out-Null $location = $SoftwareMaster.CreateElement("Location") $location.InnerText = $CurrentInstaller $version.AppendChild($location) | Out-Null $version.SetAttribute("name", $CurrentVersion) $SoftwareMaster.Save($SoftwareMasterFile) } return $CurrentVersion, $False } ELSE { IF (!(Test-Path $CurrentInstaller)) { $CurrentVersion = "0" } ELSE { [string]$CurrentVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($CurrentInstaller).FileVersion $CurrentVersion = $CurrentVersion.Trim() $CurrentVersion = $CurrentVersion -split "[\n\r\s]" | Select-Object -Index 0 IF ($CurrentVersion -eq $Null -Or $CurrentVersion -eq "") { $CurrentVersion = (Get-Item $CurrentInstaller).Length } ELSE { IF ($BitCount -eq "32") { $Versions = $SoftwareMaster.CreateElement("Versions32") $Software.AppendChild($Versions) | Out-Null $SoftwareMaster.Save($SoftwareMasterFile) } ELSEIF ($BitCount -eq "64") { $Versions = $SoftwareMaster.CreateElement("Versions64") $Software.AppendChild($Versions) | Out-Null $SoftwareMaster.Save($SoftwareMasterFile) } $version = $SoftwareMaster.CreateElement("version") $Versions.AppendChild($version) | Out-Null $location = $SoftwareMaster.CreateElement("Location") $location.InnerText = $CurrentInstaller $version.AppendChild($location) | Out-Null $version.SetAttribute("name", $CurrentVersion) $SoftwareMaster.Save($SoftwareMasterFile) } } return $CurrentVersion, $False } } ELSE { IF ($BitCount -eq "32") { $CurrentVersion = $Software.Versions32.version | Select-Object -First 1 $CurrentVersion = $CurrentVersion.name IF (!(Test-Path $CurrentInstaller)) { return $CurrentVersion, $True } } ELSEIF ($BitCount -eq "64") { $CurrentVersion = $Software.Versions64.version | Select-Object -First 1 $CurrentVersion = $CurrentVersion.name IF (!(Test-Path $CurrentInstaller)) { return $CurrentVersion, $True } } return $CurrentVersion, $False } } } Function MSI-Version([IO.FileInfo]$Path) { $Property = "ProductVersion" TRY { $WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer $MSIDatabase = $WindowsInstaller.GetType().InvokeMember("OpenDatabase","InvokeMethod",$Null,$WindowsInstaller,@($Path.FullName,0)) $Query = "SELECT Value FROM Property WHERE Property = '$($Property)'" $View = $MSIDatabase.GetType().InvokeMember("OpenView","InvokeMethod",$null,$MSIDatabase,($Query)) $View.GetType().InvokeMember("Execute", "InvokeMethod", $null, $View, $null) $Record = $View.GetType().InvokeMember("Fetch","InvokeMethod",$null,$View,$null) $Value = $Record.GetType().InvokeMember("StringData","GetProperty",$null,$Record,1) return $Value } CATCH { Write-Output $_.Exception.Message } } Function Receive-Stream { Param([System.IO.Stream]$reader,$fileName,$encoding = [System.Text.Encoding]::GetEncoding($Null)) IF($fileName) { $writer = new-object System.IO.FileStream $fileName, "Create" } ELSE { [string]$output = "" } [byte[]]$buffer = new-object byte[] 4096 [int]$total = [int]$count = 0 DO { $count = $reader.Read($buffer, 0, $buffer.Length) IF ($fileName) { $writer.Write($buffer, 0, $count) } ELSE { $output += $encoding.GetString($buffer, 0, $count) } } While ($count -gt 0) $reader.Close() IF (!($fileName)) { $output } } Function Update-Software ($ArchiveOldVersions, $BitCount, $CurrentInstaller, $CurrentVersion, $HumanReadableName, $InstallerName, $LatestVersion, $LocalRepo, $Package, $Software, $SoftwareMaster, $SoftwareMasterFile, $templocation) { IF ($CurrentInstaller -ne $Null) { IF ($CurrentVersion -eq $LatestVersion) { Write-Output "No New Version of $HumanReadableName $BitCount Bit Available`r`n" Start-Job -ScriptBlock { param($FileDelete)& { $Counter = 0 WHILE (Test-Path $FileDelete -And $Counter -lt 13) { Remove-Item $FileDelete -Force -ErrorAction SilentlyContinue Start-Sleep 5 $Counter++ } } } -ArgumentList $templocation | out-null } ELSE { Write-Output "New Version of $HumanReadableName $BitCount Bit Available!`r`n" IF ($ArchiveOldVersions) { IF ($CurrentVersion -ne 0 -And $CurrentVersion -ne $Null) { $OldRepo = $LocalRepo + "\OldVersions" IF (!(Test-Path $OldRepo)) { Try { New-Item $OldRepo -Type Directory -ErrorAction Stop | Out-Null } Catch { Write-Debug "Cannot create archive directory $OldRepo. Skipping Archive Process" } } $OldRepo = $OldRepo + "\" + $CurrentVersion Try { New-Item $OldRepo -Type Directory -ErrorAction Stop | Out-Null } Catch { Write-Debug "Cannot create archive directory $OldRepo. Skipping Archive Process" } Finally { Try { Copy-Item $CurrentInstaller $OldRepo -Force -ErrorAction Stop } Catch { Write-Debug "Cannot archive installer $CurrentInstaller. Skipping Archive Process" } } $ArchiveInstaller = $OldRepo + "\" + $InstallerName IF ($BitCount -eq "32") { $Version = $Software.Versions32.version | Where-Object { $_.name -eq $CurrentVersion } } ELSEIF ($BitCount -eq "64") { $Version = $Software.Versions64.version | Where-Object { $_.name -eq $CurrentVersion } } $Version.Location = $ArchiveInstaller $IsArchived = $SoftwareMaster.CreateElement("IsArchived") IF (!($Version.Updated)) { $Updated = $SoftwareMaster.CreateElement("Updated") $Version.AppendChild($Updated) | Out-Null $Updated.InnerText = $Timestamp } ELSE { $Version.Updated = $Timestamp } $Version.AppendChild($IsArchived) | Out-Null $IsArchived.InnerText = ("True") $SoftwareMaster.Save($SoftwareMasterFile) Remove-Variable Version } } Try { Copy-Item $templocation $LocalRepo -Force -ErrorAction Stop } Catch { write-output "Could not copy new installer to $LocalRepo. Please ensure that this script has Write permissions to this location, and try again.`r`n" } Finally { write-output "$HumanReadableName $BitCount Bit updated to version $LatestVersion !`r`n" } Start-Job -ScriptBlock { param($FileDelete)& { $Counter = 0 WHILE (Test-Path $FileDelete -And $Counter -lt 13) { Remove-Item $FileDelete -Force -ErrorAction SilentlyContinue Start-Sleep 5 $Counter++ } } } -ArgumentList $templocation | out-null $version = $SoftwareMaster.CreateElement("version") IF ($BitCount -eq "32") { IF (!($Software.Versions32)) { $Versions = $SoftwareMaster.CreateElement("Versions32") $Software.AppendChild($Versions) | Out-Null $SoftwareMaster.Save($SoftwareMasterFile) } ELSE { $Versions = $Software.Versions32 } IF ($Package.Extras32) { $version.AppendChild($SoftwareMaster.ImportNode($Package.Extras32,$true)) | Out-Null } } ELSEIF ($BitCount -eq "64") { IF (!($Software.Versions64)) { $Versions = $SoftwareMaster.CreateElement("Versions64") $Software.AppendChild($Versions) | Out-Null $SoftwareMaster.Save($SoftwareMasterFile) } ELSE { $Versions = $Software.Versions64 } IF ($Package.Extras64) { $version.AppendChild($SoftwareMaster.ImportNode($Package.Extras64,$true)) | Out-Null } } $Versions.PrependChild($version) | Out-Null $version.SetAttribute("name", $LatestVersion) $location = $SoftwareMaster.CreateElement("Location") $location.InnerText = $CurrentInstaller $version.AppendChild($location) | Out-Null $Updated = $SoftwareMaster.CreateElement("Updated") $version.AppendChild($Updated) | Out-Null $Updated.InnerText = $Timestamp $SoftwareMaster.Save($SoftwareMasterFile) } } } $WebClient = New-Object System.Net.WebClient IF ($DebugEnable) { $DebugPreference = "Continue" } #Running portion of script IF (!(Test-Path $ConfigFile)) { Write-Output "Your specified config ($ConfigFile) doesn't seem to exist, or the user running this script doesn't have access to read it. Please correct this and try again." Exit } [xml]$Configuration = Get-Content $ConfigFile #Test for required variables IF (!($Configuration.config)) { Write-Output "Your config file seems to be missing its configuration. Please correct this and try again." Exit } IF (!($Configuration.config.softwarerepo)) { Write-Output "Your Software Repo is not defined. Please correct this and try again." Exit } IF (!(Test-Path $Configuration.config.softwarerepo)) { Write-Output "Your specified software repo ($Configuration.config.softwarerepo) doesn't seem to exist, or the user running this script doesn't have access to read it. Please correct this and try again." Exit } IF (!(Test-Path $Configuration.config.packagesrepo)) { Write-Output "Your specified package repo ($Configuration.config.packagesrepo) doesn't seem to exist, or the user running this script doesn't have access to read it. Please correct this and try again." Exit } $PackageMasterFile = $Configuration.config.packagesrepo.TrimEnd("\") + "\PackageMaster.xml" IF (!(Test-Path $PackageMasterFile)) { $PackageMaster = New-Object System.Xml.XmlDocument $Packages = $PackageMaster.CreateElement("Packages") $PackageMaster.AppendChild($Packages) | Out-Null $Packages.AppendChild($PackageMaster.CreateElement("NullPackage")) | Out-Null $PackageMaster.Save($PackageMasterFile) } [xml]$PackageMaster = Get-Content $PackageMasterFile $SoftwareMasterFile = $Configuration.config.softwarerepo.TrimEnd("\") + "\SoftwareMaster.xml" IF (!(Test-Path $SoftwareMasterFile)) { $SoftwareMaster = New-Object System.Xml.XmlDocument $Software = $SoftwareMaster.CreateElement("SoftwarePackages") $SoftwareMaster.AppendChild($Software) | Out-Null $Software.AppendChild($SoftwareMaster.CreateElement("NullSoftware")) | Out-Null $SoftwareMaster.Save($SoftwareMasterFile) Remove-Variable SoftwareMaster } [xml]$SoftwareMaster = Get-Content $SoftwareMasterFile IF ($Configuration.config.SelfUpdate) { $header = "USUS/2.1" $WebClient.Headers.Add("user-agent", $header) $checkurl = "https://www.ususcript.com/api/?selfupdate=true" IF ($Configuration.config.SelfUpdate.AutoUpdate) { $AutoUpdate = $True } IF ($Configuration.config.SelfUpdate.AutoUpdate) { $checkurl = $checkurl + "&autoupdate=true" $AutoUpdate = $True } $newversion = $WebClient.DownloadString($checkurl) IF ($AutoUpdate -And $newversion -ne "No Updated version of USUS available." -And $newversion -ne $Null) { $ScriptLocation = $MyInvocation.InvocationName $relaunchusus = '-ExecutionPolicy Bypass -NoProfile -File "' + $ScriptLocation + '" -ConfigFile "' + $ConfigFile + '"' IF ($SkipSoftwareUpdates) { $relaunchusus = $relaunchusus + " -SkipSoftwareUpdates" } IF ($DebugEnable) { $relaunchusus = $relaunchusus + " -DebugEnable" } Remove-Item $ScriptLocation -Force $newversion | Out-File $ScriptLocation Write-Host "USUS updated!" Start-Process powershell.exe -ArgumentList $relaunchusus Exit } ELSEIF ($newversion -ne "No Updated version of USUS available." -And $newversion -ne $Null) { $newversion = $newversion -split "
" | Select-Object -Index 1 $newversion = $newversion.TrimStart("Version: ") IF (($SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq "USUScript" }).Count -ne 0) { $CurrentPackage = $SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq "USUScript" } | Select-Object $CurrentPackage.LatestVersion = $newversion $SoftwareMaster.Save($SoftwareMasterFile) } ELSE { $USUScript = $SoftwareMaster.CreateElement("software") $SoftwareMaster.SoftwarePackages.AppendChild($USUScript) | Out-Null $USUScript.AppendChild($SoftwareMaster.CreateElement("Name")) | Out-Null $USUScript.Name = "USUScript" $USUScript.AppendChild($SoftwareMaster.CreateElement("CurrentVersion")) | Out-Null $USUScript.CurrentVersion = "2.1" $USUScript.AppendChild($SoftwareMaster.CreateElement("LatestVersion")) | Out-Null $USUScript.LatestVersion = $newversion $SoftwareMaster.Save($SoftwareMasterFile) } } ELSE { IF (($SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq "USUScript" }).Count -ne 0) { $CurrentPackage = $SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq "USUScript" } | Select-Object $CurrentPackage.CurrentVersion = "2.1" $CurrentPackage.LatestVersion = "2.1" $SoftwareMaster.Save($SoftwareMasterFile) } } Remove-Variable header Remove-Variable checkurl IF ($newversion) { Remove-Variable newversion } IF ($AutoUpdate) { Remove-Variable AutoUpdate } IF ($CurrentPackage) { Remove-Variable CurrentPackage } IF ($USUScript) { Remove-Variable USUScript } } Remove-Variable PackageMaster Remove-Variable SoftwareMaster [xml]$PackageMaster = Get-Content $PackageMasterFile [xml]$SoftwareMaster = Get-Content $SoftwareMasterFile IF ($AddPackage -ne "") { $Packagestocheck = $AddPackage -Split "," ForEach ($Package in $Packagestocheck) { $header = "USUS/2.1" $WebClient.Headers.Add("user-agent", $header) $checkurl = "https://www.ususcript.com/api/?packagename=" + $Package + "&packageversion=0&autoupdate=true" $newversion = $WebClient.DownloadString($checkurl) IF ((!($newversion -like "No Updated versions of *")) -And $newversion -ne $Null) { $updatedpackagelocation = $Configuration.config.packagesrepo.TrimEnd("\") + "\" + $Package + ".xml" $newversion | Out-File $updatedpackagelocation } ELSE { Write-Output "No Package named $Package available from USUScript.com" Write-Output "Sorry about that." } Remove-Variable Package Remove-Variable header Remove-Variable checkurl IF ($newversion) { Remove-Variable newversion } IF ($updatedpackagelocation) { Remove-Variable updatedpackagelocation } IF ($CurrentPackage) { Remove-Variable CurrentPackage } IF ($PackageInfo) { Remove-Variable PackageInfo } } Remove-Variable AddPackage Remove-Variable Packagestocheck } Remove-Variable PackageMaster Remove-Variable SoftwareMaster [xml]$PackageMaster = Get-Content $PackageMasterFile [xml]$SoftwareMaster = Get-Content $SoftwareMasterFile IF ($Configuration.config.PackageUpdate) { IF ($Configuration.config.PackageUpdate.AutoUpdate) { $AutoUpdate = $True } ForEach ($Package in $PackageMaster.Packages.Package) { $PackageName = $Package.Name $PackageVersion = $Package.Version $PackageVerify = $Package.Verify $header = "USUS/2.10001" $WebClient.Headers.Add("user-agent", $header) $checkurl = "https://www.ususcript.com/api/?packagename=" + $PackageName + "&packageversion=" + $PackageVersion IF ($AutoUpdate) { $checkurl = $checkurl + "&autoupdate=true" } IF (!($PackageVerify -like "Private USUS XML Package File")) { $newversion = $WebClient.DownloadString($checkurl) IF ($AutoUpdate -And (!($newversion -like "No Updated versions of *")) -And $newversion -ne $Null) { $updatedpackagelocation = $Configuration.config.packagesrepo.TrimEnd("\") + "\" + $PackageName + ".xml" IF (($SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq $PackageName }).Count -ne 0) { $CurrentPackage = $SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq $PackageName } IF ($CurrentPackage.PackageInfo) { IF ($CurrentPackage.PackageInfo.NewVersion) { $CurrentPackage.PackageInfo.RemoveChild($CurrentPackage.PackageInfo.SelectSingleNode("NewVersion")) | Out-Null $SoftwareMaster.Save($SoftwareMasterFile) } } } $newversion | Out-File $updatedpackagelocation } ELSEIF ((!($newversion -like "No Updated versions of *")) -And $newversion -ne $Null) { $newversion = $newversion -split "
" | Select-Object -Index 1 $newversion = $newversion.TrimStart("Version: ") IF (($SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq $PackageName }).Count -ne 0) { $CurrentPackage = $SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq $PackageName } IF (!($CurrentPackage.PackageInfo)) { $PackageInfo = $SoftwareMaster.CreateElement("PackageInfo") $CurrentPackage.AppendChild($PackageInfo) | Out-Null $PackageInfo.AppendChild($Softwaremaster.CreateElement("NullInfo")) | Out-Null } ELSE { $PackageInfo = $CurrentPackage.PackageInfo } IF (!($PackageInfo.NewVersion)) { $PackageInfo.AppendChild($SoftwareMaster.CreateElement("NewVersion")) | Out-Null } $PackageInfo.NewVersion = $newversion $SoftwareMaster.Save($SoftwareMasterFile) } ELSE { Write-Debug "Cannot write record for new version of $PackageName package!" Write-Host "New version of $PackageName package available!" } } ELSE { IF (($SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq $PackageName }).Count -ne 0) { $CurrentPackage = $SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq $PackageName } | Select-Object IF ($CurrentPackage.PackageInfo) { IF ($CurrentPackage.PackageInfo.NewVersion) { $CurrentPackage.PackageInfo.RemoveChild($CurrentPackage.PackageInfo.SelectSingleNode("NewVersion")) | Out-Null $SoftwareMaster.Save($SoftwareMasterFile) } } } } } Remove-Variable PackageName Remove-Variable PackageVersion Remove-Variable PackageVerify Remove-Variable header Remove-Variable checkurl IF ($newversion) { Remove-Variable newversion } IF ($updatedpackagelocation) { Remove-Variable updatedpackagelocation } IF ($CurrentPackage) { Remove-Variable CurrentPackage } IF ($PackageInfo) { Remove-Variable PackageInfo } } IF ($AutoUpdate) { Remove-Variable AutoUpdate } } Remove-Variable PackageMaster Remove-Variable SoftwareMaster [xml]$PackageMaster = Get-Content $PackageMasterFile $UnimportedPackages = Get-ChildItem $Configuration.config.packagesrepo -Exclude *Example*, *Template*, PackageMaster.xml -Include *.xml -Recurse | Where-Object { !$_.PSIsContainer} IF ($Configuration.config.replaceextras) { $ReplaceExtras = $True } ForEach ($UnimportedPackage in $UnimportedPackages) { [xml]$Package = Get-Content $UnimportedPackage IF (($Package.SelectNodes("//Name") | Where-Object { $_.InnerText -ne $Null }) -eq $Null) { Write-Debug "Package $UnimportedPackage doesn't seem to be valid, skipping..." Remove-Variable Package Continue } IF (($Package.SelectNodes("//Verify") | Where-Object { $_.InnerText -eq "USUS XML Package File" -And $_.InnerText -ne $Null -Or ($_.InnerText -eq "Private USUS XML Package File" -And $_.InnerText -ne $Null)}) -eq $Null) { Write-Debug "Package $UnimportedPackage doesn't seem to be valid, skipping..." Remove-Variable Package Continue } $PackageName = $Package.package.Name $HumanReadableName = $Package.package.HumanReadableName IF (($PackageMaster.Packages.Package | Where-Object { $_.Name -eq $PackageName }).Count -ne 0) { $CurrentPackage = $PackageMaster.Packages.Package | Where-Object { $_.Name -eq $PackageName } | Select-Object [int]$CurrentVersion = $CurrentPackage.Version [int]$LatestVersion = $Package.package.Version IF ($CurrentVersion -ge $LatestVersion) { Write-Debug "Package $UnimportedPackage already exists in Package Master, skipping..." Remove-Item $UnimportedPackage Remove-Variable CurrentPackage Remove-Variable CurrentVersion Remove-Variable LatestVersion Remove-Variable Package Continue } ELSEIF ($CurrentVersion -lt $LatestVersion) { IF (!($ReplaceExtras)) { IF ($CurrentPackage.Extras32) { IF ($Package.package.Extras32) { $Package.package.RemoveChild($Package.package.SelectSingleNode("Extras32")) | Out-Null } $Package.package.AppendChild($Package.ImportNode($CurrentPackage.Extras32,$true)) | Out-Null } IF ($CurrentPackage.Extras64) { IF ($Package.package.Extras64) { $Package.package.RemoveChild($Package.package.SelectSingleNode("Extras64")) | Out-Null } $Package.package.AppendChild($Package.ImportNode($CurrentPackage.Extras64,$true)) | Out-Null } } $CurrentPackage.ParentNode.RemoveChild($CurrentPackage) | Out-Null Write-Output "`r`n`r`n$HumanReadableName Package XML Updated to Version $LatestVersion" Remove-Variable CurrentPackage Remove-Variable CurrentVersion Remove-Variable HumanReadableName Remove-Variable LatestVersion $PackageMaster.Packages.AppendChild($PackageMaster.ImportNode($Package.Package,$true)) | Out-Null Remove-Item $UnimportedPackage $PackageMaster.Save($PackageMasterFile) Remove-Variable Package $Resort = $True Continue } } $PackageMaster.Packages.AppendChild($PackageMaster.ImportNode($Package.Package,$true)) | Out-Null Remove-Item $UnimportedPackage $PackageMaster.Save($PackageMasterFile) Write-Output "`r`n`r`n$HumanReadableName Package XML Imported." Remove-Variable HumanReadableName Remove-Variable Package $Resort = $True } IF ($Resort) { #Cleanup Package Master File $PackageMaster.Packages.Package | Sort-Object { $_.Name } | ForEach { $PackageMaster.Packages.AppendChild($_) | Out-Null } [xml]$PackageMasterOriginal = Get-Content $PackageMasterFile $PackageMaster.Save($PackageMasterFile) } #Reload Package and Software Masters before running IF ($PackageMaster) { Remove-Variable PackageMaster } IF ($SoftwareMaster) { Remove-Variable SoftwareMaster } [xml]$PackageMaster = Get-Content $PackageMasterFile [xml]$SoftwareMaster = Get-Content $SoftwareMasterFile IF ($Configuration.config.ArchiveOldVersions) { $ArchiveOldVersions = $True } ELSE { $ArchiveOldVersions = $False } Write-Output "`r`n`r`n" IF ((!$SkipSoftwareUpdates)) { ForEach ($Package in $PackageMaster.Packages.Package) { $PackageName = $Package.Name $HumanReadableName = $Package.HumanReadableName IF (!(($SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq $PackageName }).Count -ne 0)) { $Software = $SoftwareMaster.CreateElement("software") $SoftwareMaster.SoftwarePackages.AppendChild($Software) | Out-Null $Software.AppendChild($SoftwareMaster.CreateElement("Name")) | Out-Null $Software.Name = $PackageName $Software.AppendChild($SoftwareMaster.CreateElement("HumanReadableName")) | Out-Null $Software.HumanReadableName = $HumanReadableName IF ($Package.IsMSI) { $Software.AppendChild($SoftwareMaster.CreateElement("IsMSI")) | Out-Null $Software.IsMSI = "True" } $SoftwareMaster.Save($SoftwareMasterFile) } ELSE { $Software = $SoftwareMaster.SoftwarePackages.software | Where-Object { $_.Name -eq $PackageName } } IF ($Package.CustomPath) { $LocalRepo = $Package.CustomPath IF (!(Test-Path $LocalRepo)) { Write-Output "Software Repository $LocalRepo doesn't seem to exist. Please create this location or run this script with the credentials required to access it." Continue } } ELSE { $LocalRepo = $Configuration.config.softwarerepo } $LocalRepo = $LocalRepo + "\" + $Package.Name IF (!(Test-Path $LocalRepo)) { Try { New-Item $LocalRepo -Type Directory -ErrorAction Stop | Out-Null } Catch { Write-Output "Could not create program directory of $LocalRepo. Please ensure that this script has Write permissions to this location, and try again.`r`n" } } $CurrentInstaller = $LocalRepo + "\" + $Package.Name IF ($Package.DownloadURL32 -Or $Package.URLGenerator32) { $CurrentInstaller32 = $CurrentInstaller + "-x32" $InstallerName32 = $Package.Name + "-x32" $templocation32 = $env:TEMP + "\" + $Package.Name + "-x32" IF ($Package.IsMSI) { $CurrentInstaller32 = $CurrentInstaller32 + ".msi" $InstallerName32 = $InstallerName32 + ".msi" $templocation32 = $templocation32 + ".msi" } ELSE { $CurrentInstaller32 = $CurrentInstaller32 + ".exe" $InstallerName32 = $InstallerName32 + ".exe" $templocation32 = $templocation32 + ".exe" } $GetSoftwareVersionResults = Get-SoftwareVersion -BitCount "32" -CurrentInstaller $CurrentInstaller32 -Package $Package -Software $Software IF ($GetSoftwareVersionResults -like "Error*" -Or $GetSoftwareVersionResults -like "Exception*") { Write-Debug $GetSoftwareVersionResults $CurrentVersion = "0" $ForceDownload = $True } ELSE { $CurrentVersion = $GetSoftwareVersionResults[0] $ForceDownload = $GetSoftwareVersionResults[1] } $GenerateURLResults = Generate-URL -BitCount "32" -CurrentVersion $CurrentVersion -Package $Package -WebClient $WebClient $DownloadURL = $GenerateURLResults[0] IF ($GenerateURLResults[1] -eq "No Version Retrieved") { $LatestVersion = "This should never match anything ever. Period. If it does, someone has gone HORRIBLY wrong in their versioning scheme. Hit Them." $LatestVersion = $Null } ELSE { $LatestVersion = $GenerateURLResults[1] } IF ($ForceDownload) { $LatestVersion = $Null } $LatestVersion = Get-LatestInstaller -CurrentVersion $CurentVersion -DownloadURL $DownloadURL -LatestVersion $LatestVersion -Package $Package -templocation $templocation32 IF ($LatestVersion -eq "This should never match anything ever. Period. If it does, someone has gone HORRIBLY wrong in their versioning scheme. Hit Them.") { Write-Debug "Wow. I mean WOW! Please find this developer and hit them. HARD. Their version string was actually 'This should never match anything ever. Period. If it does, someone has gone HORRIBLY wrong in their versioning scheme. Hit Them.'. There are no words." } Update-Software -ArchiveOldVersions $ArchiveOldVersions -BitCount "32" -CurrentInstaller $CurrentInstaller32 -CurrentVersion $CurrentVersion -HumanReadableName $HumanReadableName -InstallerName $InstallerName32 -LatestVersion $LatestVersion -LocalRepo $LocalRepo -Package $Package -Software $Software -SoftwareMaster $SoftwareMaster -SoftwareMasterFile $SoftwareMasterFile -templocation $templocation32 } IF ($Package.DownloadURL64 -Or $Package.URLGenerator64) { $CurrentInstaller64 = $CurrentInstaller + "-x64" $InstallerName64 = $Package.Name + "-x64" $templocation64 = $env:TEMP + "\" + $Package.Name + "-x64" IF ($Package.IsMSI) { $CurrentInstaller64 = $CurrentInstaller64 + ".msi" $InstallerName64 = $InstallerName64 + ".msi" $templocation64 = $templocation64 + ".msi" } ELSE { $CurrentInstaller64 = $CurrentInstaller64 + ".exe" $InstallerName64 = $InstallerName64 + ".exe" $templocation64 = $templocation64 + ".exe" } $GetSoftwareVersionResults = Get-SoftwareVersion -BitCount "64" -CurrentInstaller $CurrentInstaller64 -Package $Package -Software $Software $CurrentVersion = $GetSoftwareVersionResults[0] $ForceDownload = $GetSoftwareVersionResults[1] $GenerateURLResults = Generate-URL -BitCount "64" -CurrentVersion $CurrentVersion -Package $Package -WebClient $WebClient $DownloadURL = $GenerateURLResults[0] IF ($GenerateURLResults[1] -eq "No Version Retrieved") { $LatestVersion = "This should never match anything ever. Period. If it does, someone has gone HORRIBLY wrong in their versioning scheme. Hit Them." $LatestVersion = $Null } ELSE { $LatestVersion = $GenerateURLResults[1] } IF ($ForceDownload) { $LatestVersion = $Null } $LatestVersion = Get-LatestInstaller -CurrentVersion $CurentVersion -DownloadURL $DownloadURL -ForceDownload $ForceDownload -LatestVersion $LatestVersion -Package $Package -templocation $templocation64 IF ($LatestVersion -eq "This should never match anything ever. Period. If it does, someone has gone HORRIBLY wrong in their versioning scheme. Hit Them.") { Write-Debug "Wow. I mean WOW! Please find this developer and hit them. HARD. Their version string was actually 'This should never match anything ever. Period. If it does, someone has gone HORRIBLY wrong in their versioning scheme. Hit Them.'. There are no words." } Update-Software -ArchiveOldVersions $ArchiveOldVersions -BitCount "64" -CurrentInstaller $CurrentInstaller64 -CurrentVersion $CurrentVersion -HumanReadableName $HumanReadableName -InstallerName $InstallerName64 -LatestVersion $LatestVersion -LocalRepo $LocalRepo -Package $Package -Software $Software -SoftwareMaster $SoftwareMaster -SoftwareMasterFile $SoftwareMasterFile -templocation $templocation64 IF ($VersionURL) { Remove-Variable VersionURL } } } } ELSE { Write-Debug "Skipping Software Updates!" } IF ($Resort) { #Cleanup Software Master File $SoftwareMaster.SoftwarePackages.software | Sort-Object { $_.Name } | ForEach { $SoftwareMaster.SoftwarePackages.AppendChild($_) | Out-Null } $SoftwareMaster.Save($SoftwareMasterFile) } #End