Function EnsureGuiName ($strFolder)
{
$strFolder = BackslashTrailToFolder($strFolder)
[string]$strFolderGui = “Company.Program.Gui\”
if ($strFolder.Length -lt $strFolderGui.Length)
{
[int]$intStartIx = 0
}
else
{
[int]$intStartIx = $strFolder.Length – $strFolderGui.Length
}
if ($strFolder.Substring($intStartIx) -ne $strFolderGui)
{
$strFolder += $strFolderGui
}
if ($strFolder.Substring(0, “D:\Websites\”.Length) -ne “D:\Websites\”)
{
$strFolder = “D:\Websites\” + $strFolder
}
return $strFolder
}
function Expand-File($file, $destination)
{
if ((Test-Path $destination) -eq $false)
{ New-Item -Path (Split-Path -Path $destination -Parent) -Name (Split-Path -Path $destination -Leaf) -ItemType directory | Out-Null }
$shell = new-object -com shell.application
$zip = $shell.NameSpace($file)
foreach($item in $zip.items())
{
$shell.Namespace($destination).copyhere($item)
}
}
function TestRequirementFilesys($astrFileList, $strLog)
{
[bool]$blnResult = $true
For ($i=0; $i -lt ($astrFileList.Count); $i++)
{
Write-Host “Testing “ $astrFileList[$i] ” ... “ -NoNewline
if ((Test-Path $astrFileList[$i]) -eq $false)
{
Add-Content -Value ($astrFileList[$i] + ” missing”) -Path $strLog
Write-Host “`n”
Throw ($astrFileList[$i] + ” missing”)
$blnResult = $false
}
else
{
Write-Host “OK”
}
}
if ($PSVersionTable.PSVersion.Major -lt 4)
{
Add-Content -Value “This script requires at least version 4 of PowerShell (in WMF 4, http://www.microsoft.com/en-us/download/details.aspx?id=40855)." -Path $strLog -PassThru
$blnResult = $false
}
return $blnResult
}
function GetDevExpressVersionFromProgramVersion($strNewVersion)
{
[int]$intProgMainVersion = ($strNewVersion.Split(”.”))[0]
switch ($intProgMainVersion)
{
2 {
return 9
}
3 {
return 15
}
}
}
function GetFilePropTags([string]$strPath)
{
$objShell = New-Object -COMObject Shell.Application
[string]$strFolder = Split-Path $strPath
[string]$strFile = Split-Path $strPath -Leaf
$objShellfolder = $objShell.Namespace($strFolder)
$objShellfile = $objShellfolder.ParseName($strFile)
# To get a list of index numbers and their meaning, use this:
# 0..287 | Foreach-Object { '{0} = {1}' -f $, $shellfolder.GetDetailsOf($null, $) }
[int]$intExtFilePropsTags = 18
$objShellfolder.GetDetailsOf($objShellfile, $intExtFilePropsTags)
}
function GetMsiProdVer([string]$strPath)
{
$strTagsFromMsi = GetFilePropTags($strPath)
[string[]]$astrFileTags = $strTagsFromMsi.Split(”,”)
[int[]]$aintVno = ($astrFileTags[1]).split(”.”)
[string]::Join(”.”, $aintVno)
}
function GetDevExpressVersion([string]$strDevExpressFolder)
{
$dirDevExpress = Get-ChildItem $strDevExpressFolder *.dll
((Get-ItemProperty ($dirDevExpress[0].FullName)).VersionInfo).FileVersion
}
#endregion
$hshProgramUpdaterSettings = Get-IniContent $IniFileUser
$hshProgramUpdaterSettings += Get-IniContent $IniFileWebConfig
[string]$strDeploymentFolder = “D:\Websites\Deploy\”
[string]$strLogFolder = $strDeploymentFolder + “UpdateLogs\” + (Get-Date -format “yyyyMMdd.HHmm”) + “h\”
if ((Test-Path $strLogFolder) -eq $false)
{ New-Item -Path (Split-Path -Path $strLogFolder -Parent) -Name (Split-Path -Path $strLogFolder -Leaf) -ItemType directory | Out-Null }
[string]$strLog = $strLogFolder + “ProgramUpdater“ + (Get-Date -format “yyyyMMddHHmm”) + “h.log”
if ( ( $hshProgramUpdaterSettings[“HeaderUser”][“Version”] -ne $strIniVersion ) -or ( $hshProgramUpdaterSettings[“HeaderWebConfig”][“Version”] -ne $strIniVersion ) )
{
Add-Content -Value “Wrong version of at least 1 .ini.” -Path $strLog -PassThru
Exit
}
[string]$strVerMsSql = $hshProgramUpdaterSettings[“MssqlVersionen”][“DEFAULT”]
[string]$strHostname = $env:COMPUTERNAME
if ($null -ne $hshProgramUpdaterSettings[“MssqlVersionen”][$strHostname])
{ $strVerMsSql = $hshProgramUpdaterSettings[“MssqlVersionen”][$strHostname] }
[string]$strWebsiteFolder = $hshProgramUpdaterSettings[“Website folder to Upgrade”][“Folder”]
# $strWebsiteFolder.Trim(” “)
while ( $strWebsiteFolder.EndsWith(” “) ) { $strWebsiteFolder = $strWebsiteFolder.Substring( 0, ($strWebsiteFolder.Length – 1) ) }
$strWebsiteFolder = EnsureGuiName($strWebsiteFolder)
[string]$strIISWebsiteName = (Get-Website | Where-Object -Property “PhysicalPath” -EQ -Value (FolderNameWoTrailingBackslash($strWebsiteFolder))).Name
[string]$strIISAppPool = (Get-Item (“IIS:\Sites\” + $strIISWebsiteName) | Select-Object applicationPool).applicationPool
[string]$strDeployZipFile = $strDeploymentFolder + “Company.Program.CC.Web.Gui.” + $strVerMsSql + ”.zip”
[string]$strOldVersion = ((Get-ItemProperty ($strWebsiteFolder + “bin\Company.Program.BusinessLogik.dll”)).VersionInfo).ProductVersion
$msidir = Get-Item ($strDeploymentFolder + “Company.Program.Nb.Setup.” + $strVerMsSql + ”.*.msi”)
[string]$strFirstMsiNewVer = $strDeploymentFolder + ($msidir[0].Name)
[string]$strNewVersion = GetMsiProdVer($strFirstMsiNewVer)
while ($null -eq $strNewVersion -or $strNewVersion -eq ””)
{
Write-Host “Die Zielversion konnte nicht aus $strFirstMsiNewVer ermittelt werden, bitte hier eingeben ('3.xx.x.xxxxx'):” -ForegroundColor Red
$strNewVersion = Read-Host
}
[string]$strDevExpressFolder = $strDeploymentFolder + “DevExpress{0}\” -f (GetDevExpressVersionFromProgramVersion($strNewVersion))
[string]$strBackupFolder = FolderNameWoTrailingBackslash($strWebsiteFolder)
$strBackupFolder += ““
$strBackupFolder += $strOldVersion
$strBackupFolder += ““
$strBackupFolder += (Get-Date -format “yyyyMMdd.HHmm”)
$strBackupFolder += “h\”
Write-Host -BackgroundColor Gray -ForegroundColor Blue -Object “n
nEffective Parameters for current run of this script”
[string]$strThisScriptVersion = (Get-Help $PSCommandPath -Full).alertSet.alert[0] -split(“`n”) -match “Version: “ -replace(”}”,””)
$objParamTable = New-Object PSObject
$objParamTable | Add-Member “Ini Files” ($IniFileUser + ”, “ + $IniFileWebConfig + ” — optional command line parameters”)
$objParamTable | Add-Member “Website folder” $strWebsiteFolder
$objParamTable | Add-Member “This script's version” $strThisScriptVersion
$objParamTable | Add-Member “IIS website name” $strIISWebsiteName
$objParamTable | Add-Member “IIS application pool name” $strIISAppPool
$objParamTable | Add-Member “Old version” $strOldVersion
$objParamTable | Add-Member “New version” $strNewVersion
$objParamTable | Add-Member “MS SQL version” $strVerMsSql
$objParamTable | Add-Member “Deploy folder” $strDeploymentFolder
$objParamTable | Add-Member “Deploy zip file” $strDeployZipFile
$objParamTable | Add-Member “DevExpress folder” $strDevExpressFolder
$objParamTable | Add-Member “Backup folder” $strBackupFolder
$objParamTable | Add-Member “Log folder” $strLogFolder
$objParamTable | Format-List
[string[]]$astrFileList = ($strDeploymentFolder + “.msi”)
$astrFileList += ($strDeploymentFolder + “UpgradeTool-” + $strVerMsSql + ”.exe”)
$astrFileList += $strDeployZipFile
$astrFileList += ($strDevExpressFolder + ““)
$astrFileList += ($strWebsiteFolder + “*”)
[bool]$blnResult = TestRequirementFilesys $astrFileList $strLog
if ($blnResult -eq $false)
{
Exit
}
Write-Host -BackgroundColor Gray -ForegroundColor Blue -Object “If necessary, stop and run script again. Run '.\ProgramUpdater.ps1 –?' for more details.”
Write-Host -BackgroundColor Gray -ForegroundColor Red -Object “If you don't understand what this script does read the <Program> installation guides.”
[string]$strTitle = “ProgramUpdater”
[string]$strMessage = “Do you want to go on?”
$yes = New-Object System.Management.Automation.Host.ChoiceDescription “&Yes”,
<span style="color:#4070a0">"Go on."</span>
<span style="color:#19177c">$no</span> = <span style="color:#06287e">New-Object</span> System.<span style="color:#06287e">Management</span>.<span style="color:#06287e">Automation</span>.<span style="color:#06287e">Host</span>.<span style="color:#06287e">ChoiceDescription</span> <span style="color:#4070a0">"&No"</span>,
“Exit the script.”
$options = System.Management.Automation.Host.ChoiceDescription[]
[int]$intResult = $host.ui.PromptForChoice($strTitle, $strMessage, $options, 1)
switch ($intResult)
{
1 {Exit}
}
[string]$strFQDNThisMachine = [System.Net.Dns]::GetHostByName((hostname)).HostName
Add-Content -Value (“Computer name (FQDN): “ + $strFQDNThisMachine) -Path $strLog
Add-Content -Value (“Script starter: “ + $env:USERDOMAIN + “\” + $env:USERNAME) -Path $strLog
Add-Content -Value (“Website folder: “ + $strWebsiteFolder) -Path $strLog
Add-Content -Value (“Deploy folder: “ + $strDeploymentFolder) -Path $strLog
Add-Content -Value (“Dev express folder: “ + $strDevExpressFolder) -Path $strLog
Add-Content -Value (“Backup folder: “ + $strBackupFolder) -Path $strLog
Add-Content -Value (“New version: “ + $strNewVersion) -Path $strLog
Add-Content -Value (“IIS website name: “ + $strIISWebsiteName) -Path $strLog
Add-Content -Value (“IIS application pool name: “ + $strIISAppPool) -Path $strLog
Add-Content -Value (“MS SQL version: “ + $strVerMsSql) -Path $strLog
Add-Content -Value (“n
n”) -Path $strLog
# Out-Null: Do not continue before this line has been completely executed
Stop-Website -Name $strIISWebsiteName | Out-Null
Stop-WebAppPool -Name $strIISAppPool | Out-Null
Add-Content -Value (“Attempted to stop IIS website “ + $strIISWebsiteName + ““ + (Get-Date -format “yyyyMMddHHmm”)) -Path $strLog -PassThru
Add-Content -Value (“Attempted to stop IIS application pool “ + $strIISAppPool + ““ + (Get-Date -format “yyyyMMddHHmm”)) -Path $strLog -PassThru
Add-Content -Value (“Attempting to ensure apppool” + $strIISAppPool + ” and website “ + $strIISWebsiteName + ” are stopped. _ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Add-Content -Value (“Apppool “ + $strIISAppPool + ” status: “ + (Get-WebAppPoolState $strIISAppPool).Value + ”. _ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Add-Content -Value (“Website “ + $strIISWebsiteName + ” status: “ + (Get-WebsiteState $strIISWebsiteName).Value + ”. _ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
“Waiting” | Out-Null
[int]$intSec = 0
while ( ( (Get-WebAppPoolState $strIISAppPool).Value -ne “Stopped” ) -and ( (Get-WebsiteState $strIISWebsiteName).Value -ne “Stopped” ) )
{
Start-Sleep 2
$intSec += 2
Add-Content -Value (“Waited “ + $intSec + ” of 60 seconds. _ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
if ($intSec -eq 60)
{
Add-Content -Value (“apppool and website apparently still running, exiting. _ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Exit
}
}
[string]$strNewVerFolder = FolderNameWoTrailingBackslash($strWebsiteFolder)
$strNewVerFolder += “_New\”
Expand-File -file $strDeployZipFile -destination $strNewVerFolder | Out-Null
Add-Content -Value (“Unzipped “ + $strDeployZipFile + ” “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Remove-Item -Path ($strWebsiteFolder + “bin\DevExpress“) -Force -Recurse | Out-Null
Add-Content -Value (“Deleted “ + $strWebsiteFolder + “bin\DevExpress “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
if ((Test-Path $strNewVerFolder) -eq $false)
{ New-Item -Path (Split-Path -Path $strNewVerFolder -Parent) -Name (Split-Path -Path $strNewVerFolder -Leaf) -ItemType directory | Out-Null }
if ((Test-Path $strBackupFolder) -eq $false)
{ New-Item -Path (Split-Path -Path $strBackupFolder -Parent) -Name (Split-Path -Path $strBackupFolder -Leaf) -ItemType directory | Out-Null }
Copy-Item -Path ($strDevExpressFolder + ““) -Destination ($strNewVerFolder + “bin”) -Force | Out-Null
Add-Content -Value (“Copied “ + $strDevExpressFolder + “ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
try
{
Move-Item -Path ($strWebsiteFolder + ““) -Destination $strBackupFolder -Exclude “Log”,“Setup”,“Temp”,“logo” -Force -ErrorAction SilentlyContinue | Out-Null
}
catch
{
}
Add-Content -Value (“Moved “ + $strWebsiteFolder + “ except Log\, Setup\, Temp\, logo\ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Copy-Item -Path ($strWebsiteFolder + “*”) -Destination $strBackupFolder -Force -Recurse | Out-Null
Add-Content -Value (“Copied “ + $strWebsiteFolder + “\Log\, ...\Setup\, ...\Temp\, ...\logo\ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
AdaptWebConfig $strNewVerFolder $strBackupFolder $strNewVersion $strLog $hshProgramUpdaterSettings
Remove-Item -Path ($strWebsiteFolder + “Setup\Company.Program.Nb.Setup..msi”) -Force | Out-Null
Add-Content -Value (“Deleted “ + $strWebsiteFolder + “Setup\Company.Program.Nb.Setup..msi “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
[string]$strMsiCopyPath = $strWebsiteFolder + “Setup\msi”
if ((Test-Path $strMsiCopyPath) -eq $false)
{
New-Item -Path (Split-Path -Path $strMsiCopyPath -Parent) -Name (Split-Path -Path $strMsiCopyPath -Leaf) -ItemType directory | Out-Null
}
else
{
Remove-Item -Path ($strMsiCopyPath + “\Company.Program.Nb.Setup.*.msi”) -Force | Out-Null
}
[string]$strWebConfigMsiPath = $strMsiCopyPath + “\web.config”
if ((Test-Path $strWebConfigMsiPath) -eq $false)
{
$strWebConfigMsiContent | Out-File $strWebConfigMsiPath -Force -Encoding utf8
[string]$strWebConfigMsiAttr = (Get-Item -Force $strWebConfigMsiPath).Attributes -join(”,”)
if ($strWebConfigMsiAttr -notmatch(“Hidden”))
{
(Get-Item -Force $strWebConfigMsiPath).Attributes = $strWebConfigMsiAttr + ”,Hidden”
}
Add-Content -Value (“Created “ + $strWebConfigMsiPath + ” “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
}
Add-Content -Value (“Deleted “ + $strWebsiteFolder + “Setup\msi\Company.Program.Nb.Setup.*.msi “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Remove-Item -Path ($strWebsiteFolder + “Setup\UpgradeLog.txt”) -Force | Out-Null
Add-Content -Value (“Deleted “ + $strWebsiteFolder + “Setup\UpgradeLog.txt “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Remove-Item -Path ($strWebsiteFolder + “Setup\UpgradeTool-” + $strVerMsSql + ”.exe”) -Force | Out-Null
Add-Content -Value (“Deleted “ + $strWebsiteFolder + “Setup\UpgradeTool-” + $strVerMsSql + ”.exe “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Remove-Item -Path ($strWebsiteFolder + “Log*.“) -Force | Out-Null
Add-Content -Value (“Deleted “ + $strWebsiteFolder + “Log*. “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
while ((Get-ChildItem $strNewVerFolder).Length -gt 0)
{
Move-Item -Path ($strNewVerFolder + ““) -Destination $strWebsiteFolder -Force -ErrorAction SilentlyContinue | Out-Null
}
Add-Content -Value (“Moved “ + $strNewVerFolder + “ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Remove-Item -Path ($strNewVerFolder) -Force -Recurse | Out-Null
Add-Content -Value (“Deleted “ + $strNewVerFolder + ” “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Copy-Item -Path ($strDeploymentFolder + “Company.Program.Nb.Setup.” + $strVerMsSql + “.msi”) -Destination ($strWebsiteFolder + “Setup”) -Force | Out-Null
Add-Content -Value (“Copied “ + $strDeploymentFolder + “Company.Program.Nb.Setup.” + $strVerMsSql + “.msi to Setup\” + ” “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Copy-Item -Path ($strDeploymentFolder + “Company.Program.Nb.Setup.” + $strVerMsSql + “.msi”) -Destination ($strWebsiteFolder + “Setup\msi”) -Force | Out-Null
Add-Content -Value (“Copied “ + $strDeploymentFolder + “Company.Program.Nb.Setup.” + $strVerMsSql + “.msi to Setup\msi\” + ” “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Copy-Item -Path ($strDeploymentFolder + “UpgradeTool-” + $strVerMsSql + ”.exe”) -Destination ($strWebsiteFolder + “Setup”) -Force | Out-Null
Add-Content -Value (“Copied “ + $strDeploymentFolder + “UpgradeTool-” + $strVerMsSql + ”.exe” + ” “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
[string]$strTitle = “ProgramUpdater”
[string]$strMessage = “Do you want the script to copy the path to the web.config to clipboard, for UpgradeTool? “
$strMessage += “This will overwrite current contents of clipboard.”
$yes = New-Object System.Management.Automation.Host.ChoiceDescription “&Yes”,
<span style="color:#4070a0">"Copy the path, overwrite the clipboard contents."</span>
<span style="color:#19177c">$no</span> = <span style="color:#06287e">New-Object</span> System.<span style="color:#06287e">Management</span>.<span style="color:#06287e">Automation</span>.<span style="color:#06287e">Host</span>.<span style="color:#06287e">ChoiceDescription</span> <span style="color:#4070a0">"&No"</span>,
“Do not copy anything, just start the UpgradeTool.”
$options = System.Management.Automation.Host.ChoiceDescription[]
[int]$intResult = $host.ui.PromptForChoice($strTitle, $strMessage, $options, 0)
switch ($intResult)
{
0 { [Windows.Forms.Clipboard]::SetText($strWebsiteFolder + “web.config”) }
}
$UpgradeToolPid = (Start-Process -FilePath ($strWebsiteFolder + “Setup\UpgradeTool-” + $strVerMsSql + ”.exe”) -Wait -PassThru).Id
try
{
Wait-Process -Id $UpgradeToolPid -ErrorAction SilentlyContinue
}
catch
{
}
Copy-Item -Path ($strWebsiteFolder + “Setup\UpgradeLog.txt”) -Destination ($strLogFolder) -Force | Out-Null
Start-Website -Name $strIISWebsiteName
Start-WebAppPool -Name $strIISAppPool | Out-Null
# “Started IIS website ” + $strIISWebsiteName + “ ” + (Get-Date -format “yyyyMMddHHmm”) -> PassThru
# “Started IIS application pool ” + $strIISAppPool + “ ” + (Get-Date -format “yyyyMMddHHmm”)
Add-Content -Value (“Attempting to start IIS website “ + $strIISWebsiteName + ” “ + (Get-Date -format “yyyyMMddHHmm”)) -Path $strLog -PassThru | Out-Null
Add-Content -Value (“Attempting to start IIS application pool “ + $strIISAppPool + ” “ + (Get-Date -format “yyyyMMddHHmm”)) -Path $strLog -PassThru | Out-Null
“Waiting” | Out-Null
[int]$intSec = 0
while ( ( (Get-WebAppPoolState $strIISAppPool).Value -ne “Started” ) -and ( (Get-WebsiteState $strIISWebsiteName).Value -ne “Started” ) )
{
Start-Sleep 2
$intSec += 2
Add-Content -Value (“Waited “ + $intSec + ” of 60 seconds. _ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
if ($intSec -eq 60)
{
Add-Content -Value (“apppool and website not running, upgrader failed, result mail might fail. _ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
break
}
}
Add-Content -Value (“Apppool “ + $strIISAppPool + ” status: “ + (Get-WebAppPoolState $strIISAppPool).Value + ”. _ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
Add-Content -Value (“Website “ + $strIISWebsiteName + ” status: “ + (Get-WebsiteState $strIISWebsiteName).Value + ”. _ “ + (Get-Date -format “yyyyMMdd_HHmm”)) -Path $strLog -PassThru
$Error | Select-Object * | Out-File ($strLogFolder + “ProgramUpdater.errors” + (Get-Date -format “yyyyMMdd.HHmm”) + “h.log”)
MailResult $strLogFolder $hshProgramUpdaterSettings
}