##/*********************************************************************************
##Author                :   Vishnu S
##Purpose               :   Display the success and failed logins from audit log in O365
##Created               :   24/01/2018
##Modified By	        :   Prabaharan.T
##/*********************************************************************************
$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
$PSDefaultParameterValues = @{'*:Encoding' = 'utf8'}

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$egurkhaPath=($scriptPath.Substring(0,$scriptPath.ToLower().IndexOf('egurkha')+7)).Trim()
$egEncryPath=$scriptPath+"\EGFileEncryption.psm1"
$egDatnKy=$scriptPath+"\GetDatnKeyFiles.psm1"
Import-Module $egEncryPath,$egDatnKy

clear

#<#
$TestInputs=$args
$userName=$TestInputs[0]
$Password=Eg-O365Dcr -EncStr $TestInputs[1]
$proxyUsr=$TestInputs[2]
$proxyPass=Eg-O365Dcr -EncStr $TestInputs[3]
$rpmea=$TestInputs[4]
$rpArr=$rpmea.Split('#')
$reportingNam=$rpArr[0]
$meaperiod=$rpArr[1]
$proxyserverip=($rpArr[2]).ToString().trim()
$appDetails=$TestInputs[5]
if($appDetails -and $appDetails -ne 'none'){
    $appDetailsArr=($appDetails).ToString() -Split ("~!~")
    $clientId=$appDetailsArr[0]
    $tenantName=$appDetailsArr[1]
    $thumbPrint=$appDetailsArr[2]
}
$lstDat=$TestInputs[6]
#>

$azureVal=Eg-GetAzureEnv -UserName $userName
$azureEnvArr=$azureVal.Split(',')
$langPath=$egurkhaPath+'\agent\config\O365_lang.ini'
$encTyp=Eg-GetINIContent -Path $langPath -Subject 'File_Type' -Key 'encoding'
$am_Format=Eg-GetINIContent -Path $langPath -Subject 'TimeFormats' -Key 'AM' -Type $encTyp
$pm_Format=Eg-GetINIContent -Path $langPath -Subject 'TimeFormats' -Key 'PM' -Type $encTyp

