Powershell : Adding a GUI for a silent installer.

Seems counter intuative , right ?

Customer needs a pop up to display that software is being installed and offer the delay action. CM2012 could be used but it needs to be clear and simple for the (ab)users.

This happens to be for a SAP silent install , but the theory will work for all / any program.

###################################################################################################################################################################################################
# Coded By: Mr X
# Butchered by Bond
# Generated On: 07/12/2016 22:39.
# Version 1.3.2
# PreReq The required files need to copied to
# C:\$Batch$\Appscache\SAP7.40 including background image and .ico
###################################################################################################################################################################################################

#Small Functions
#Forms
#Function trigger calls
# Import the Assemblies for forms and drawings
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null

$objform = New-Object System.Windows.Forms.Form
$lblUpdates = New-Object System.Windows.Forms.Label
$lblUpdates1 = New-Object System.Windows.Forms.Label
$lblUpdates2 = New-Object System.Windows.Forms.Label
$okButton = New-Object System.Windows.Forms.Button
$DelayButton = New-Object System.Windows.Forms.Button
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#$a = 3 #number of delays allowed
#$DelayCount = 1 #initialise DelayCount
#$endprog = 0
function TimeDetection
{
$Time=Get-Date
$Time.AddHours(1).ToString("HH:mm:ss")
}
#not used
function GenratePopUp
{
[System.Windows.Forms.MessageBox]::Show("You cannot delay installation further" , "SAP Installation continuing")
}
#add reg key to run the script again if people power off / quit the installer

#Add into the registry
function AddRunOnce()
{
$BatchFix='$'+'batch$'
Write-Host "Adding RunOnce script." -foregroundcolor "magenta"
$RunOnceKey = "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
#set-itemproperty $RunOnceKey "NextRun" ('C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe -executionPolicy Unrestricted -File ' + "C:\$BatchFix\appscache\SAP7.40\.SAPInstaller.ps1")
set-itemproperty $RunOnceKey "NextRun" ("C:\$BatchFix\appscache\EU_SAP_7.40_Extracted\setup\NWSAPSETUP.exe -ArgumentList /UPDATE /silent")

}

#removes runone from the registry
function RemoveRunOnce()
{
#removes reg key to run the script again if people power off / quit the installer
Write-Host "Remvoing RunOnce script." -foregroundcolor "magenta"
$RunOnceKey = "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
remove-itemproperty $RunOnceKey "NextRun"
}

#Preps the installer , terminates the saplgpad ( only works in 7.20 , then runs the installer )
function InstallSap()
{
stop-process -name saplgpad -Force -ErrorAction SilentlyContinue
Start-Process 'C:\$Batch$\appscache\EU_SAP_7.40_Extracted\setup\NWSAPSETUP.exe' -ArgumentList "/UPDATE /silent"
RemoveScheduledTask
RemoveRunOnce
}

#does what the function name says ..
function AddScheduledTask
{
$BatchFix='$'+'batch$'
$Time=Get-Date
$Start=$Time.ToString("HH:mm:ss")
$Delay=$Time.AddHours(1).ToString("HH:mm:ss")
$EndTime=$Time.AddHours(6).ToString("HH:mm:ss")
SchTasks /Create /SC DAILY /TN “SAP Powershell Task” /TR “powershell.exe -windowstyle hidden -file C:\$batchfix\appscache\SAP7.40\SAPGUIFinal.ps1 -ExecutionPolicy unrestricted” /ST $Start /ET $EndTime /RI 60
}

#guess ..
Function RemoveScheduledTask
{
#remove the schedule task
SchTasks /Delete /TN "SAP Powershell Task" /F
}

#Popup gnerator for informing users
function AndTheyAreOff
{
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("Installation underway. Please do not use SAP for 30Minutes",0,"SAP Installation",0x0)
}

# test function for the loop listed lower down. Not actually in use
function IExplore()
{
Start-Process iexplore.exe
exit
}

# test function for the loop listed lower down. Not actually in use
function SomethingElse()
{
Start-Process calc.exe
exit
}

