clear
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$egurkhaPath=(Get-Item Env:EGURKHA_INSTALL_DIR).value.ToString()
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$egEncryPath=$scriptPath+"\EGFileEncryption.psm1"
$egDatnKy=$scriptPath+"\GetDatnKeyFiles.psm1"
Import-Module $egEncryPath,$egDatnKy

$testargs=$args
$userName=$testargs[0]
$Password=Eg-O365Dcr -EncStr $testargs[1]
$Proxycrds=$testargs[2]
$pxycrds=$Proxycrds.split("#")
$proxyUsr=$pxycrds[0]
$proxyPass=Eg-O365Dcr -EncStr $pxycrds[1]
$Rptcrds=$testargs[4].split("#")
$reportingname=$Rptcrds[0]
$mTime=$Rptcrds[1]

$azureVal=Eg-GetAzureEnv -UserName $userName
$azureEnvArr=$azureVal.Split(',')

$ManualThrottle=0
[double]$ActiveThrottle=.25
$ResetSeconds=870

$WriteLog=$true
$LogFile = $egurkhaPath+'/agent/MTM/'+$reportingname+"\audits.log"
$LogFile1 = $egurkhaPath+'/agent/MTM/'+$reportingname+"\audits1.log"


$isFrstTimLog=$true
# Writes output to a log file with a time date stamp
Function Write-Log {
	Param ([string]$string)

	[string]$date = Get-Date -Format G
	
    if ($WriteLog) {
       ( "[" + $date + "] - [" + $reportingname+"] mTime -  " + $mTime + " - " + $string ) | Out-File -FilePath $LogFile -Append } 

    if($isFrstTimLog){     
        if ($WriteLog -eq $true){ #if flag is true 
            if ([System.IO.File]::Exists($LogFile) -and (Get-Item $LogFile).length -gt 2mb) {  #if the size of file is greater than 1MB 
                if([System.IO.File]::Exists($LogFile1)){  #if logfile1 already exists, delete logfile1 
                    Remove-Item $LogFile1 
                } 
                Rename-Item $LogFile $LogFile1 
            }
        }
        $isFrstTimLog=$false
    }

}

Function Start-SleepWithProgress {
	Param([int]$sleeptime)

	For ($i=0;$i -le $sleeptime;$i++){
		$timeleft = ($sleeptime - $i);
		Write-Progress -Activity "Sleeping" -CurrentOperation "$Timeleft More Seconds" -PercentComplete (($i/$sleeptime)*100);
		start-sleep 1
	}
	
	Write-Progress -Completed -Activity "Sleeping"
}

Function New-CleanO365Session {


    $Credential = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $(convertto-securestring $Password -asplaintext -force)
	
    $i = 0
	while (($Credential -eq $Null) -and ($i -lt 5)){
		$script:Credential = Get-Credential -Message "Please provide your Exchange Online Credentials"
		$i++
	}

	if ($Credential -eq $null){
		Write-log "[Error] - Failed to get credentials"
		Write-Error -Message "Failed to get credentials" -ErrorAction Stop
	}

	Write-Log "Removing all PS Sessions"

	Get-PSSession | Remove-PSSession -Confirm:$false
	[System.GC]::Collect()
	Write-Log ("Sleeping 15 seconds for Session Tear Down")
	Start-SleepWithProgress -SleepTime 15
	$Error.Clear()
	
	# Create the session
	Write-Log "Creating new PS Session"
	$sessionOption = New-PSSessionOption -SkipRevocationCheck
	if($proxyUsr -ne 'none' -and $proxyPass -ne 'none'){
	    $proxyCred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $proxyUsr, $(convertto-securestring $proxyPass -asplaintext -force)
	    $sessionOption = New-PSSessionOption -SkipRevocationCheck -ProxyAccessType IEConfig -ProxyAuthentication basic -ProxyCredential $proxyCred
	}
	$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $azureEnvArr[1] -Credential $Credential -Authentication Basic -AllowRedirection -SessionOption $sessionOption -WarningAction SilentlyContinue
		
	# Check for an error while creating the session
	if ($Error.Count -gt 0){
	
		Write-Log "[ERROR] - Error while setting up session"
		Write-log $Error
		$ErrorCount++
		if ($ErrorCount -gt 3){
			$deleky=0
			Write-log "[ERROR] - Failed to setup session after multiple tries"
			Write-log "[ERROR] - Aborting Script"
			exit		
		}
		Write-Log "Sleeping 60s so that issue can potentially be resolved"
		Start-SleepWithProgress -sleeptime 60

		New-CleanO365Session
	}
	else {
		$ErrorCount = 0
	}
	
	# Import the PS session
	$null = Import-PSSession $session -AllowClobber -WarningAction SilentlyContinue -DisableNameChecking
	
	# Set the Start time for the current session
	Set-Variable -Scope script -Name SessionStartTime -Value (Get-Date)

}

