clear
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
function Get-INIContent(){
    [CmdletBinding()]
    Param (
    [Parameter(Mandatory=$true, Position=1)]
    [String]$subject, 
    [Parameter(Mandatory=$true, Position=2)]
    [String]$appNam
    )
    Process
    {
        $appVal=''
        $hashAppVal=@{}
        $ischk=$false
        $egurkhaPath=(Get-Item Env:EGURKHA_INSTALL_DIR).value.ToString()
        $tstIniPath=$egurkhaPath+'\agent\config\O365_Prerequisites.ini'
        $iniContent=get-content -Path $tstIniPath
        $isFound=$false
        for($i=0;$i -lt $iniContent.Length;$i++ ){
            if($appNam -eq 'none'){
                if($iniContent[$i].StartsWith('['+$subject) -and (!$iniContent[$i].StartsWith(';'))){ 
                    $ischk=$true
                    #Write-Host '88888 ' $iniContent[$i]
                    $subNam=($iniContent[$i] -split '-')[1]
                    $val=$subNam.Substring(0,($subNam.length-1)).Trim()
                    $i++
                    $key=($iniContent[$i] -split '=')[1]
                    $hashAppVal.Add($key,$val)
                }
            }else{
                if($iniContent[$i].StartsWith('['+$subject) -and (!$iniContent[$i].StartsWith(';'))){ 
                    $i++
                    while($true){
                        try{
                            $iniArr=$iniContent[$i].Split('=')
                            if($appNam -eq $iniArr[0]){
                                $appVal=$iniArr[1]
                                $isFound=$true
                                break;    
                            }
                        }catch{$isFound=$true;break;}
                            $i++  
                    }
                }
                if($isFound){break;}
            }
        }
        if($ischk){
            return $hashAppVal
        }
        else{
            return $appVal
        }
    }
}
function Check-DotNETversion(){
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true, Position=1)]
        [String]$FolderName1, 
        [Parameter(Mandatory=$true, Position=2)]
        [String]$FolderName2,
        [Parameter(Mandatory=$true, Position=3)]
        [String]$ReleaseNo
    )
    Process{
        $getPaths=Get-ChildItem -Path 'HKLM:SOFTWARE\Microsoft\NET Framework Setup\NDP' |select *
        foreach($path in $getPaths){
            if($path.Name.EndsWith($FolderName1)){
                $path1=$path.Name.Replace('HKEY_LOCAL_MACHINE\','HKLM:')
                $secndPaths=Get-ChildItem -Path $path1
                foreach($secPath in $secndPaths){
                    if($secPath.Name.EndsWith($FolderName2)){
                        $getProps=$secPath.Name.Replace('HKEY_LOCAL_MACHINE\','HKLM:')
                        if((Get-ItemProperty $getProps).Release -ge $ReleaseNo){
                            return $true
                        }
                        else{
                            return $false
                        }
                    }
                }
            }
        }
    }
}

$os=[String](Get-WMIObject win32_operatingsystem).Name
$osNam=$os.Substring(0,$os.IndexOf('|')).Trim() #(Microsoft Windows 7 Professional |C:\Windows|\Device\Harddisk0\Partition2)
$csdVersion=(Get-WMIObject win32_operatingsystem).CSDVersion #(Service Pack 1)
$sysType=(Get-WMIObject win32_operatingsystem).OSArchitecture #(64-bit)

Write-Host 'SYSTEM INFO - ' $osNam ' -- ' $csdVersion '--' $sysType

#Set Download Location
$dwnld=Get-INIContent -subject 'Location' -appNam 'Download'
if($dwnld -ne 'none' -and (Test-Path $dwnld)){
    $DownloadLocation=$dwnld   
}else{
    $DownloadLocation = $env:USERPROFILE+'\downloads\O365\'
}
if(!(Test-Path -Path $DownloadLocation)){
    $null=New-Item -ItemType directory -Path $DownloadLocation
}
Write-Host 'Download Location - ' $DownloadLocation

#Set LOG Location
$lgf=Get-INIContent -subject 'Location' -appNam 'Log'
if($lgf -ne 'none' -and (Test-Path $lgf)){
    $logDir=$lgf   
}else{
    $egurkhaPath=(Get-Item Env:EGURKHA_INSTALL_DIR).value.ToString()
    $logDir=$egurkhaPath+'\agent\O365'
}
if(!(Test-Path -Path $logDir)){
    $null=New-Item -ItemType directory -Path $logDir
}
$logFile=$logDir+'\Installation.log'
#Remove-Item -Path $logFile

Function O365-WriteLog{
	Param(
    [String]$writString,
    [String]$LogPath,
    [String]$ReportingName
    )
    $LogPath1=$LogPath.Replace(".log","1.log")
	[string]$date = Get-Date -Format G
    ( "[" + $date + "] - [" + $ReportingName+"]"+" - " + $writString ) | Out-File -FilePath $LogPath -Append
    if ([System.IO.File]::Exists($LogPath) -and (Get-Item $LogPath).length -gt 2mb) {  #if the size of file is greater than 1MB 
        if([System.IO.File]::Exists($LogPath1)){  #if logfile1 already exists, delete logfile1 
            Remove-Item $LogPath1 
        } 
        Rename-Item $LogPath $LogPath1 
    }
}

function Unzip{
    param([string]$zipfile, [string]$outpath)
    #[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
    $shell_app=new-object -com shell.application
    $zip_file = $shell_app.namespace($zipfile)
    $destination = $shell_app.namespace($outpath)
    $destination.Copyhere($zip_file.items())
}

function Chk-OSTypes(){
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true, Position=1)]
        [String]$OSStr       
    )
    Process
    {
        if($OSStr -eq 'AllOS'){
            return $true
        }else{
            $chkOS=$false
            $osArr=$OSStr -split '!'
            foreach($osTyp in $osArr){           
                if($osTyp -match '#' -and $osTyp -notmatch '-'){
                    $osVerArr=$osTyp -split '#'
                    if($osNam -match $osVerArr[0] -and $osNam -match $osVerArr[1]){$chkOS=$true}
                }elseif($osTyp -match '#' -and $osTyp -match '-'){
                    $osVerArr=$osTyp -split '#'
                    $osHyArr=$osVerArr[1] -split '-'
                    if($osNam -match $osVerArr[0] -and $osNam -match $osHyArr[0] -and $csdVersion -match $osHyArr[1]){$chkOS=$true}
                }elseif($osTyp -notmatch '#' -and $osTyp -match '-'){
                    $osVerArr=$osTyp -split '-'
                    if($osNam -match $osVerArr[0] -and $csdVersion -match $osVerArr[1]){$chkOS=$true}
                }else{
                    if($osNam -match $osTyp){$chkOS=$true}
                }
                if($chkOS){
                    return $true
                }
            }
            return $false   
        }
    }
}