$rptPath='O365/'+$reportingNam
try{
    $CultureDateTimeFormat = (Get-Culture).DateTimeFormat
    $DateFormat = $CultureDateTimeFormat.ShortDatePattern
    $TimeFormat = $CultureDateTimeFormat.LongTimePattern
    $DateTimeFormat = "$DateFormat $TimeFormat"
    $hrfrmt=((Get-Date).ToUniversalTime()).ToString('tt').Trim()
    if($hrfrmt -eq $null -or $hrfrmt -eq ''){$hrfrmt='none'}
    $frmtTim=(-$meaperiod-60)
    $format=((Get-Date).ToUniversalTime().AddMinutes($frmtTim)).ToString('tt')

    $UserDisplayName=@{}
    $sysDateFmt=(Get-Date).ToUniversalTime().AddMinutes(-60)
    $sysDat=$sysDateFmt.AddMinutes(-$meaperiod)
    $uniqUserId=@{}

    $sysDat1=(Get-Date).ToUniversalTime()
    $endDat=$sysDat1.AddMinutes(-60)
    $startDat=$endDat.AddMinutes(-$meaperiod)

    $cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $(convertto-securestring $Password -asplaintext -force)
    $sessionOption = New-PSSessionOption -SkipRevocationCheck
    if(!$proxyserverip.ToString().ToLower().Contains('none')){
        $proxyserver='http://'+$proxyserverip
        [system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy($proxyserver)
        if($proxyUsr -ne 'none' -and $proxyPass -ne 'none'){
            $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
        }
    }

    if($appDetails -and $appDetails -ne 'none'){
            Connect-ExchangeOnline -CertificateThumbPrint $thumbPrint -AppID $clientId -Organization $tenantName -PSSessionOption $sessionOption -ShowBanner:$false -WarningAction SilentlyContinue
    }else{
        Connect-ExchangeOnline -ExchangeEnvironmentName $azureEnvArr[4] -Credential $cred -PSSessionOption $sessionOption -WarningAction SilentlyContinue
    }
    #if((Get-PSSession).Availability -eq 'Available' -and (Get-PSSession).State -eq 'Opened'){
        Try{
            $writFaildLog = Eg-WriteFile -ComntRptPath $rptPath -FileName "O365FailedLogs" -keyFileName "kO365FailedLogs" -EgPath $egurkhaPath
            $curResCntFL=0
            while($true){
            $flresults=Search-UnifiedAuditLog -StartDate $startDat -EndDate $endDat -Operations "UserLoggedIn","UserLoginFailed"  -SessionId fl -SessionCommand ReturnLargeSet -ResultSize 5000 |Select-Object  CreationDate,AuditData                                 
                $flresults | Export-Csv $writFaildLog[1] -Append -Encoding $encTyp                                        
                $curResCntFL=$curResCntFL+($flresults.count)                               
                if(($curResCntFL -eq 50000) -or ($flresults.count -lt 5000)){ 
                        break                 
                } 
            }
            $null=Protect-File  $writFaildLog[1] -Algorithm AES -KeyAsPlainText $writFaildLog[0] -RemoveSource
        }Catch{
	        $egurkhaRprtPath=  $egurkhaPath+'\agent\'+$rptPath+'\'
            $fileRead=Get-ChildItem -Path $egurkhaRprtPath |Where-Object {$_.Name -like 'kO365FailedLogs*.dat'}| Sort-Object LastWriteTime -Descending | Select Name -First 1
            foreach($file in $fileRead){
                $fileName=([String]$file.Name).Trim()
                if([System.IO.File]::Exists(($egurkhaRprtPath+$fileName)) -eq 'True'){
                    Remove-Item $egurkhaRprtPath$fileName -Force
                }
            }
	    }
    #}
    $getSession=Get-PSSession -ErrorAction SilentlyContinue
    if($getSession -ne $null -and $getSession -ne ''){
	    Disconnect-ExchangeOnline -Confirm:$false
    }

    try{
        $readUsrAct=Eg-ReadFile -ComntRptPath $rptPath -FileName "O365FailedLogs" -keyFileName "kO365FailedLogs" -EgPath $egurkhaPath
        if($readUsrAct -ne $null -and [System.IO.File]::Exists($readUsrAct[1]) -eq 'True'){
            $unProtctUsrAct=$readUsrAct[1] -replace (".csv",".dat") 
            $usrActPath=Unprotect-File $unProtctUsrAct -Algorithm AES -KeyAsPlainText $readUsrAct[0]	
            $a= import-csv $usrActPath -Encoding $encTyp | Sort-Object CreationDate
            Remove-Item $usrActPath
        }
    }
    catch{
        $errmsg=$_.Exception.Message
        Write-Error -Message $errmsg
    }
    [System.GC]::GetTotalMemory($true) | out-null
    $usrLoginFailed=0
    $usrLogedIn=0
    $lastReadDat=([String]($a |select -Last 1).CreationDate).Replace(' ','#')
    $lstDat=([String]$lstDat).Replace('#',' ')
    $timDiffinMins=0
    if($lstDat -ne 'none'){
        $dat1=Eg-ParseExact -DateStr $lstDat -DateTimeFormat $DateTimeFormat -TimeFormat $TimeFormat -HourFrmt $hrfrmt
        $timDiff = New-TimeSpan -Start $dat1 -End $startDat
        $timDiffinMins=(($timDiff.Days)*24*60)+(($timDiff.Hours)*60)+($timDiff.Minutes)
    }

	#ignore previous date value if the time diff of it and now is greater than 2 hours 
    if($lstDat -eq $null -or $lstDat -eq 'none' -or $lstDat -eq '' -or $timDiffinMins -gt 120){
        $lstDat=$startDat.ToString($DateTimeFormat)
    }

    foreach($b in $a){
        $inpDatStr=([String]$b.CreationDate).Trim()
        if($inpDatStr -ne $null -and $inpDatStr -ne ''){
            $cmDat=Eg-ParseExact -DateStr $lstDat -DateTimeFormat $DateTimeFormat -TimeFormat $TimeFormat -HourFrmt $hrfrmt
            $dateCreated=Eg-ParseExact -dateStr $inpDatStr -DateTimeFormat $DateTimeFormat -TimeFormat $TimeFormat -HourFrmt $hrfrmt
            #if([DateTime]$b.CreationDate -gt [DateTime]$cmDat){
            if($dateCreated -gt $cmDat){
                #if($dateCreated -ge $sysDat){
                    $activity = $b.AuditData | ConvertFrom-Json | select *          
                    if($activity -ne "" -and $activity -ne $null){
                        $key=$activity.Operation+"~"+$activity.UserId+"~"+$activity.ClientIP+"~"+$activity.CreationTime
                        if(!$uniqUserId.ContainsKey($key)){
                            $uniqUserId.Add($key,1)
                            if($key.StartsWith("UserLoggedIn")){
                                $usrLogedIn+=1
                            }
                            if($key.StartsWith("UserLoginFailed")){
                                $usrLoginFailed+=1
                                Write-Host '#ddLoginFailed '$dateCreated '~!~'$activity.ClientIP'~!~'$activity.UserId'~!~'$activity.Workload'~!~'$activity.LogonError
                            }
                        }  
                    }
                #}
            }  
        }  
    }
    Write-Host 'UserLoginFailed~'$usrLoginFailed
    Write-Host 'UserLoggedIn~'$usrLogedIn
    Write-Host 'Last Read Date~'$lastReadDat
}
catch{    
    $exceptionmsg=($_.Exception.Message)+($_.ScriptStackTrace) 
	Write-error "Error Occured in User Logins Test --  $exceptionmsg "
}
[System.GC]::GetTotalMemory($true) | out-null