Function Test-O365Session {

	$ObjectTime = Get-Date
	$SessionInfo = $null
	$SessionInfo = Get-PSSession

	if ($SessionInfo -eq $null) { 
		Write-Log "[ERROR] - No Session Found"
		Write-log "Recreating Session"
		New-CleanO365Session
	}	
	elseif ($SessionInfo.State -ne "Opened"){
		Write-Log "[ERROR] - Session not in Open State"
		Write-log ($SessionInfo | fl | Out-String )
		Write-log "Recreating Session"
		New-CleanO365Session
	}
	elseif (($ObjectTime - $SessionStartTime).totalseconds -gt $ResetSeconds){
		Write-Log ("Session Has been active for greater than " + $ResetSeconds + " seconds" )
		Write-Log "Rebuilding Connection"
		[int]$DelayinSeconds = ((($ResetSeconds * $ActiveThrottle) / 2) - 15)

		if ($DelayinSeconds -gt 0){
		
			Write-Log ("Sleeping " + $DelayinSeconds + " addtional seconds to allow throttle recovery")
			Start-SleepWithProgress -SleepTime $DelayinSeconds
		}
		else {
			Write-Log ("Active Delay calculated to be " + ($DelayinSeconds + 15) + " seconds no addtional delay needed")
		}

		New-CleanO365Session
	}
	else {

	}

	if ($ManualThrottle -gt 0){
		Write-log ("Sleeping " + $ManualThrottle + " milliseconds")
		Start-Sleep -Milliseconds $ManualThrottle
	}
}

Function Get-EstimatedTimeToCompletion {
	param([int]$ProcessedCount)

	$ProcessedCount++
	if (($ProcessedCount % 100) -eq 0){
		$CurrentDate = Get-Date
		$AveragePerObject = (((($CurrentDate) - $ScriptStartTime).totalseconds) / $ProcessedCount)
		Write-Log ("[STATS] - Total Number of Objects:     " + $ObjectCount)
		Write-Log ("[STATS] - Number of Objects processed: " + $ProcessedCount)
		Write-Log ("[STATS] - Average seconds per object:  " + $AveragePerObject)
		Write-Log ("[STATS] - Estimated completion time:   " + $CurrentDate.addseconds((($ObjectCount - $ProcessedCount) * $AveragePerObject)))
	}

	return $ProcessedCount
}

$rptPath='MTM/'+$reportingname
$MyDir=$egurkhaPath+'/agent/MTM/'+$reportingname

if(!(Test-Path -Path $MyDir )){
    New-Item -ItemType directory -Path $MyDir
}
$isErrorOccur= $false

$endDat = Get-Date
$startDat=$endDat.AddMinutes(-$mTime)
Set-StrictMode -Version 2

$ErrorCount = 0
New-CleanO365Session
$ScriptStartTime = Get-Date

$Error.Clear()
    Try{
        $auditOper = Eg-WriteFile -ComntRptPath $rptPath -FileName "MTMdAuditOper" -keyFileName "kMTMdAuditOper" -EgPath $egurkhaPath
        $AuditOutput=1
        while ($AuditOutput) {
            $AuditOutput = Search-UnifiedAuditLog -StartDate $startDat -EndDate $endDat -SessionId "2" -ResultSize 500 -SessionCommand ReturnLargeSet | Select-Object AuditData,Operations,RecordType,CreationDate,UserIds
            if($AuditOutput){
                $AuditOutput | Where-Object {$_.RecordType -like 'MicrosoftTeam*'}| Export-Csv $auditOper[1] -NoTypeInformation -Append
            }
        }
        $null=Protect-File  $auditOper[1] -Algorithm AES -KeyAsPlainText $auditOper[0] -RemoveSource
        }Catch{
	        $egurkhaRprtPath=  $egurkhaPath+'\agent\'+$rptPath+'\'
            $fileRead=Get-ChildItem -Path $egurkhaRprtPath |Where-Object {$_.Name -like 'kMTMdAuditOper*.dat'}| Sort-Object LastWriteTime -Descending | Select Name -First 1
            foreach($file in $fileRead){
                    $fileName=([String]$file.Name).Trim()
                    Remove-Item $egurkhaRprtPath$fileName -Force
            }
	    }



$csvDir=$egurkhaPath+'/agent/MTM/'+$reportingname+'/'
Eg-DeleteCsvFiles -FilePath $csvDir -Pattern 'MTMdAuditOper'

Write-Log "Script Complete Destroying PS Sessions"
Get-PSSession | Remove-PSSession -Confirm:$false