function Chk-Registry(){
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true, Position=1)]
        [String]$RegStr       
    )
    Process
    {
        if($RegStr -eq 'NIL'){
            return $true
        }else{
            $regArr=$RegStr -split '#'
            $regValuesArr=$regArr[1] -split '!'
            $regValues=Get-ItemProperty -Path $regArr[0]
            foreach($regValue in $regValuesArr){
                $valArr=$regValue -split '-'
                $regStr=$valArr[0]
                $curval=[int]$regValues."$regStr"
                $val=[int]$valArr[1]
                if(!($curval -ge $val)){
                    return $true
                    break;
                }
            }
            return $false
        }
    }
}


function Proceed-Download(){
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true, Position=1)]
        [String]$APPName, 
        [Parameter(Mandatory=$true, Position=2)]
        [String]$APPFile
    )
    Process
    {
        Try{
            if($APPFile -match '#'){
                $arr=$APPFile -split '#'
                $appDst=$arr[0].Substring($arr[0].LastIndexOf('/')+1)
                $dest=$DownloadLocation+$appDst
                if((Get-Host).Version.Major -le 3){
                    $wc=New-Object System.Net.WebClient
                    $wc.DownloadFile($arr[0],$dest)
                }else{
                    $isPresent=Test-Path $dest -PathType Leaf
                    if(!$isPresent){
                        Try{
                            Write-Host $APPName '- Download started...' -ForegroundColor Green
                            O365-WriteLog -writString 'Downloading started' -LogPath $logFile -ReportingName $APPName
                            Start-BitsTransfer -Source $arr[0] -Destination $dest -TransferType Download -Description "Transfering $APPName" -ErrorAction Stop
                            Write-Host $APPName '- Download completed!' -ForegroundColor Green
                            O365-WriteLog -writString 'Downloading completed' -LogPath $logFile -ReportingName $APPName
                        }Catch{
                            Write-Host $APPName '- Download not completed or failed!' -ForegroundColor Green
                            O365-WriteLog -writString 'Downloading not completed or failed' -LogPath $logFile -ReportingName $APPName
                        }
                    }
                }
                Unzip -zipfile $dest -outpath $DownloadLocation
                #$dest=$dest.Replace(".zip",$arr[1])
                #$installHash.Add($dest,$APPName)
            }else{
                $appDst=$APPFile.Substring($APPFile.LastIndexOf('/')+1)
                $dest=$DownloadLocation+$appDst
                if((Get-Host).Version.Major -le 3){
                    $wc=New-Object System.Net.WebClient
                    $wc.DownloadFile($APPFile,$dest)
                }else{
                    $isPresent=Test-Path $dest -PathType Leaf
                    if(!$isPresent){
                        Try{
                            Write-Host $APPName '- Download started...' -ForegroundColor Green
                            O365-WriteLog -writString 'Download started...' -LogPath $logFile -ReportingName $APPName
                            Start-BitsTransfer -Source $APPFile -Destination $dest -TransferType Download -Description "Transfering $APPName" -ErrorAction Stop
                            Write-Host $APPName '- Download completed!' -ForegroundColor Green
                            O365-WriteLog -writString 'Download completed!' -LogPath $logFile -ReportingName $APPName
                        }Catch{
                            Write-Host $APPName '- Download not completed or failed!' -ForegroundColor Green
                            O365-WriteLog -writString 'Download not completed or failed!' -LogPath $logFile -ReportingName $APPName
                        }
                    }
                }       
            }
        }Catch{
                Write-Host "Download Failed" $Exception.Message -ForegroundColor Red
        }
    }      
}

