<#
    .Synopsis
        Powershell installer for Cavisson Agents
    .Description
        This is a powershell installer that would install Cavisson agents on
        local and in remote servers.
    .Example
        .\install.ps1 -tier AppTier -instance Instance1 -controller controller.cavisson.com:443

        Above example installs agents to the local only
    .Example
        .\install.ps1 -tier AppTier -instance Instance1 -poolName "pool1,pool2"
            -remote user1:pass1:host1,user2:pass2:host2 -dest E:\POC

        Above example installs the agents to the remote hosts
        Password is optional and if not provided it will prompt for it but in  that case
        -remote should be in format user:host,user2:host ...

    .Example
        .\install.ps1 -appAgent 1 -machineAgent 1 -logAgent 1 -tier Apptier

	.Example
        .\install.ps1 -appAgent 1 -machineAgent 1 -logAgent 1 -silent 

	above silent option is used for installing in silent mode.


        Above examples installs machineAgent, appAgent and logAgent
	
	 .\partialuninstall.ps1 -partialuninstall 1 -machineAgent 0 -appAgent 0 -logAgent 1  
	Above example uninstall logagent partially
    .Notes
        1. When using remote option -dest is required as this script copies
           related files to the remote host. The dest path must exists and it is
           not created by the script
        2. Trusted hosts must be enabled in winrm client config
        3. Password authentication may be required for each action

#>
[CmdletBinding()]
param (
    # The tier name, a logical grouping of applications
    [string] $tier="Default",
    # Netdiagnostics collector host port
    [string] $controller = "www.cav-test.com:443",
    # Instance name
    [string] $instance = "",
    # Communication protocol to use (WSS/TCP)
    [string] $protocol = "WSS",
	# Provide the value for tags
	[string] $tags = "",
	# Provide the value for Port
	[string] $port = "",
	# Provide the value for enable_listen
	[string] $enable_listen = "",
	# Provide the value for attributes 
	[string] $attributes = "",
    # Name of the MSI to install, default it picks from the current directory
    [string] $msi = (Get-ChildItem . -Filter "Cavisson*.msi").Name,
	[string] $msi1 = "WindowsApplicationDriver_1.2.1.msi",
	[string] $msi2 = "winsdksetup.exe",
    # Install Applicaton Agent, use this if you want to install the app agent
    [int] $appAgent = 1,
    # Install Machine Agent, use this if you want to install the machine agent
    [int] $machineAgent = 1,
    # Install Netforest Log Agent, use this if you want to install the log agent
    [int] $logAgent = 1,
    # Install winlogBeat as NFLogBeat, use this if you want to install the 
    [int] $nfLogBeat = 0,
	# Copy ProfilerHelper.DLL of profilerhelper_udp_folder copy to gcc folder (BUG_ID-146187)
    [int] $udp = 0,
	#For install WindowsApplicationDriver_1.2.1.msi & winsdksetup.exe (bug_id -146518)
	[int] $winapp = 0,
    # List of pool names to monitor separated by comma
    [string] $poolName = "",
    # NF Index prefix, use only with nfagent enabled
    [string] $nfIndexPrefix,
    # NF server hostname/IP, use only with nfagent enabled
    [string] $nfServer,
    # NF env name, use only with nfagent enabled
    [string] $nfEnv = "Production",
    # NF Reload Port, use only with nfagent enabled
    [int] $nfReloadPort = 9600,
    # Visual studio runtime executable
    [string] $vcExe = "VC_redist.x64.exe",
    # Visual studio runtime executable x86
    [string] $vcExe86 = "VC_redist.x86.exe",	
    # Log file to log installer logs
    [string] $logFile = "agent-install.log",
    # List of remote endpoints separated by comma (user1:host1,user2:host2...)
    [string] $remote,
	#Entry for server
	[string] $server = "",
    # Destination directory to copy related installation files
    [string] $dest="C:\Users",
    # Username to run Machine Agent with
    [string] $username = "",
    # Password of username to run Machine Agent
    [string] $password = "",
    # Copy local files to remote, useful when files are already present
    # on remote host
    [int] $copy = 1,
    # Flag to install vc++
    [int] $installVCRuntime = 0,
	$hostfile="",
    #ISS reset post installation
    [int] $iisreset = 0,
    #Flag to upgrade installer on server
    [switch] $upgrade=$false,
    #flag to do silent installation
    [switch] $silent=$false,
	#help
	[switch] $help=$false,
    # do remote installation
	[int] $remoteinstall,
    #that is for installation path
    [string] $installdir = "C:\opt\",
    [string] $installedPath = $installdir + "cavisson\",
    # keyword for partial uninstallation
    #[switch] $partialuninstall=$false,
    #keyword for NDproxy setting
    [String] $ndproxy = "",
    #flag to uninstall agents
    [switch] $uninstall=$false,
	#flag for saas feature
    [switch] $saas,
	#Keyword for projectkey
	[string] $projectkey,
	#keyword for url
    [string] $url,	
	#keyword for tierattributes
	[string] $tierattributes,
	#Keyword for appname
	[string] $appname
)

# Check for Windows Script Host
$registryPath = "HKLM:\Software\Microsoft\Windows Script Host\Settings"
$valueName = "Enabled"

# Check if the registry path exists
if (Test-Path $registryPath) {
    try {
        # Check if the "Enabled" value exists in the registry
        if (Test-Path "$registryPath\$valueName") {
            # Get the current value of the "Enabled" key
            $enabledValue = Get-ItemProperty -Path $registryPath -Name $valueName | Select-Object -ExpandProperty $valueName

            # Check if the value is 0
            if ($enabledValue -eq 0) {
                Write-Host "$($logEntry) Error : Windows Script Host access is disabled on this machine. To run the installer, you need to Enable it."
                exit  # Exit the script immediately
            }
        } else {
        }
    } catch {
        exit
    }
} else {
    exit
}