#Couple of variables I needed , no functions as stored and called elsewhere.
$BatchFix='$'+'batch$'
$Time=Get-Date
$Start=$Time.ToString("HH:mm:ss")
$Delay=$Time.AddHours(1).ToString("HH:mm:ss")
$EndTime=$Time.AddHours(6).ToString("HH:mm:ss")

#Scheduled task installer check loop. There are no native PS commandlets in the kellogg deployed PS version so had to workaround
Function CheckIfTaskExists() {
$schedule = new-object -com Schedule.Service
$schedule.connect()
$tasks = $schedule.getfolder("\").gettasks(0)

foreach ($task in ($tasks | select Name)) {
echo "TASK : $($task.name)"
if($task.name.equals( "SAP Powershell Task")) {
write-output "$($task.name) already exists"
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("You have delayed once , you cannot delay again. Press OK to continue",0,"SAP Installation",0x0)
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("SAP Now installing, please leave 30 minutes before using again",0,"SAP Installation",0x0)
InstallSap
return
}
}
SchTasks /Create /SC DAILY /TN “SAP Powershell Task” /TR “powershell.exe -windowstyle hidden -file C:\$batchfix\appscache\SAP7.40\SAPGUIFinal.ps1 -ExecutionPolicy unrestricted” /ST $Start /ET $EndTime /RI 60
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("Delaying for 1h. The installer will automatically pop up in 1h",0,"SAP Installation",0x0)
$objform.Close()
return
}

#FORM below.

#GenerateForm
function GenerateForm {
#
$killprog=$endprog
$DelCount=$DelayCount
$b=$a
$OnLoadForm_StateCorrection=
{
#Correct the initial state of the form to prevent the .Net maximized form issue
$objform.WindowState = $InitialFormWindowState
}
$objform.AutoSize = $True
$objform.BackColor = [System.Drawing.Color]::FromArgb(255,255,255,255)
#ICON file specification
$Icon = New-Object system.drawing.icon ('C:\$Batch$\Appscache\EU_SAP_7.40_Extracted\favicon.ICO')
$objform.Icon = $Icon
#Background Image specified. Location C:\$Batch$\Appscache\EUSAPUpdates\Back1.bmp
$objform.BackgroundImage = [System.Drawing.Image]::FromFile('C:\$Batch$\Appscache\EU_SAP_7.40_Extracted\Background.png')
$objform.BackgroundImageLayout = 2
$System_Drawing_Size = New-Object System.Drawing.Size
#Window Size Specified
$System_Drawing_Size.Height = 600
$System_Drawing_Size.Width = 1000
$objform.ClientSize = $System_Drawing_Size
$objform.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0)
$objform.FormBorderStyle = 5
$objform.Name = "objform"
$objform.Text = "EU SAP GUI 7.40 Upgrade"

#START Specify Attributes of Top Line Window text
$lblUpdates.BackColor = [System.Drawing.Color]::FromArgb(255,255,255,255)
$lblUpdates.DataBindings.DefaultDataSourceUpdateMode = 0
$lblUpdates.FlatStyle = 1
$lblUpdates.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",15,1,3,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 155
$System_Drawing_Point.Y = 160
$lblUpdates.Location = $System_Drawing_Point
$lblUpdates.Name = "lblUpdates"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 50
$System_Drawing_Size.Width = 650
$lblUpdates.Size = $System_Drawing_Size
$lblUpdates.TabIndex = 3
$lblUpdates.Text = "Mandatory upgrade to SAP and Business Explorer Applications."
$lblUpdates.TextAlign = 2
#END Specify Attributes of Line 3 Box text
#Print Top Line of Box text
$objform.Controls.Add($lblUpdates)
#START Specify Attributes of Middle Line Window text
$lblUpdates1.DataBindings.DefaultDataSourceUpdateMode = 0
$lblUpdates1.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",16,5,3,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 155
$System_Drawing_Point.Y = 225
$lblUpdates1.Location = $System_Drawing_Point
$lblUpdates1.Name = "lblUpdates1"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 50
$System_Drawing_Size.Width = 650
$lblUpdates1.Size = $System_Drawing_Size
$lblUpdates1.TabIndex = 5
$lblUpdates1.Text = "Please save and close all your work before continuing"
$lblUpdates1.TextAlign = 2
#END Specify Attributes of Middle Line Window text
#Print Middle Line of Window Text
$objform.Controls.Add($lblUpdates1)
#START Specify Attributes of Bottom Line Window text
$lblUpdates2.DataBindings.DefaultDataSourceUpdateMode = 0
$lblUpdates2.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",15,1,3,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 155
$System_Drawing_Point.Y = 290
$lblUpdates2.Location = $System_Drawing_Point
$lblUpdates2.Name = "lblUpdates2"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 50
$System_Drawing_Size.Width = 650
$lblUpdates2.Size = $System_Drawing_Size
$lblUpdates2.TabIndex = 6
$lblUpdates2.Text = "Please click on OK button to continue"
$lblUpdates2.TextAlign = 2
#END Specify Attributes of Bottom Line Window text
#Print Boittom Line of Window text
$objform.Controls.Add($lblUpdates2)
#START Specify Attributes of Dev Button
$okButton.BackColor = [System.Drawing.Color]::FromArgb(255,220,220,220)
$okButton.DataBindings.DefaultDataSourceUpdateMode = 0
$okButton.FlatAppearance.BorderColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$okButton.FlatAppearance.BorderSize = 10
$okButton.FlatAppearance.MouseDownBackColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$okButton.FlatAppearance.MouseOverBackColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$okButton.FlatStyle = 3
$okButton.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",15,1,3,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 300
$System_Drawing_Point.Y = 390
$okButton.Location = $System_Drawing_Point
$okButton.Name = "okButton"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 90
$System_Drawing_Size.Width = 175
$okButton.Size = $System_Drawing_Size
$okButton.TabIndex = 1
$okButton.Text = "OK - Continue"
#On Click of OK Button Close SAP
$okButton.add_Click(
{
$objform.Close()
AndTheyAreOff
InstallSap
RemoveRunOnce
}
)
$objform.Controls.Add($okButton)
#END Specify Attributes of OK Button and Publish button
#START Specify Attributes of Delay Button
$DelayButton.BackColor = [System.Drawing.Color]::FromArgb(255,220,220,220)
$DelayButton.FlatAppearance.BorderColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$DelayButton.DataBindings.DefaultDataSourceUpdateMode = 0
$DelayButton.FlatAppearance.BorderSize = 10
$DelayButton.FlatAppearance.MouseDownBackColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$DelayButton.FlatAppearance.MouseOverBackColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$DelayButton.FlatStyle = 3
$DelayButton.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",15,1,3,0)
$DelayButton.ForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 480
$System_Drawing_Point.Y = 390
$DelayButton.Location = $System_Drawing_Point
$DelayButton.Name = "DelayButton"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 90
$System_Drawing_Size.Width = 175
$DelayButton.Size = $System_Drawing_Size
$DelayButton.TabIndex = 0
$DelayButton.Text = "Delay for 1Hour"
#On Click of Dev Button call CopyIni
$DelayButton.add_Click(
{
$objform.Close()
CheckIfTaskExists
#Exit

}
)

$objform.Controls.Add($DelayButton)
#END Specify Attributes of Standard Button and Publish button

#Save the initial state of the form
$InitialFormWindowState = $objform.WindowState

#Init the OnLoad event to correct the initial state of the form
$objform.add_Load($OnLoadForm_StateCorrection)

#Show the Form
$objForm.FormBorderStyle = 'Fixed3D'
$objForm.MaximizeBox = $false
$objForm.Visible = $false
$objform.ShowDialog()| Out-Null

$DelayCount = $DelCount
$a=$b
$endprog = $killprog
}

#END.Function GenerateForm

AddRunOnce
GenerateForm