O365-WriteLog -writString '*****************************************************************' -LogPath $logFile -ReportingName 'START'
O365-WriteLog -writString $osNam ' -- ' $csdVersion '--' $sysType -LogPath $logFile -ReportingName 'SYSTEM INFO'
O365-WriteLog -writString $DownloadLocation -LogPath $logFile -ReportingName 'Download Location'

$preDwnldHash=[ordered]@{}
$installHash=[ordered]@{}
$moduleHash=[ordered]@{}

$options=@{}
$options=Get-INIContent -subject 'APPs' -appNam 'none'
$onames =$options.Keys
$chkBxStr=''
$isRunNetwrkAssmnt=$False
######***GUI****#######
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object System.Windows.Forms.Form
$flowlayoutpanel = New-Object System.Windows.Forms.FlowLayoutPanel
$buttonOK = New-Object System.Windows.Forms.Button
$textbox1=New-Object System.Windows.Forms.TextBox
$label1=New-Object System.Windows.Forms.Label
$textbox2=New-Object System.Windows.Forms.TextBox
$label2=New-Object System.Windows.Forms.Label

$textbox3=New-Object System.Windows.Forms.TextBox
$label3=New-Object System.Windows.Forms.Label
$textbox4=New-Object System.Windows.Forms.TextBox
$label4=New-Object System.Windows.Forms.Label
$label5=New-Object System.Windows.Forms.Label

$O365DtlsLbl=New-Object System.Windows.Forms.Label
$O365UsrLbl=New-Object System.Windows.Forms.Label
$O365UsrTxtBx=New-Object System.Windows.Forms.TextBox
$O365PassLbl=New-Object System.Windows.Forms.Label
$O365PassTxtBx=New-Object System.Windows.Forms.TextBox

$compLbl=New-Object System.Windows.Forms.Label
   
$totalvalues = ($onames.count)

$formsize = 290 + (30 * $totalvalues)
$flowlayoutsize = 10 + (30 * $totalvalues)
$buttonplacement = 245 + (30 * $totalvalues)

$script:CheckBoxArray = @()