# Detects if a compatible and bundled version of visual c++ is installed or not
# Returns true if matches else returns false
function IsAgentInstall(){
    $software = "Cavisson Agent";
    $installed = ((Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where { $_.DisplayName -eq $software }) -ne $null) -or ((Get-ItemProperty HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where { $_.DisplayName -eq $software }) -ne $null)
    
    If(-Not $installed) {
        Write-Host "'$software' is NOT installed.";
        return $false
    }else {
        $Cur= (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |  Select-Object DisplayName, DisplayVersion | Select-String -Pattern CavMachineAgent)
        $Cur2=(Get-ItemProperty HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |  Select-Object DisplayName, DisplayVersion | Select-String -Pattern CavMachineAgent)
        $p= "@{DisplayName=CavMachineAgent; DisplayVersion=(?<content>.*)}"
		
		
        ($Cur -match $p) -or ($Cur2 -match $p)
        #$version=$Matches['content']
        #Write-Host "CavMachineAgent is installed of version" $version
		Write-Host "CavMachineAgent is installed of version"
        return $true
    }

}
#check the installed path
function checkpath{param([string] $installedPath)
    Write-Host "The defualt installed path for the Agent is  C:\opt\cavisson\"  -ForegroundColor Yellow
    Write-host "Is Cavisson Agent installed on default path ?" -ForegroundColor Yellow 
    $installedPath=$installedPath
    $Readhost = Read-Host " ( Y / N ) " 
    Switch ($ReadHost) { 
        Y {Write-host "Enter the correct installed path of cavisson Agents"; $installedPath = Read-Host -Prompt "Agent installed path"} 
        N {Write-Host "The installed cavisson Agent path is default"} 
        Default {Write-Host "Please select correct option i.e Y or N" -ForegroundColor Red} 
    } 
    return $installedPath
}
#For uninstall the ND
function uninstallND {param([string] $installedPath, [string] $logFile)
    if (IsAgentInstall){ 
        $installedPath=checkpath $installedPath
        Write-Host $installedPath
        $cur_path=$pwd
        Write-Host $cur_path
        if (Test-Path -Path $installedPath\netdiagnostics){
            Write-Host "Going to uninstall Application Performance monitoring module"
            Set-Location -Path $installedPath
            
    #        cd ..
    #Remove-Item 'netdiagnostics' -Force -Recurse
            [Environment]::SetEnvironmentVariable("NDHOME",$null,"Machine")
            [Environment]::SetEnvironmentVariable("CONNECT_TO_NDC",$null,"Machine")
            [Environment]::SetEnvironmentVariable("ND_CONFIGURE_BACKEND_NAME",$null,"Machine")
            [Environment]::SetEnvironmentVariable("COR_ENABLE_PROFILING",$null,"Machine")
            [Environment]::SetEnvironmentVariable("COR_PROFILER",$null,"Machine")
            [Environment]::SetEnvironmentVariable("COR_PROFILER_PATH_32",$null,"Machine")
            [Environment]::SetEnvironmentVariable("COR_PROFILER_PATH_64",$null,"Machine")
            [Environment]::SetEnvironmentVariable("ND_ENABLE_ALL_POOL",$null,"Machine")
            $ServiceName = 'NDProxyService'
            $arrService = Get-Service -Name $ServiceName
            if ($arrService.Status -eq 'Running'){
             #   Stop-Service $ServiceName
              #  $service = Get-WmiObject -Class Win32_Service -Filter "Name='NDProxyService'"
               # $service.delete() >>$logFile
            #}
                $ServicePID = (get-wmiobject win32_service | where { $_.name -eq 'NDProxyService'}).processID
                taskkill /f /pid $ServicePID >>$logFile
                sc.exe delete NDProxyService >>$logFile
            }
            Remove-Item 'netdiagnostics' -Force -Recurse
            Write-Host "Application performance monitoring module is uninstalled successfully"
    
        }
        else {
            Write-Host "Application performance monitoring module is not installed" -ForegroundColor Red
        }
        Set-Location -Path $cur_path
    }
}
    #uninstallND $installedPath
	#For Uninstalling the NF
