<#
    /*****************************************************************************
    Author            :       Mounika Kuna
    Purpose           :       Provides O365 Users Details
    Created           :       17/09/2020    
    /*****************************************************************************
#>

$OutputEncoding = [console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
$PSDefaultParameterValues = @{'*:Encoding' = 'utf8'}

clear
[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 -WarningAction SilentlyContinue

#<#
$TestInputs=$args
$username=$TestInputs[0]
$password=Eg-O365Dcr -EncStr $TestInputs[1]
$proxyUser=$TestInputs[2]
$proxyPass=Eg-O365Dcr -EncStr $TestInputs[3]
$proxyserver=$TestInputs[4]
$rptNam=$TestInputs[5]
$graphDetails=$TestInputs[6]
if($graphDetails -and $graphDetails -ne 'none'){
    $graphDetailsArr=($graphDetails).ToString() -Split ("~!~")
    $appId=$graphDetailsArr[0]
    $appSecret=$graphDetailsArr[1]
    $authString=$graphDetailsArr[2]
    $resource=$graphDetailsArr[3]
}
#>

$langPath=$egurkhaPath+'\agent\config\O365_lang.ini'
$encTyp=Eg-GetINIContent -Path $langPath -Subject 'File_Type' -Key 'encoding'

if($proxyUser.toString().toLower().Trim() -eq 'none') { $proxyUser=$proxyUser.toString().toLower().Trim() }
if($proxyPass.toString().toLower().Trim() -eq 'none') { $proxyPass=$proxyPass.toString().toLower().Trim() }
if($proxyserver.toString().toLower().Trim().Contains('none')) { $proxyserver=$proxyserver.toString().toLower().Trim() }
if(!$proxyserver.ToString().ToLower().Contains('none')){
    [system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy($proxyserver)
    if($proxyUser.ToString().ToLower() -ne 'none' -and $proxyPass.ToString().ToLower() -ne 'none'){
        $proxyCred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $proxyUser, $(convertto-securestring $proxyPass -asplaintext -force)
        [system.net.webrequest]::defaultwebproxy.credentials =$proxyCred
        [system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $true
    }
}

$rptPath=$egurkhaPath+'\agent\O365\'+$rptNam
if(!(Test-Path -Path $rptPath )){
   $null =  New-Item -ItemType directory -Path $rptPath -WarningAction SilentlyContinue
}

Function Eg-InvokeUrl(){
	[CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true, Position=1)]
        [String]$Url
    )

    Process
    {
        $typePath=(([XML]((Get-Package -Name AzureAD  | select SwidTagText)).SwidTagText).SoftwareIdentity.Meta.InstalledLocation)+'\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'
        Add-Type -Path $typePath
        $creds = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential" -ArgumentList $appId, $appSecret
        $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext"-ArgumentList $authString
        $context = $authContext.AcquireTokenAsync($resource, $creds).Result
        $authCode=$context.CreateAuthorizationHeader()

        $header = @{
            'Authorization'=$authCode
        }
        $queryRes = Invoke-RestMethod -Method 'Get' -Headers $header -Uri $Url   
        return $queryRes
    }
}

$timenow = [int][double]::Parse((Get-Date -UFormat %s))
$O365LicenseDetailsCSV=$rptPath+'\O365LicenseDetails'+$timenow+'.csv'
Eg-RemoveGraphcsvFiles -rmvPath $O365LicenseDetailsCSV

$url='https://graph.microsoft.com/v1.0/subscribedSkus?$select=SKUPartNumber,skuId'
while($true){
    $O365LicenseDetails=Eg-InvokeUrl -Url $url   
    $O365LicenseDetails.value | Export-Csv  $O365LicenseDetailsCSV -Encoding $encTyp -Force -NoTypeInformation -Append
    $url=$O365LicenseDetails.'@odata.nextLink'
    if($url -eq $null -or $url -eq ''){
        break
    }
}
$O365LicenseDetails=Import-csv $O365LicenseDetailsCSV -Encoding $encTyp

$licenseTable = @{}
foreach ($licenseDetail in $O365LicenseDetails) { $licenseTable.Add([string]$licenseDetail.SkuId, [string]$licenseDetail.SKUPartNumber) }

$timenow = [int][double]::Parse((Get-Date -UFormat %s))
$O365UsersDetailsCSV=$rptPath+'\O365UsersDetails'+$timenow+'.csv'
Eg-RemoveGraphcsvFiles -rmvPath $O365UsersDetailsCSV

$url='https://graph.microsoft.com/v1.0/users/?$select=userPrincipalName,displayName,jobTitle,businessPhones,mobilePhone,mail,officeLocation,preferredLanguage,givenName,surname,id,department,assignedLicenses,country'
$count=0
while($true){
    $O365UsersDetails=Eg-InvokeUrl -Url $url   
    foreach($output in $O365UsersDetails.value){
    foreach($bp in $output.businessPhones){$businessPhones=$bp}

    $assignedLicenses = '';
    $hasLicense='No' 
    foreach ($license in $output.AssignedLicenses) {
        $hasLicense='Yes'
        if($licenseTable.ContainsKey($license.SkuId) -eq $True) {
            $assignedLicenses = $assignedLicenses+'+'+$licenseTable.Item($license.SkuId) }
        else{
            $assignedLicenses = $assignedLicenses+'+'+$License 
        }
    }

    if($assignedLicenses -and $assignedLicenses.Trim().Length -gt 1000){
        $assignedLicenses=$assignedLicenses.Substring(1, 999) 
    }elseif($assignedLicenses -and $assignedLicenses.Trim().Length -gt 0){
        $assignedLicenses=$assignedLicenses.Substring(1) 
    }

    [array]$newObject = [PSCustomObject][ordered]@{
            userPrincipalName=$output.userPrincipalName
            displayName=$output.displayName
            jobTitle=$output.jobTitle
            businessPhones=$businessPhones
            mobilePhone=$output.mobilePhone
            mail=$output.mail
            officeLocation=$output.officeLocation
            preferredLanguage=$output.preferredLanguage
            givenName=$output.givenName
            surname=$output.surname
            id=$output.id
            department=$output.department
            hasLicense=$hasLicense
            assignedLicenses=$assignedLicenses
            country=$output.country
        }
        $newObject | Export-Csv  $O365UsersDetailsCSV -Encoding $encTyp -Force -NoTypeInformation -Append
   
    }
    $url=$O365UsersDetails.'@odata.nextLink'
    if($url -eq $null -or $url -eq ''){
        break
    }
}

$UserDetails=Import-csv $O365UsersDetailsCSV -Encoding $encTyp

foreach($User in $UserDetails){
    if($User.userPrincipalName -notmatch '#EXT'){
			$count++
			$UserDD='UserDD##'+$User.userPrincipalName+'~!~'+$User.displayName+'~!~'+$User.jobTitle+'~!~'+$User.businessPhones+'~!~'+$User.mobilePhone+'~!~'+$User.mail+'~!~'+$User.officeLocation+'~!~'+$User.preferredLanguage+'~!~'+$User.givenName+'~!~'+$User.surname+'~!~'+$User.id+'~!~'+$User.department+'~!~'+$User.hasLicense+'~!~'+$User.assignedLicenses+'~!~'+$User.country
		    Write-Host $UserDD
    }
}
Write-Host 'Measure##'$count
if([System.IO.File]::Exists($O365LicenseDetailsCSV) -eq 'True'){
    Remove-Item $O365LicenseDetailsCSV
}
if([System.IO.File]::Exists($O365UsersDetailsCSV) -eq 'True'){
    Remove-Item $O365UsersDetailsCSV
}
[System.GC]::GetTotalMemory($true) | out-null