$form_Load = {
    foreach($user in $onames){
        $DynamicCheckBox = New-object System.Windows.Forms.CheckBox
        $DynamicCheckBox.Margin = '10, 8, 0, 0'
        $DynamicCheckBox.Name = $user
        $DynamicCheckBox.Size = '200, 22'
        $DynamicCheckBox.Text = "" + $user
        $DynamicCheckBox.TextAlign = 'MiddleLeft'
        $flowlayoutpanel.Controls.Add($DynamicCheckBox)
        $script:CheckBoxArray += $DynamicCheckBox
    }       
}
$form.Controls.Add($O365DtlsLbl)
$form.Controls.Add($O365UsrLbl)
$form.Controls.Add($O365UsrTxtBx)
$form.Controls.Add($O365PassLbl)
$form.Controls.Add($O365PassTxtBx)
$form.Controls.Add($label5)
$form.Controls.Add($label1)
$form.Controls.Add($textbox1)
$form.Controls.Add($label2)
$form.Controls.Add($textbox2)
$form.Controls.Add($label3)
$form.Controls.Add($textbox3)
$form.Controls.Add($label4)
$form.Controls.Add($textbox4)
$form.Controls.Add($compLbl)
$form.Controls.Add($flowlayoutpanel)
$form.Controls.Add($buttonOK)
$form.AcceptButton = $buttonOK
$form.AutoScaleDimensions = '8, 17'
$form.AutoScaleMode = 'Font'
$form.ClientSize = "360 , $formsize"
$form.FormBorderStyle = 'FixedDialog'
$form.Margin = '5, 5, 5, 5'
$form.MaximizeBox = $False
$form.MinimizeBox = $False
$form.Name = 'form1'
$form.StartPosition = 'CenterScreen'
$form.Text = 'O365 Prerequisites'
$form.add_Load($($form_Load))
    
$flowlayoutpanel.BorderStyle = 'FixedSingle'
$flowlayoutpanel.Location = '38, 220'
$flowlayoutpanel.Margin = '4, 4, 4, 4'
$flowlayoutpanel.Name = 'flowlayoutpanel1'
$flowlayoutpanel.AccessibleName = 'flowlayoutpanel1'
$flowlayoutpanel.Size = "270, $flowlayoutsize"
$flowlayoutpanel.TabIndex = 1

$O365DtlsLbl.Location="38,15"
$O365DtlsLbl.Anchor="Bottom, Left"
$O365DtlsLbl.Text="&O365 Details :"
$O365DtlsLbl.Size="100,20"

$O365UsrLbl.Location="38,38"
$O365UsrLbl.Anchor="Bottom, Left"
$O365UsrLbl.Text="&Username"
$O365UsrLbl.Size="60,20"

$O365UsrTxtBx.Location="105,38"
$O365UsrTxtBx.Name="O365User"
$O365UsrTxtBx.Size="200,20"
$O365UsrTxtBx.Text="none"

$O365PassLbl.Location="38,67"
$O365PassLbl.Anchor="Bottom, Left"
$O365PassLbl.Text="&Password"
$O365PassLbl.Size="60,20"

$O365PassTxtBx.Location="105,67"
$O365PassTxtBx.Name="O365Pass"
$O365PassTxtBx.Size="200,20"
$O365PassTxtBx.Text="none"
$O365PassTxtBx.PasswordChar='*'

$label5.Location="38,95"
$label5.Anchor="Bottom, Left"
$label5.Text="&Proxy Details :"
$label5.Size="100,20"

$label1.Location="38,118"
$label1.Anchor="Bottom, Left"
$label1.Text="&Host IP"
$label1.Size="60,20"

$textbox1.Location="105,118"
$textbox1.Name="ProxyHost"
$textbox1.Size="120,20"
$textbox1.Text="none"

$label2.Location="228,118"
$label2.Anchor="Bottom, Left"
$label2.Text="&Port"
$label2.Size="25,20"

$textbox2.Location="255,118"
$textbox2.Name="Port"
$textbox2.Size="50,20"
$textbox2.Text="none"

$label3.Location="38,145"
$label3.Anchor="Bottom, Left"
$label3.Text="&Username"
$label3.Size="60,20"

$textbox3.Location="105,145"
$textbox3.Name="ProxyUser"
$textbox3.Size="200,20"
$textbox3.Text="none"

$label4.Location="38,171"
$label4.Anchor="Bottom, Left"
$label4.Text="&Password"
$label4.Size="60,20"

$textbox4.Location="105,171"
$textbox4.Name="ProxyPass"
$textbox4.Size="200,20"
$textbox4.Text="none"
$textbox4.PasswordChar='*'

$compLbl.Location="38,200"
$compLbl.Anchor="Bottom, Left"
$compLbl.Text="&Components to be monitored :"
$compLbl.Size="180,20"