function uninstallNF {param([String] $installedPath, [string] $logFile)
    if (IsAgentInstall){
        $installedPath=checkpath $installedPath
        Write-Host "$installedPath"
        $cur_path=$pwd
        Write-Host "$cur_pwd"
        if (Test-Path -Path $installedPath\Netforest){
            Write-Host "Going to uninstall Log monitoring module"
            Set-Location -Path $installedPath
           
            [Environment]::SetEnvironmentVariable("RELOADPORT",$null,"Machine")
            [Environment]::SetEnvironmentVariable("YML_CONFIG_NFDB",$null,"Machine")

            $ServiceName = 'NFAgent'
            $arrService = Get-Service -Name $ServiceName
            #if ($arrService.Status -eq 'Running'){
            #   Write-Host 'going to uninstall Logagent'
            
                $ServicePID = (get-wmiobject win32_service | where { $_.name -eq 'NFAgent'}).processID 

            #Now with this PID, you can kill the service
                taskkill /f /pid $ServicePID >>$logFile
                sc.exe delete NFAgent >>$logFile
            #sc stop NFAgent
            #$service = Get-WmiObject -Class Win32_Service -Filter "Name='NFAgent'"
            #$service.delete() >$logFile
        
            $ServiceName = 'NFLogBeat'
            $arrService = Get-Service -Name $ServiceName
            #if ($arrService.Status -eq 'Running'){
            #   Write-Host 'going to uninstall NFlogbeat'
            
                $ServicePID = (get-wmiobject win32_service | where { $_.name -eq 'NFLogBeat'}).processID 

            #Now with this PID, you can kill the service
                taskkill /f /pid $ServicePID >>$logFile
                sc.exe delete NFLogBeat >>$logFile
           
        
            Remove-Item 'netforest\bin\NFAgent.exe' -Force -Recurse
            Remove-Item 'netforest\bin\NFLogBeat.exe' -Force -Recurse
            Remove-Item 'netforest' -Force -Recurse
            Write-Host "Log monitoring module is uninstalled successfully "
        }else {
        Write-Host "Log monitoring module is not installed" -ForegroundColor Red
        }
        Set-Location -Path $cur_path
     
    }
}
#For uninstalling the cavwmon
function uninstallCavwmon {param ([string] $installedPath, [string] $logFile)
    if(IsAgentInstall){
        $installedPath=checkpath $installedPath
        Write-Host "$installedPath"
        $cur_path=$pwd
        Write-Host "$cur_path"
        if (Test-Path -Path $installedPath\wmonitors) {
            Set-Location -Path $installedPath
            $ServiceName = 'CavWMON'
            $arrService = Get-Service -Name $ServiceName
            if ($arrService.Status -eq 'Running'){
                Write-Host 'going to uninstall Infrastructure monitoring module'
                $ServicePID = (get-wmiobject win32_service | where { $_.name -eq 'CavWMON'}).processID 
                taskkill /f /pid $ServicePID >>$logFile
                sc.exe delete CavWMON >>$logFile
             #Stop-Service CavWMON
                #$service = Get-WmiObject -Class Win32_Service -Filter "Name='CavWMON'"
            }    #$service.delete() >>$logFile
            #}
        
            Remove-Item "wmonitors" -Force -Recurse
            Write-Host "Infrastructure monitoring module is uninstalled successfully"   
        } 
        else {
            Write-Host "Infrastructure monitoring module is not installed" -ForegroundColor Red
        }      
        Set-Location -Path $cur_path
    }
}    
#For checking that visual runtime is installed or not
function IsVSRuntimeInstalled() {
    # Default bundled version
    $BundledVersion = "v14.25.28508.03"
    # Registry path to check
    $Key = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64"
    try {
        $runtime = (Get-ItemProperty -Path Registry::$Key -Name version -Ea Stop)
        if ($runtime.Version -eq $BundledVersion) {
            return $true
        }
        else {
            return $false
        }
    }
    catch [System.Management.Automation.PSArgumentException] {
        # Registry key property is missing (Value is not found)
        return $false
    }
    catch [System.Management.Automation.ItemNotFoundException] {
        # Registry key itself is missing(Not installed)
        return $false
    }
}
#Conditions for partial uninstallation of different products
<#
if ($partialuninstall)
{   if (($machineAgent -eq 1) -and ($appAgent -eq 1) -and ($logAgent -eq 1)) {
    $uninstall=$true
    }
    if (($machineAgent -eq 1) -and ($appAgent -eq 1) -and ($logAgent -eq 0)) {
        $partial="cmon,nd"
    }if (($machineAgent -eq 1) -and ($appAgent -eq 0) -and ($logAgent -eq 0)) {
        $partial="cmon"
    }if (($machineAgent -eq 1) -and ($appAgent -eq 0) -and ($logAgent -eq 1)) {
        $partial="cmon,nf"    
    }if (($machineAgent -eq 0) -and ($appAgent -eq 1) -and ($logAgent -eq 0)) {
        $partial="nd"
    }if (($machineAgent -eq 0) -and ($appAgent -eq 1) -and ($logAgent -eq 1)) {
        $partial="nd,nf"
    }if (($machineAgent -eq 0) -and ($appAgent -eq 0) -and ($logAgent -eq 1)) {
       $partial="nf"

    }
}
#>
$addLocal = " ADDLOCAL=CONFIGFILES,"
#For installation of machineagent ,appagent and logagent
if (($machineAgent -eq 1) -and ($appAgent -eq 1) -and ($logAgent -eq 1)) {
    $addLocal += "CMON,ND,NF"
	$app= "CMON,ND,NF"
}
#For installation of machineagent ,appagent 
if (($machineAgent -eq 1) -and ($appAgent -eq 1) -and ($logAgent -eq 0)) {
    $addLocal += "CMON,ND"
	$app= "CMON,ND"
}
#For installtion of machineagent
if (($machineAgent -eq 1) -and ($appAgent -eq 0) -and ($logAgent -eq 0)) {
    $addLocal += "CMON"
	$app= "CMON"
}
#For installation of machineagent and logagent
if (($machineAgent -eq 1) -and ($appAgent -eq 0) -and ($logAgent -eq 1)) {
    $addLocal += "CMON,NF"
	$app= "CMON,NF"
}
#For installation of appagent
if (($machineAgent -eq 0) -and ($appAgent -eq 1) -and ($logAgent -eq 0)) {
    $addLocal += "ND"
	$app= "ND"
}
#For installation of appagent and logagent
if (($machineAgent -eq 0) -and ($appAgent -eq 1) -and ($logAgent -eq 1)) {
    $addLocal += "ND,NF"
	$app= "ND,NF"
}
#For installation of logagent
if (($machineAgent -eq 0) -and ($appAgent -eq 0) -and ($logAgent -eq 1)) {
    $addLocal += "NF"
	$app= "NF"
}
<#
if (($upgrade) -and ($uninstall) -and ($partialuninstall -ne "")) {
    Write-Host "Upgradation, uninstallation and partialuninstallation can't be done simultaneously"
    Write-Host "Please select right option"
    exit
} 
#>
#For enabling the saas feature
if ($saas){
$MSIArgs += " SAAS_PRO=1"
}
if ($silent) {
    $uiState = "/qn"
} else {
    $uiState = ""
}
#For Help 
if ($help){
Write-Host	"----------------------------------------------------HELP----------------------------------------------"
Write-Host ""
Write-Host ""
Write-Host "[-tier tier] -- The tier name a logical grouping of applications"
Write-Host "[-controller] -- TO pass controller value"
Write-Host "[-instance] -- TO pass instance value"
Write-Host "[-protocol ] -- Communication protocol to use (WSS/TCP)"
Write-Host "[-tags]-- Provide the value for tags"
Write-Host "[-port 80] -- Provide the value for Port"
Write-Host "[-enable_listen 0] -- Provide the value for enable_listen"
Write-Host "[-attributes] -- Provide the value for attributes"
Write-Host "[-appAgent 1] -- Install Applicaton Agent, use this if you want to install the app agent"
Write-Host "[-machineAgent 1] -- Install Machine Agent, use this if you want to install the machine agent"
Write-Host "[-logAgent 1] -- Install Netforest Log Agent, use this if you want to install the log agent"
Write-Host "[-nfLogBeat 1] -- Install winlogBeat as NFLogBeat, use this if you want to install"
Write-Host "[-udp 1] -- TO enable udp option "
Write-Host "[-poolName] -- List of pool names to monitor separated by comma"
Write-Host "[-winapp 1] -- TO install WindowsApplicationDriver_1.2.1.msi & winsdksetup.exe"
Write-Host "[-nfIndexPrefix ] -- NF Index prefix, use only with nfagent enabled"
Write-Host "[-nfServer ] -- NF server hostname/IP, use only with nfagent enabled"
Write-Host "[-nfEnv] -- NF env name, use only with nfagent enabled"
Write-Host "[-nfReloadPort ] -- NF Reload Port, use only with nfagent enabled"
Write-Host "[-upgrade 1] -- TO upgrade installer on server "
Write-Host "[-silent ] -- To do silent installation "
Write-Host "[-remoteinstall 1] -- TO remote installtion"
Write-Host "[-$ndproxy] -- keyword for NDproxy setting"
Write-Host "[-saas 1] -- TO enable saas feature"
Write-Host ""
Write-Host ""

Write-Host "Example

.\install.ps1 -appAgent 1 -machineAgent 1 -logAgent 0  -tier tier -nfServer 10.20.0.74:7676 -controller 10.20.0.74:7892 -instance Instance1  -poolName "pool1,pool2" -port 80 -enable_listen 1 -remoteinstall 1 -udp 1 -winapp 1  -upgrade 1 -silent
"
Write-Host ""
Write-Host ""


exit


}
#For uninstalling the products
if ($uninstall) {
    $MSIArgs += " OPERATION=uninstall"
    if ($remoteinstall -eq 0) {
        if (IsAgentInstall){
            $path = Read-Host -Prompt "Enter the path of msi file for uninstallation"
            Write-Host "uninstalling Cavisson Agent modules..."
            Write-Host "uninstallation will take time...."
           $Cur= (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |  Select-Object DisplayName, DisplayVersion | Select-String -Pattern CavMachineAgent) 
			$Cur2=(Get-ItemProperty HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |  Select-Object DisplayName, DisplayVersion | Select-String -Pattern CavMachineAgent)
            $p= "@{DisplayName=CavMachineAgent; DisplayVersion=(?<content>.*)}" 
			
            #($Cur2 -match $p) -or ($Cur -match $p)
            #$version=$Matches['content']
            #if (Test-Path $path\Cavisson-Agent-Installer.$version.msi){
				if (Test-Path $path\Cavisson-Agent-Installer.msi){
                #Start-Process -FilePath "msiexec" -Wait -ArgumentList "/x $path/Cavisson-Agent-Installer.$version.msi $uiState /log $logFile"
				Start-Process -FilePath "msiexec" -Wait -ArgumentList "/x $path/Cavisson-Agent-Installer.msi $uiState /log $logFile"				
                [Environment]::SetEnvironmentVariable("NFHOME",$null,"Machine")				
                [Environment]::SetEnvironmentVariable("NDHOME",$null,"Machine")				
                [Environment]::SetEnvironmentVariable("COR_PROFILER_PATH_32",$null,"Machine")				
                [Environment]::SetEnvironmentVariable("COR_PROFILER_PATH_64",$null,"Machine")
                Write-Host "uninstallation is complete..."
            }else {
                Write-Host "$path/Cavisson-Agent-Installer.$version.msi does not exist" -ForegroundColor Yellow
            }
            
            Write-Host "uninstallation is complete..."
        }
		#Install the msi on remote servers
    }elseif($remoteinstall -eq 1) {
        if ($dest -eq "") {
            Write-Host "  Usage: -dest is needed for remote uninstallation log file"
            $dest = Read-Host -Prompt "Enter destination directory for log file"
            $path = Read-Host -Prompt "Enter the path of msi file for uninstallation"
            if ($dest.Trim() -eq "") { return }
        }
		$hostfile = get-content "$hostfile"
	 foreach ($line in $hostfile){
    $remote3 = $line
	echo "this is ---------->$remote3"
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	 $remote=$remote3
     #   $userHostArr = $remote.Split(",")
        # For each user:host pair extract user and host
        foreach ($userHost in $remote) {
            # Extract user:host from remote delimited by ','
            $params = $userHost.Split(":")
            $usingPassword = $false
            # Password has been set by user
            if ($params.Length -eq 3) {
                $remoteUser = $params[0]
                $remotePlainPass = $params[1]
                $remoteHost = $params[2]
                $usingPassword = $true
            }
            else {
                $remoteUser = $params[0]
                $remoteHost = $params[1]
            }

            Write-Host "Uinstalling on $remoteUser@$remoteHost"
            # Default auth mechanism
            $credential = $remoteUser

            if ($usingPassword) {
                $remotePassword = ConvertTo-SecureString -AsPlainText $remotePlainPass -Force
                $credential = New-Object System.Management.Automation.PSCredential -ArgumentList $remoteUser, $remotePassword
            }
            Invoke-Command -ComputerName $remoteHost -Credential $credential -ScriptBlock {
            param ($logFile, $dest, $IsAgentInstall, $path)
                if (IsAgentInstall){
                    Write-Host "Unistalling Cavisson Agent modules..."
                    Write-Host "Uninstallation will take time........"
                    $Cur= Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |  Select-Object DisplayName, DisplayVersion | Select-String -Pattern CavMachineAgent
                    $p= "@{DisplayName=CavMachineAgent; DisplayVersion=(?<content>.*)}"
                    $Cur -match $p
                    $version=$Matches['content']
                    if (Test-Path $path\Cavisson-Agent-Installer.$version.msi){
                        Start-Process -FilePath "msiexec" -Wait -ArgumentList "/x $path/Cavisson-Agent-Installer.$version.msi $uiState /log $logFile"
                        [Environment]::SetEnvironmentVariable("NFHOME",$null,"Machine")
                        [Environment]::SetEnvironmentVariable("NDHOME",$null,"Machine")
                        [Environment]::SetEnvironmentVariable("COR_PROFILER_PATH_32",$null,"Machine")
                        [Environment]::SetEnvironmentVariable("COR_PROFILER_PATH_64",$null,"Machine")
                        Write-Host "Uninstallation is complete"
                    }else {
                        Write-Host "$path/Cavisson-Agent-Installer.$version.msi does not exist" -ForegroundColor Yellow
                    }
                }
            } -ArgumentList $logFile, $dest, ${Function:IsAgentInstall}, $path
        }
        break
    }
	}
    
}
elseif ($partial -eq "cmon") {
    if ($remoteinstall -eq 0) {
        uninstallCavwmon $installedPath $logFile
       
    }elseif ($remoteinstall -eq 1) {
        if ($dest -eq "") {
            Write-Host "  Usage: -dest is needed for remote uninstallation log file"
            $dest = Read-Host -Prompt "Enter destination directory for log file"
            if ($dest.Trim() -eq "") { return }
        }
	$hostfile = get-content "$hostfile"
		foreach ($line in $hostfile){
    $remote3 = $line
	echo "this is ---------->$remote3"
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	 $remote=$remote3
        #$userHostArr = $remote.Split(",")
        # For each user:host pair extract user and host
        foreach ($userHost in $remote) {
            # Extract user:host from remote delimited by ','
            $params = $userHost.Split(":")
            $usingPassword = $false
            # Password has been set by user
            if ($params.Length -eq 3) {
                $remoteUser = $params[0]
                $remotePlainPass = $params[1]
                $remoteHost = $params[2]
                $usingPassword = $true
            }
            else {
                $remoteUser = $params[0]
                $remoteHost = $params[1]
            }

            Write-Host "Uinstalling on $remoteUser@$remoteHost"
            # Default auth mechanism
            $credential = $remoteUser

            if ($usingPassword) {
                $remotePassword = ConvertTo-SecureString -AsPlainText $remotePlainPass -Force
                $credential = New-Object System.Management.Automation.PSCredential -ArgumentList $remoteUser, $remotePassword
            }
            Invoke-Command -ComputerName $remoteHost -Credential $credential -ScriptBlock {
            param ($logFile, $dest, $IsAgentInstall, $installedPath, $uninstallCavwmon, $checkpath )
                Write-Host "Unistalling Cavisson Agents..."
                uninstallCavwmon $installedPath $logFile
                Write-Host "Uninstallation is complete"
            } -ArgumentList $logFile, $dest, ${Function:IsAgentInstall}, $installedPath, ${function:uninstallCavwmon}, ${function:checkpath}
        }
        break
    }
    }
}
elseif ($partial -eq "nd") {
    if ($remoteinstall -eq 0) {
        uninstallND $installedPath $logFile
       
    }elseif($remoteinstall -eq 1) {
        if ($dest -eq "") {
            Write-Host "  Usage: -dest is needed for remote uninstallation log file"
            $dest = Read-Host -Prompt "Enter destination directory for log file"
            if ($dest.Trim() -eq "") { return }
        }


$hostfile = get-content "$hostfile"
		foreach ($line in $hostfile){
    $remote = $line.Split(',')
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	echo $remote
	 }
	 
	 foreach ($line in $hostfile){
    $remote3 = $line
	echo "this is ---------->$remote3"
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	 $remote=$remote3
        #$userHostArr = $remote.Split(",")
        # For each user:host pair extract user and host
        foreach ($userHost in $remote) {
            # Extract user:host from remote delimited by ','
            $params = $userHost.Split(":")
            $usingPassword = $true
            # Password has been set by user
            if ($params.Length -eq 3) {
                $remoteUser = $params[0]
                $remotePlainPass = $params[1]
                $remoteHost = $params[2]
                $usingPassword = $true
            }
            else {
                $remoteUser = $params[0]
                $remoteHost = $params[1]
            }

            Write-Host "Uinstalling on $remoteUser@$remoteHost"
            # Default auth mechanism
            $credential = $remoteUser

            if ($usingPassword) {
                $remotePassword = ConvertTo-SecureString -AsPlainText $remotePlainPass -Force
                $credential = New-Object System.Management.Automation.PSCredential -ArgumentList $remoteUser, $remotePassword
            }
            Invoke-Command -ComputerName $remoteHost -Credential $credential -ScriptBlock {
            param ($logFile, $dest, $IsAgentInstall, $installedPath, $uninstallND, $checkpath )
                Write-Host "Unistalling Cavisson AppAgents..."
                uninstallND $installedPath $logFile
                Write-Host "AppAgent Uninstallation is complete"
            } -ArgumentList $logFile, $dest, ${Function:IsAgentInstall}, $installedPath, ${function:uninstallND}, ${function:checkpath}
        }
        break
    }
    }
}
elseif ($partial -eq "nf") {
    if ($remoteinstall -eq 0) {
        uninstallNF $installedPath $logFile
       
    }elseif($remoteinstall -eq 1) {
        if ($dest -eq "") {
            Write-Host "  Usage: -dest is needed for remote uninstallation log file"
            $dest = Read-Host -Prompt "Enter destination directory for log file"
            if ($dest.Trim() -eq "") { return }
        }
 $hostfile = get-content "$hostfile"
		 foreach ($line in $hostfile){
    $remote3 = $line
	echo "this is ---------->$remote3"
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	 $remote=$remote3
	 
        #$userHostArr = $remote.Split(",")
        # For each user:host pair extract user and host
        foreach ($userHost in $remote) {
            # Extract user:host from remote delimited by ','
            $params = $userHost.Split(":")
            $usingPassword = $false
            # Password has been set by user
            if ($params.Length -eq 3) {
                $remoteUser = $params[0]
                $remotePlainPass = $params[1]
                $remoteHost = $params[2]
                $usingPassword = $true
            }
            else {
                $remoteUser = $params[0]
                $remoteHost = $params[1]
            }

            Write-Host "Uinstalling on $remoteUser@$remoteHost"
            # Default auth mechanism
            $credential = $remoteUser

            if ($usingPassword) {
                $remotePassword = ConvertTo-SecureString -AsPlainText $remotePlainPass -Force
                $credential = New-Object System.Management.Automation.PSCredential -ArgumentList $remoteUser, $remotePassword
            }
            Invoke-Command -ComputerName $remoteHost -Credential $credential -ScriptBlock {
            param ($logFile, $dest, $IsAgentInstall, $installedPath, $uninstallNF, $checkpath )
                Write-Host "Unistalling Cavisson LogAgent..."
                uninstallCavwmon $installedPath $logFile
                Write-Host "LogAgent Uninstallation is complete"
            } -ArgumentList $logFile, $dest, ${Function:IsAgentInstall}, $installedPath, ${function:uninstallNF}, ${function:checkpath}
        }
        break
    }
	}
    
}
elseif ($partial -eq "cmon,nd") {
    if ($remoteinstall -eq 0) {
        uninstallND $installedPath $logFile
        uninstallCavwmon $installedPath $logFile
       
    }elseif($remoteinstall -eq 1) {
        if ($dest -eq "") {
            Write-Host "  Usage: -dest is needed for remote uninstallation log file"
            $dest = Read-Host -Prompt "Enter destination directory for log file"
            if ($dest.Trim() -eq "") { return }
        }
	 $hostfile = get-content "$hostfile"
		foreach ($line in $hostfile){
    $remote = $line.Split(',')
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	echo $remote
	 }
	 
	 foreach ($line in $hostfile){
    $remote3 = $line
	echo "this is ---------->$remote3"
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	 $remote=$remote3
		
       # $userHostArr = $remote.Split(",")
        # For each user:host pair extract user and host
        foreach ($userHost in $remote) {
            # Extract user:host from remote delimited by ','
            $params = $userHost.Split(":")
            $usingPassword = $false
            # Password has been set by user
            if ($params.Length -eq 3) {
                $remoteUser = $params[0]
                $remotePlainPass = $params[1]
                $remoteHost = $params[2]
                $usingPassword = $true
            }
            else {
                $remoteUser = $params[0]
                $remoteHost = $params[1]
            }

            Write-Host "Uinstalling on $remoteUser@$remoteHost"
            # Default auth mechanism
            $credential = $remoteUser

            if ($usingPassword) {
                $remotePassword = ConvertTo-SecureString -AsPlainText $remotePlainPass -Force
                $credential = New-Object System.Management.Automation.PSCredential -ArgumentList $remoteUser, $remotePassword
            }
            Invoke-Command -ComputerName $remoteHost -Credential $credential -ScriptBlock {
            param ($logFile, $dest, $IsAgentInstall, $installedPath, $uninstallND, $checkpath, $uninstallCavwmon )
                Write-Host "Unistalling Cavisson Agents..."
                uninstallND $installedPath $logFile
                uninstallCavwmon $installedPath $logFile
                Write-Host "Uninstallation is complete"
            } -ArgumentList $logFile, $dest, ${Function:IsAgentInstall}, $installedPath, ${function:uninstallND}, ${function:checkpath}, ${function:uninstallCavwmon}
        }
        break
    }
    }
}
elseif ($partial -eq "cmon,nf") {
    if ($remoteinstall -eq 0) {
        uninstallNF $installedPath $logFile
        uninstallCavwmon $installedPath $logFile
       
    }elseif($remoteinstall -eq 1) {
        if ($dest -eq "") {
            Write-Host "  Usage: -dest is needed for remote uninstallation log file"
            $dest = Read-Host -Prompt "Enter destination directory for log file"
            if ($dest.Trim() -eq "") { return }
        }
        $hostfile = get-content "$hostfile"
		foreach ($line in $hostfile){
    $remote = $line.Split(',')
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	echo $remote
	 }
	 
	 foreach ($line in $hostfile){
    $remote3 = $line
	echo "this is ---------->$remote3"
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	 $remote=$remote3
       # $userHostArr = $remote.Split(",")
        # For each user:host pair extract user and host
        foreach ($userHost in $remote) {
            # Extract user:host from remote delimited by ','
            $params = $userHost.Split(":")
            $usingPassword = $true
            # Password has been set by user
            if ($params.Length -eq 3) {
                $remoteUser = $params[0]
                $remotePlainPass = $params[1]
                $remoteHost = $params[2]
                $usingPassword = $true
            }
            else {
                $remoteUser = $params[0]
                $remoteHost = $params[1]
            }

            Write-Host "Uinstalling on $remoteUser@$remoteHost"
            # Default auth mechanism
            $credential = $remoteUser

            if ($usingPassword) {
                $remotePassword = ConvertTo-SecureString -AsPlainText $remotePlainPass -Force
                $credential = New-Object System.Management.Automation.PSCredential -ArgumentList $remoteUser, $remotePassword
            }
            Invoke-Command -ComputerName $remoteHost -Credential $credential -ScriptBlock {
            param ($logFile, $dest, $IsAgentInstall, $installedPath, $uninstallNF, $checkpath, $uninstallCavwmon )
                Write-Host "Unistalling Cavisson Agents..."
                uninstallNF $installedPath $logFile
                uninstallCavwmon $installedPath $logFile
                Write-Host "Uninstallation is complete"
            } -ArgumentList $logFile, $dest, ${Function:IsAgentInstall}, $installedPath, ${function:uninstallNF}, ${function:checkpath}, ${function:uninstallCavwmon}
        }
        break
    }
	}
    
}
elseif ($partial -eq "nf,nd") {
    if ($remoteinstall -eq 0) {
        uninstallND $installedPath $logFile
        uninstallNF $installedPath $logFile
       
    }elseif(remoteinstall -eq 1) {
        if ($dest -eq "") {
            Write-Host "  Usage: -dest is needed for remote uninstallation log file"
            $dest = Read-Host -Prompt "Enter destination directory for log file"
            if ($dest.Trim() -eq "") { return }
        }
 $hostfile = get-content "$hostfile"
		foreach ($line in $hostfile){
    $remote = $line.Split(',')
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	echo $remote
	 }
	 
	 foreach ($line in $hostfile){
    $remote3 = $line
	echo "this is ---------->$remote3"
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	 $remote=$remote3
      #  $userHostArr = $remote.Split(",")
        # For each user:host pair extract user and host
        foreach ($userHost in $remote) {
            # Extract user:host from remote delimited by ','
            $params = $userHost.Split(":")
            $usingPassword = $false
            # Password has been set by user
            if ($params.Length -eq 3) {
                $remoteUser = $params[0]
                $remotePlainPass = $params[1]
                $remoteHost = $params[2]
                $usingPassword = $true
            }
            else {
                $remoteUser = $params[0]
                $remoteHost = $params[1]
            }

            Write-Host "Uinstalling on $remoteUser@$remoteHost"
            # Default auth mechanism
            $credential = $remoteUser

            if ($usingPassword) {
                $remotePassword = ConvertTo-SecureString -AsPlainText $remotePlainPass -Force
                $credential = New-Object System.Management.Automation.PSCredential -ArgumentList $remoteUser, $remotePassword
            }
            Invoke-Command -ComputerName $remoteHost -Credential $credential -ScriptBlock {
            param ($logFile, $dest, $IsAgentInstall, $installedPath, $uninstallND, $checkpath, $uninstallNF )
                Write-Host "Unistalling Cavisson Agents..."
                uninstallND $installedPath $logFile
                uninstallNF $installedPath $logFile
                Write-Host "Uninstallation is complete"
            } -ArgumentList $logFile, $dest, ${Function:IsAgentInstall}, $installedPath, ${function:uninstallND}, ${function:checkpath}, ${function:uninstallNF}
        }
        break
    }
    }
}
#for upgrading the msi
elseif ($upgrade) {
    if ($msi -eq "") {
        $msi = Read-Host -Prompt "Cavisson-Agent-Installer MSI Path"
    }
	$services = @("CavNDProxy", "CavWMON", "NFAgent")

				# Loop through each service and check its status
				foreach ($service in $services) {
					# Check if the service exists
					$serviceObject = Get-Service -Name $service -ErrorAction SilentlyContinue
					if ($serviceObject) {
						# Check the service status
						if ($serviceObject.Status -eq "Running") {
							#Write-Output "Stopping service: $service"
							# Stop the service
							Stop-Service -Name $service > $null 3>&1
							if ($?) {
								#Write-Output "Service $service stopped."
							} else {
								Write-Output "Service $service is not stopped.Hence Exiting"
								exit 
							}
							Start-Sleep -Seconds 2
						} else {
							#Write-Output "Service $service is not running."
						}
					}
				}
    $MSIArgs += $addLocal
    $MSIArgs += " OPERATION=upgrade"
    if ($remoteinstall -eq 0) {
        if ($installVCRuntime -eq 1) {
            Write-Host "Checking if Microsoft Visual C++ runtime is installed..."
            $installed = IsVSRuntimeInstalled
            if (-not $installed) {
                Write-Host "Installing Microsoft Visual C++ 2015-2019 runtime..."
                Start-Process -FilePath "$vcExe" -Wait -ArgumentList "/install /passive /norestart /log $logFile"
				Start-Process -FilePath "$vcExe86" -Wait -ArgumentList "/install /passive /norestart /log $logFile"
            }
            else {
                Write-Host "Microsoft Visual C++ is already installed..."
            }
        }
		if ($appAgent -eq 1){
				#check_vc_redist
				Remove-Item -Path "C:\opt\cavisson\netdiagnostics\dotnet\dll\ProfilerHelper.dll" -Recurse
				#Move-Item -Path "C:\opt\cavisson\wmonitors\bin\CavWMON.exe" -Destination "C:\Windows\Temp\" 
				Remove-Item -Path "C:\opt\cavisson\netdiagnostics\dotnet\profilerhelper_folder" -Recurse
				Remove-Item -Path "C:\opt\cavisson\netdiagnostics\dotnet\profilerhelper_folder_32" -Recurse
				Remove-Item -Path "C:\Windows\Microsoft.NET\assembly\GAC_64\ProfilerHelper" -Recurse
				Remove-Item -Path "C:\Windows\Microsoft.NET\assembly\GAC_32\ProfilerHelper" -Recurse	
			}
		if ($machineAgent -eq 1) {
		Stop-Service -Name CavWMON
		Remove-Item -Path "C:\opt\cavisson\wmonitors\bin\CavWMON.exe" -Recurse
		}			
		
        Write-Host "upgrading Cavisson Agents..."
		#Move-Item -Path "C:\opt\cavisson\wmonitors\bin\CavWMON.exe" -Destination "C:\Windows\Temp\"
        Start-Process -FilePath "msiexec" -Wait -ArgumentList "/i $msi /log $logFile /norestart REINSTALL=ALL  REINSTALLMODE=vomus $uiState $MSIArgs  /L*V upgrade.logs "		
        Write-Host "Upgradation is complete..."
        if ($iisreset -eq 1) {
            Write-Host "Post installation - resetting IIS"
            iisreset /noforce /RESTART
        }
		 if ($appAgent -eq 1) {
		 if ($poolName -eq "") {
            Write-Host "App agent will monitor all pools "
		 }
            try {
                setx ND_ENABLE_ALL_POOL "1" -m
            }
            catch {
                Write-Error "Unable to set flag for monitoring all pools"
            }
        }
		if (($app -eq "CMON,ND") -or ($app -eq "CMON") -or ($app -eq "ND"))
		{
			[Environment]::SetEnvironmentVariable("NFHOME",$null,"Machine")
		}
    }
    elseif($remoteinstall -eq 1) {
	    
        if ($dest -eq "") {
            Write-Host "  Usage: -dest is needed for remote upgradation"
            $dest = Read-Host -Prompt "Enter destination directory to copy files"
            if ($dest.Trim() -eq "") { return }
        }
 $hostfile = get-content "$hostfile"
		foreach ($line in $hostfile){
    $remote = $line.Split(',')
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	echo $remote
	 }
	 
	 foreach ($line in $hostfile){
    $remote3 = $line
	echo "this is ---------->$remote3"
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	 $remote=$remote3
        #$userHostArr = $remote.Split(",")
        # For each user:host pair extract user and host
        foreach ($userHost in $remote) {
            # Extract user:host from remote delimited by ','
            $params = $userHost.Split(":")
            $usingPassword = $false
            # Password has been set by user
            if ($params.Length -eq 3) {
                $remoteUser = $params[0]
                $remotePlainPass = $params[1]
                $remoteHost = $params[2]
                $usingPassword = $true
            }
            else {
                $remoteUser = $params[0]
                $remoteHost = $params[1]
            }

            Write-Host "upgrading on $remoteUser@$remoteHost"
            # Default auth mechanism
            $credential = $remoteUser

            if ($usingPassword) {
                $remotePassword = ConvertTo-SecureString -AsPlainText $remotePlainPass -Force
                $credential = New-Object System.Management.Automation.PSCredential -ArgumentList $remoteUser, $remotePassword
            }

            if ($copy -eq 1) {
                # Initiate a new PSSession to copy files to remote
                $session = New-PSSession -ComputerName $remoteHost -Credential $credential
                Copy-Item $msi -Destination $dest -ToSession $session
                Copy-Item $vcExe -Destination $dest -ToSession $session
				Copy-Item $vcExe86 -Destination $dest -ToSession $session
            }

            # Install visual studio c++ runtime & MSI
            Invoke-Command -ComputerName $remoteHost -Credential $credential -ScriptBlock {
                param($destDir, $vsRuntime, $logFile, $msi, $pool, $iisreset, $app, $installVCRuntime, $isVSRuntimeInstalledFunc)
                if ($installVCRuntime -eq 1) {
                    Write-Host "Checking if Microsoft Visual C++ runtime is installed..."
                    # First create function and then invoke it
                    $installed = [ScriptBlock]::Create($isVSRuntimeInstalledFunc).invoke()
                    if (-not $installed) {
                        Write-Host "Installing Microsoft Visual C++ 2015-2019 runtime..."
                        $runtimePath = Join-Path -Path $destDir -ChildPath $vsRuntime
                        Start-Process -FilePath "$runtimePath" -Wait -ArgumentList "/install /passive /norestart /log $destDir\$logFile"
						$runtimePath = Join-Path -Path $destDir -ChildPath $vcExe86
                        Start-Process -FilePath "$runtimePath" -Wait -ArgumentList "/install /passive /norestart /log $destDir\$logFile"
                    }
                    else {
                        Write-Host "Microsoft Visual C++ is already installed..."
                    }
                }
                Write-Host "Upgrading Cavisson Agents..."
                Start-Process -FilePath "msiexec" -Wait -ArgumentList "/i $destDir\$msi /log $destDir\$logFile REINSTALL=ALL  REINSTALLMODE=vomus $uiState $MSIArgs"
                Write-Host "Upgradation Complete"
				if ($pool -eq "") { setx ND_ENABLE_ALL_POOL "1" -m }
				if (($app -eq "CMON,ND") -or ($app -eq "CMON") -or ($app -eq "ND"))
					{
						[Environment]::SetEnvironmentVariable("NFHOME",$null,"Machine")
					}
                if ($iisreset -eq 1) {
                    Write-Host "Post upgradation - resetting IIS"
                    iisreset /noforce /RESTART
                }
            } -ArgumentList $dest, $vcExe, $logFile, $msi, $poolName, $iisreset, $app, $installVCRuntime, ${function:IsVSRuntimeInstalled}
        }
    }
    }
}
else {
    #normal installation
    if ($msi -eq "") {
        $msi = Read-Host -Prompt "CavMachine Agent MSI Path"
    }
    #install VC runtime only if ND APM agent is to be installed;
    $installVCRuntime = $appAgent

    #pass agent modules to be installed in argument list to msi for
    $MSIArgs += $addLocal
    
    $MSIArgs += " OPERATION=install"
      
	 $addLocal = " ADDLOCAL=CONFIGFILES,"
#For installation of machineagent ,appagent and logagent
if (($machineAgent -eq 1) -and ($appAgent -eq 1) -and ($logAgent -eq 1)) {
    $addLocal += "CMON,ND,NF"
	$app= "CMON,ND,NF"
}
#For installation of machineagent ,appagent 
if (($machineAgent -eq 1) -and ($appAgent -eq 1) -and ($logAgent -eq 0)) {
    $addLocal += "CMON,ND"
	$app= "CMON,ND"
}
#For installtion of machineagent
if (($machineAgent -eq 1) -and ($appAgent -eq 0) -and ($logAgent -eq 0)) {
    $addLocal += "CMON"
	$app= "CMON"
}
#For installation of machineagent and logagent
if (($machineAgent -eq 1) -and ($appAgent -eq 0) -and ($logAgent -eq 1)) {
    $addLocal += "CMON,NF"
	$app= "CMON,NF"
}
#For installation of appagent
if (($machineAgent -eq 0) -and ($appAgent -eq 1) -and ($logAgent -eq 0)) {
    $addLocal += "ND"
	$app= "ND"
}
#For installation of appagent and logagent
if (($machineAgent -eq 0) -and ($appAgent -eq 1) -and ($logAgent -eq 1)) {
    $addLocal += "ND,NF"
	$app= "ND,NF"
}
#For installation of logagent
if (($machineAgent -eq 0) -and ($appAgent -eq 0) -and ($logAgent -eq 1)) {
    $addLocal += "NF"
	$app= "NF"
} 
	  
	if ($saas ){
	if($projectkey -eq ""){
	$projectkey=Read-Host -Prompt "Project key"
	
	
	}
	$MSIArgs += " PROJECTKEY=`"$projectkey`" URL=`"$url`" TIERATTRIBUTES=`"$tierattributes`" APPNAME=`"$appname`" ENDPOINT=`"$endpoint`""
	}
	
	else{
    

    
    if ($logAgent -eq 1) {
       
       

        
		$MSIArgs += " INDEX_PREFIX=`"$nfIndexPrefix`" NFSERVER=`"$nfServer`" ENV=`"$nfEnv`" RELOADPORT=`"$nfReloadPort`"" 
    }
}
    #Bug - 146613
	if ($ndproxy -eq "") {
    $ip = (Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias (Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | Select-Object -First 1).InterfaceAlias).IPAddress
    $nd_port = "1111"
    $ndproxy = $ip + ":" + $nd_port
}
	
    $MSIArgs += " NDSERVER=`"$controller`" Port=`"$port`" ENABLE_LISTEN=`"$enable_listen`" TIER=`"$tier`" INSTANCE=`"$instance`" NDCPROTOCOL=`"$protocol`" TAGS=`"$tags`" ATTRIBUTES=`"$attributes`" USERNAME=`"$username`" PASSWORD=`"$password`" SERVER=`"$server`" NDPROXY=`"$ndproxy`" INSTALLDIR=`"$installdir`" CAVWMON=`"$machineAgent`" NFAGENT=`"$logAgent`" NDAGENT=`"$appAgent`" NFLOGBEAT=`"$nfLogBeat`""

    if ($poolName) { $MSIArgs += " APP=`"$poolName`"" }
    
    # If remote argument is not provided we assume it to be
    # local installation
    
	if (($app -eq "CMON,ND") -or ($app -eq "CMON") -or ($app -eq "ND") -or ($app -eq "CMON,ND,NF") -or ($app -eq "ND,NF") -or ($app -eq "CMON,NF") -or ($app -eq "NF")){
			[Environment]::SetEnvironmentVariable("NFHOME",$null,"Machine")
			if ($? -ne 1){
			Write-Host "Not running with administrator privileges. Please run this script as an administrator."
			exit 0
				}
		}

    if ($remoteinstall -eq 0) {
        if ($installVCRuntime -eq 1) {
            Write-Host "Checking if Microsoft Visual C++ runtime is installed..."
            $installed = IsVSRuntimeInstalled
            if (-not $installed) {
                Write-Host "Installing Microsoft Visual C++ 2015-2019 runtime..."
                Start-Process -FilePath "$vcExe" -Wait -ArgumentList "/install /passive /norestart /log $logFile"
				Start-Process -FilePath "$vcExe86" -Wait -ArgumentList "/install /passive /norestart /log $logFile"
            }
            else {
                Write-Host "Microsoft Visual C++ is already installed..."
            }
        }

        Write-Host "Installing Cavisson Agent Modules..."
		#Bug_id - 148404
		if ($appAgent -eq 1) {
			$dotnetVersion = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -Name Release).Release
			$highest_version_output = reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\full" /v version

			# Extract version number from output
			$highest_version = ($highest_version_output | Select-String "version" | ForEach-Object { $_ -split "\s+" })[-1]

			if ($dotnetVersion -lt 378389) {
			Write-Host "Error: The installed .NET version is less than 4.5. Detected higher version is $highest_version. Exiting. Please contact Cavisson support for assistance."
			exit 1
			} 
		}
        $p=Start-Process -FilePath "msiexec" -PassThru -Wait -ArgumentList "/i $msi /log $logFile /norestart $uiState $MSIArgs"
        $exit_code = $p.ExitCode
		#write-host $exit_code
		$HOSTNAME = hostname         
		if ($exit_code -eq 0) {
			Write-Host "Cavisson agent is deployed successfully on $HOSTNAME."
		}
		else {
			Write-Host "Cavisson agent is failed to deployed on $HOSTNAME with exitcode:$exit_code"
		}
		if ($udp -eq 1) {
			#Write-Host "udp"
		    Copy-Item -Path "C:\opt\cavisson\netdiagnostics\dotnet\profilerhelper_udp_folder\profilerhelper_udp_folder\v4.0_1.0.0.0__fcb740f63446e2f2\ProfilerHelper.dll" -Destination "C:\Windows\Microsoft.NET\assembly\GAC_64\ProfilerHelper\v4.0_1.0.0.0__fcb740f63446e2f2" -Force
			Copy-Item -Path "C:\opt\cavisson\netdiagnostics\dotnet\profilerhelper_udp_folder_32\profilerhelper_udp_folder_32\v4.0_1.0.0.0__fcb740f63446e2f3\ProfilerHelper.dll" -Destination "C:\Windows\Microsoft.NET\assembly\GAC_32\ProfilerHelper\v4.0_1.0.0.0__fcb740f63446e2f2" -Force

		}
		if ($winapp -eq 1){
		Start-Process $msi1 /qn  2>&1 > "error.log"
		Write-Host "Installing winsdksetup it will take 4-5 min..."
		Start-Process $msi2 /S  2>&1 > "error.log"
		Start-Sleep -Seconds 201
		}
		
		if ($appAgent -eq 1) {
		if ($poolName -eq "") {
            Write-Host "App agent will monitor all pools  "
		    }
			
            try {
                setx ND_ENABLE_ALL_POOL "1" -m
            }
            catch {
                Write-Error "Unable to set flag for monitoring all pools"
            }
			
		if (($app -eq "CMON,ND") -or ($app -eq "CMON") -or ($app -eq "ND")){
			[Environment]::SetEnvironmentVariable("NFHOME",$null,"Machine")
		}
        }
        if ($iisreset -eq 1) {
            Write-Host "Post install - resetting IIS"
            iisreset /noforce /RESTART
        }
		


  }
    elseif($remoteinstall -eq 1) {
        if ($dest -eq "") {
            Write-Host "  Usage: -dest is needed for remote installation"
            $dest = Read-Host -Prompt "Enter destination directory to copy files"
            if ($dest.Trim() -eq "") { return }
        }
		#if ($hostfile -eq ""){
		#$HostFile=Read-host "Enter the host file"
		
		$hostfile = get-content "$hostfile"
		#}

foreach ($line in $hostfile){
    $remote3 = $line
   # [array]$OutputFile +=  $Arr[0] + "|" + $Arr[4] + "|" + $Arr[1] + "|" + $Arr[2] + "|" + "@@" + $Arr[5]
	#$remote=$Arr[0]
	 $remote=$remote3
       # $userHostArr = $remote.Split(",")
        # For each user:host pair extract user and host
        foreach ($userHost in $remote) {
            # Extract user:host from remote delimited by ','
            $params = $userHost.Split(":")
            $usingPassword = $true
            # Password has been set by user
            if ($params.Length -eq 3) {
                $remoteUser = $params[0]
                $remotePlainPass = $params[1]
                $remoteHost = $params[2]
			
                $usingPassword = $true
            }
            else {
                $remoteUser = $params[0]
                $remoteHost = $params[1]
            }

            #Write-Host "Installing on $remoteUser@$remoteHost"
            # Default auth mechanism
            $credential = $remoteUser

            if ($usingPassword) {
                $remotePassword = ConvertTo-SecureString -AsPlainText $remotePlainPass -Force
                $credential = New-Object System.Management.Automation.PSCredential -ArgumentList $remoteUser, $remotePassword

            }

            if ($copy -eq 1) {
                # Initiate a new PSSession to copy files to remote
				
                $session = New-PSSession -ComputerName $remoteHost -Credential $credential
				$time_date=Get-Date
                Write-Host "$time_date | Info | Copying the $msi on server $remoteHost"
                Copy-Item $msi -Destination $dest -ToSession $session 2>&1 > "error.log"
				if ( -not $?){
				$time_date=Get-Date
                Write-Host "$time_date | [Error] | Unable to copy  the $msi on server $remoteHost.Please check the error.log file"
				
				} 
				else{
				$time_date=Get-Date
                Write-Host "$time_date | Info | Copied  the $msi on server $remoteHost"
				}
				
				$time_date=Get-Date
                Write-Host "$time_date | Info | Copying the $vcExe on server $remoteHost"

                Copy-Item $vcExe -Destination $dest -ToSession $session 2>&1 > "error.log"
				Copy-Item $vcExe86 -Destination $dest -ToSession $session 2>&1 > "error_x86.log"
				if ( -not $?){
				$time_date=Get-Date
                Write-Host "$time_date | [Error] | Unable to copy  the $vcExe or $vcExe86 on server $remoteHost.Please check the error.log file"
				
				} 
				else{
				$time_date=Get-Date
                Write-Host "$time_date | Info | Copied  the $vcExe and $vcExe86 on server $remoteHost"
				}
            }

            # Install visual studio c++ runtime & MSI
            Invoke-Command -ComputerName $remoteHost -Credential $credential -ScriptBlock {
                param($destDir, $vsRuntime, $logFile, $msi, $pool, $iisreset, $msiArgs, $app,$hostfile, $installVCRuntime, $isVSRuntimeInstalledFunc)
                if ($installVCRuntime -eq 1) {
                $time_date=Get-Date 
                Write-Host "$time_date | Info | Checking if Microsoft Visual C++ runtime is installed..."
                    # First create function and then invoke it
                    $installed = [ScriptBlock]::Create($isVSRuntimeInstalledFunc).invoke()
                    if (-not $installed) {
                        Write-Host "$time_date | Info | Installing Microsoft Visual C++ 2015-2019 runtime..."
                        $runtimePath = Join-Path -Path $destDir -ChildPath $vsRuntime
                        Start-Process -FilePath "$runtimePath" -Wait -ArgumentList "/install /passive /norestart /log $destDir\$logFile" 2>&1 > "error.log"
                        #$runtimePath = Join-Path -Path $destDir -ChildPath $vcExe86
                        Start-Process -FilePath "$destDir\VC_redist.x86.exe" -Wait -ArgumentList "/install /passive /norestart /log $destDir\$logFile" 2>&1 > "error.log"
						if ( -not $?){
				         $time_date=Get-Date
                         Write-Host "$time_date | [Error] | Unable to install  the $vcExe on server $remoteHost.Please check the error.log file"
				         
				       } 
				       else{
				       $time_date=Get-Date
                       Write-Host "$time_date | Info | Successfully installed the $vcExe on server $remoteHost"
				      }
                    }
                    else {
					    $time_date=Get-Date
                        Write-Host "$time_date | Info | Microsoft Visual C++ is already installed..."
                    }
                }
				$time_date=Get-Date
                Write-Host "$time_date | Info | Installing Cavisson Agent modules..."
                #Write-Host "MSIArgs=$MSIArgs"
                Start-Process -FilePath "msiexec" -Wait -ArgumentList "/i $destDir\$msi /log $destDir\$logFile $uiState $MSIArgs" 2>&1 > "error.log"
				if ( -not $?){
				         $time_date=Get-Date
                         Write-Host "$time_date | [Error] | Unable to install  the $msi on server $remoteHost.Please check the error.log file"
				         
				       } 
				       else{
				       $time_date=Get-Date
                       Write-Host "$time_date | Info | Successfully installed the $msi on server $remoteHost"
				      }
            #    Write-Host "cavisson agent installed"
				if ($pool -eq "") { setx ND_ENABLE_ALL_POOL "1" -m 2>&1 > "error.log"}
				if (($app -eq "CMON,ND") -or ($app -eq "CMON") -or ($app -eq "ND")){
					[Environment]::SetEnvironmentVariable("NFHOME",$null,"Machine")
				}
                if ($iisreset -eq 1) {
                    Write-Host "Post install - resetting IIS"
                    iisreset /noforce /RESTART
                }
            } -ArgumentList $dest, $vcExe, $logFile, $msi, $poolName, $iisreset, $MSIArgs, $app,$hostfile,$installVCRuntime, ${function:IsVSRuntimeInstalled}
        }
		}
    }
}