$buttonOK.Anchor = 'Bottom, Right'
$buttonOK.DialogResult = 'OK'
$buttonOK.Location = "135, $buttonplacement"
$buttonOK.Margin = '4, 4, 4, 4'
$buttonOK.Name = 'buttonOK'
$buttonOK.Size = '100, 30'
$buttonOK.TabIndex = 0
$buttonOK.Text = '&OK'

$frmDialog=$form.ShowDialog()
$isChkdOption=$false
foreach($cbox in $CheckBoxArray){
    if($cbox.CheckState -eq 'Checked'){
        $isChkdOption=$true
        $chkBxStr=$chkBxStr+'~'+$options[$cbox.Name]
    }   
}  
Remove-Variable checkbox*
if($frmDialog -eq 'OK' -and $isChkdOption){
    $proxyHost=$textbox1.Text
    $proxyPort=$textbox2.Text
    $proxyUsr=$textbox3.Text
    $proxyPass=$textbox4.Text
    $userName=$O365UsrTxtBx.Text
    $password=$O365PassTxtBx.Text

    $chkVerError=$false
    foreach($opt in $options.Values){
        if($chkBxStr -match $opt){
            $subject='APPs-'+$opt
            $cntNam=$opt+'_ChkDotNetVer'
            $chkVerArr=Get-INIContent -subject $subject -appNam $cntNam
            if($chkVerArr -ne $null -and $chkVerArr -ne '') {
                $verArr=$chkVerArr.Split('~')
                $chkVersion=Check-DotNETversion -FolderName1 $verArr[0] -FolderName2 $verArr[1] -ReleaseNo $verArr[2]
                if($chkVersion -eq $false){
                    $chkVerError=$true
                    $chkSub='APPs-'+$opt;$chkNam=$opt+'_Name'
                    $nam=Get-INIContent -subject $chkSub -appNam $chkNam
                    Write-Host 'Please upgrade your .NET Framework to '$verArr[3]'v to monitor '$nam -ForegroundColor Red
                }
            }
        }  
    }
    if($chkVerError){
        Write-Host 'Error! Exiting...'
        exit
    }
   
    if($userName -ne '' -and $userName -ne $null -and $userName -ne 'none' -and $password -ne '' -and $password -ne $null -and $password -ne 'none'){
        $credential = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $(convertto-securestring $password -asplaintext -force)
    }
    $sessionOption = New-PSSessionOption -SkipRevocationCheck
    if($proxyHost -ne '' -and $proxyHost -ne $null -and $proxyHost -ne 'none' -and $proxyPort -ne '' -and $proxyPort -ne $null -and $proxyPort -ne 'none'){
        $proxyserver='http://'+$proxyHost+':'+$proxyPort
        O365-WriteLog -writString 'Proxy Available in this System '$proxyserver -LogPath $logFile -ReportingName 'SYSTEM'
        [system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy($proxyserver)
        if($proxyUsr -ne '' -and $proxyUsr -ne $null -and $proxyUsr -ne 'none' -and $proxyPass -ne '' -and $proxyPass -ne $null -and $proxyPass -ne 'none'){
            O365-WriteLog -writString 'Proxy credentials are Available in this System ' -LogPath $logFile -ReportingName 'SYSTEM'
            $proxyCred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $proxyUsr, $(convertto-securestring $proxyPass -asplaintext -force)
            [system.net.webrequest]::defaultwebproxy.credentials =$proxyCred
            [system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $true
            $sessionOption = New-PSSessionOption -SkipRevocationCheck -ProxyAccessType WinHttpConfig -ProxyAuthentication basic -ProxyCredential $proxyCred
        }
    }

    $moduleNam=Get-InstalledModule
    $availModules=''
    foreach($nam in $moduleNam){
        $availModules=$availModules+'~'+$nam.Name
    }
    
    Try{
        Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction Stop
    }Catch{}

    foreach($opt in $options.Values){
        $subject='APPs-'+$opt
        if($chkBxStr -match $opt){
            if($chkBxStr -match 'SBO'){$isRunNetwrkAssmnt=$true}
            $subject='APPs-'+$opt
            $cntNam=$opt+'_Ins'
            $appsOptArr=Get-INIContent -subject $subject -appNam $cntNam
            $appsOpts=$appsOptArr -split '~'
            foreach($appOpt in $appsOpts){
                if($appOpt -ne 'none'){
                    $appOptArr=$appOpt -split '@'
                    $chkOS=Chk-OSTypes $appOptArr[1]
                    $chkReg=Chk-Registry $appOptArr[2]
                    if($chkOS -and $chkReg){
                        $APPName=$appOptArr[0]
                        $APPFile=$appOptArr[3]
                        if($APPFile -match '#'){
                            $arr=$APPFile -split '#'
                            $appDst=$arr[0].Substring($arr[0].LastIndexOf('/')+1)
                            $dest=$DownloadLocation+$appDst
                            $isPresent=Test-Path $dest -PathType Leaf
                            if(!$isPresent){
                                Try{
                                    $preDwnldHash.add($APPName,$APPFile)
                                }Catch{}
                            }
                            $dest=$dest.Replace(".zip",$arr[1])
                        }else{
                            $appDst=$APPFile.Substring($APPFile.LastIndexOf('/')+1)
                            $dest=$DownloadLocation+$appDst
                            $isPresent=Test-Path $dest -PathType Leaf
                            if(!$isPresent){
                                Try{
                                    $preDwnldHash.add($APPName,$APPFile)
                                }Catch{}
                            }
                        } 
                        Try{
                            $installHash.Add($dest,$APPName) 
                        }Catch{}
                    }
                }
            }
        }

        $appNAm=$opt+'_PG'
        $APPsPGArr=Get-INIContent -subject $subject -appNam $appNAm
        $pgArr=$APPsPGArr -split '~'
        $i=0
        foreach($pg in $pgArr){
            Try{
                if($availModules -notmatch $pg){
                    $moduleHash.add($pg,$i)
                }
            }Catch{}
            $i++
        }
    }
}
else{
    Write-Host 'you clicked cancel or did not select options...'
    exit
}

#DOWNLOAD
$proceedInstal1=$False
if($preDwnldHash.Count -ne 0){
    $message = @("Download the below?")
    $message+=" "
    foreach($key in $preDwnldHash.Keys){
    $message+=' -> '+$key
    }
    $res=[system.windows.forms.messagebox]::show(($message -join "`n"),"Download",'YesNo')
    if($res -eq 'Yes'){
        foreach($key in $preDwnldHash.Keys){
            Proceed-Download -APPName $key -APPFile $preDwnldHash[$key]
        } 
        $proceedInstal1=$true    
    }else{
        Write-Host 'You cancelled the download...'
    }
}else{
    $msg = @("Downloads available in")
    $msg+=$DownloadLocation
    $msg+=" "
    $msg+="Proceed with installation?"
    $procdIns=[system.windows.forms.messagebox]::show(($msg -join "`n"),"Download",'YesNo')
    if($procdIns -eq 'Yes'){
        $proceedInstal1=$true
    }else{
        Write-Host 'You cancelled the installation ....'
    }
}

#INSTALLATION
if($proceedInstal1){
    if($installHash.Count -ne 0){
        $insMsg=@("Install the below?")
        $insMsg+=" "
        foreach($key in $installHash.Keys){
            $insMsg+=' -> '+$installHash[$key]
        }
        $insRes=[system.windows.forms.messagebox]::show(($insMsg -join "`n"),"Installation",'YesNo')
        if($insRes -eq 'Yes'){
            foreach($key in $installHash.Keys){
                Try{
                    Write-Host $installHash[$key]' Installation Started...' -ForegroundColor Yellow
                    O365-WriteLog -writString 'Installation started' -LogPath $logFile -ReportingName $installHash[$key]
                    Start-Process $key -Wait -ErrorAction Stop
                    Write-Host $installHash[$key]' Installation process completed!' -ForegroundColor Yellow
                    O365-WriteLog -writString 'Installation process completed' -LogPath $logFile -ReportingName $installHash[$key]
                }Catch{
                    Write-Host 'Installation failed!' -ForegroundColor Red
                    O365-WriteLog -writString 'Installation process not completed or failed' -LogPath $logFile -ReportingName $installHash[$key]
                }  
            } 
            
            foreach($key in $moduleHash.Keys){
                Try{
                    Install-Module $key -Scope AllUsers -AllowClobber -Force
                    Write-Host $key ' modules installed successfully!' -ForegroundColor Green
                    O365-WriteLog -writString $pg ' modules are installed Successfully' -LogPath $logFile -ReportingName $key
                }
                Catch{
                    Write-Host $key ' - Exception occured - '$_.Exception.Message -ForegroundColor Red
                    O365-WriteLog -writString 'Excepton occured in'$key $_.Exception.Message -LogPath $logFile -ReportingName $key
                }
            }          
        }else{
            Write-Host 'You cancelled installation process...'
        }
    }else{
       [system.windows.forms.messagebox]::show("All Prerequisites are in place","Installation",'Ok')
    }
}

if($isRunNetwrkAssmnt){
    $egurkhaPath=(Get-Item Env:EGURKHA_INSTALL_DIR).value.ToString()
    $ntwrkAssmntFile=$egurkhaPath+'\lib\SBONtwrkAssmnt.ps1'
    $nwAssesTool=Get-Childitem "C:\*\Microsoft Skype for Business Network Assessment Tool"
    if($nwAssesTool -ne $null -and $nwAssesTool -ne ''){
        & $ntwrkAssmntFile
        write-host 'Network Assessment Tool config updated!'
    }  
}

#TESTING
#-------
Write-Host 'Checking...'
O365-WriteLog -writString 'Testing started ' -LogPath $logFile -ReportingName 'Testing'
if($credential -ne $null -and $credential -ne ''){
    foreach($opt in $options.Values){
        $subject='APPs-'+$opt
        if($chkBxStr -match $opt){ 
            $appNAm=$opt+'_Name'
            $nam=Get-INIContent -subject $subject -appNam $appNAm

            if($nam -eq 'Office 365'){
             
                #MSOnline
                Write-host "Trying to connect to Microsoft Online..." -ForegroundColor Yellow
                O365-WriteLog -writString 'trying to connect Microsoft Online.....' -LogPath $logFile -ReportingName 'TESTING - MSOnline'
                try{
                    Connect-MsolService -Credential $Credential -ErrorAction Stop
                    $Tenant = Get-MsolAccountSku
                    $domainNam = $Tenant | select -First 1
                    Write-Host 'Microsoft Online connected successfully!' -ForegroundColor Green
                    O365-WriteLog -writString 'Microsoft Online connected successfully' -LogPath $logFile -ReportingName 'TESTING - MSOnline'
                }Catch{
                    Write-Host "Failed - unable to connect to Microsoft Online!" -ForegroundColor Red
                    O365-WriteLog -writString 'Failed - Cannot connect to Microsoft Online' -LogPath $logFile -ReportingName 'TESTING - MSOnline'
                }

                #Exchange Online
                Write-host "Trying to connect to Exchange Online..." -ForegroundColor Yellow
                O365-WriteLog -writString 'trying to connect Exchange Online...' -LogPath $logFile -ReportingName 'TESTING - Exchange Online'
                try {
                    $ExchSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Credential  -Authentication Basic -AllowRedirection -SessionOption $sessionOption -ErrorAction Stop
                    Import-PSSession $ExchSession -DisableNameChecking -AllowClobber  -ErrorAction Stop | Out-Null
                    $domain = Get-AcceptedDomain | where {$_.Name -like "*.onmicrosoft.com" -and $_.Name -notlike "*.mail.onmicrosoft.com"} | select name
                    $domainFullNam=$domain.Name   
                    Write-Host 'Exchange Online connected successfully!' -ForegroundColor Green
                    O365-WriteLog -writString 'Exchange Online connected successfully' -LogPath $logFile -ReportingName 'TESTING - Exchange Online'
                    Get-PSSession | Remove-PSSession
                } Catch {
                    Write-Host "Failed - Unable to connect to Exchange Online" -ForegroundColor Red
                    O365-WriteLog -writString 'Failed - Cannot connect to Exchange Online' -LogPath $logFile -ReportingName 'TESTING - Exchange Online'
                }             
            }

            if($nam -eq 'SharePointOnline'){
                $domainNam =""
                try{
                    Connect-MsolService -Credential $Credential -ErrorAction Stop
                    $Tenant = Get-MsolAccountSku
                    $domainNam = $Tenant | select -First 1
                    $domainNam=($domainNam.AccountName).ToString().Trim()
                    O365-WriteLog -writString $domainNam -LogPath $logFile -ReportingName 'TESTING - SharePoint Online'
                }catch{}
                if($domainNam -ne $null -and $domainNam -ne ""){
                    Write-host "Trying to connect to SharePoint Online..." -ForegroundColor Yellow
                    O365-WriteLog -writString 'trying to connect SharePoint Online...' -LogPath $logFile -ReportingName 'TESTING - SharePoint Online'
                    try{     
                        $url='https://'+$domainNam+'-admin.sharepoint.com'
                        Connect-SPOService -Url $url -Credential $credential -ErrorAction Stop
                        Write-Host 'SharePoint Online connected successfully' -ForegroundColor Green
                        O365-WriteLog -writString 'SharePoint Online connected successfully' -LogPath $logFile -ReportingName 'TESTING - SharePoint Online'
                        Disconnect-SPOService
                    }Catch{
                        Write-Host "Failed - Cannot connect to SharePoint Online" -ForegroundColor Red
                        O365-WriteLog -writString 'Failed - Cannot connect to SharePoint Online' -LogPath $logFile -ReportingName 'TESTING - SharePoint Online'
                    }
                }else{
                    Write-Host "[$domainNam is null or empty] - SharePoint Online" -ForegroundColor Red
                }
            }

            if($nam -eq 'Skype for Business Online'){
                $domainFullNam=''
                try{
                    $ExchSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Credential  -Authentication Basic -AllowRedirection -ErrorAction Stop
                    Import-PSSession $ExchSession -DisableNameChecking -AllowClobber  -ErrorAction Stop | Out-Null
                    $domain = Get-AcceptedDomain | where {$_.Name -like "*.onmicrosoft.com" -and $_.Name -notlike "*.mail.onmicrosoft.com"} | select name
                    $domainFullNam=$domain.Name
                    O365-WriteLog -writString $domainFullNam -LogPath $logFile -ReportingName 'TESTING - Skype for Business Online'
                }catch{}
                Get-PSSession | Remove-PSSession
                if($domainFullNam -ne $null -and $domainFullNam -ne ""){
                    Write-host "Trying to connect Skype for Business Online..." -ForegroundColor Yellow
                    O365-WriteLog -writString 'trying to connect Skype for Business Online.....' -LogPath $logFile -ReportingName 'TESTING - Skype for Business Online'
                    try {
                        $SfBSession = New-CsOnlineSession -Credential $Credential -OverrideAdminDomain $domainFullNam -SessionOption $sessionOption -ErrorAction Stop 
                        Import-PSSession $SfBSession -ErrorAction Stop -AllowClobber -DisableNameChecking | Out-Null
                        Write-Host "Skype for Business Online connected successfully!" -ForegroundColor Green
                        O365-WriteLog -writString 'Skype for Business Online connected successfully' -LogPath $logFile -ReportingName 'TESTING - Skype for Business Online'
                        Get-PSSession | Remove-PSSession
                    }catch{
                        Write-Host "Failed - Unable to connect to Skype for Business Online" -ForegroundColor Red
                        O365-WriteLog -writString 'Failed - Cannot connect to Skype for Business Online' -LogPath $logFile -ReportingName 'TESTING - Skype for Business Online'
                    } 
                }else{
                    Write-Host "[$domainFullNam is null or empty] - SharePoint Online" -ForegroundColor Red
                }
            }

            if($nam -eq 'Microsoft Teams'){
                try{
                    Connect-MsolService -Credential $Credential -ErrorAction Stop
                    $Tenant = Get-MsolAccountSku
                    $domainNam = $Tenant | select -First 1
                    Write-Host 'Microsoft Online connected successfully' -ForegroundColor Green
                    O365-WriteLog -writString 'Microsoft Online connected successfully' -LogPath $logFile -ReportingName 'TESTING - MSOnline'
                }Catch{
                    Write-Host "Failed - Unable to connect to Microsoft Online" -ForegroundColor Red
                    O365-WriteLog -writString 'Failed - Cannot connect to Microsoft Online' -LogPath $logFile -ReportingName 'TESTING - MSOnline'
                }

                $ConneTeams=Connect-MicrosoftTeams -Credential $Credential
                try{

                    $ConneTeams=Connect-MicrosoftTeams -Credential $Credential
                    if($ConneTeams.Account -ne $null){

                        Write-Host 'Microsoft Teams connected successfully' -ForegroundColor Green
                    }else{
                        Write-Host 'Failed to connect Microsoft Teams ' -ForegroundColor Red
                    }
                 }catch{
                    Write-Host 'Exception Occured in  Connect-MicrosoftTeams - ' $_.Exception.Message -ForegroundColor Red
                 }                
            }

        }
    }
 }

 O365-WriteLog -writString '**************************************************************************' -LogPath $logFile -ReportingName 'END'
