[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
<# 
This script can be called in two ways - one is by passing arguments from SaaS manager, another is thorugh manually. if u dont pass any arguments to script, it will open a input window. 
#>
clear
#$args=@('monitoring@365rpt.onmicrosoft.com','abc123ABC','none','none','none','none','BoxManual_30','eGservicmon256','eGservicmon@2019')
$TestInputs=$args
if($TestInputs.Count -ne 0){
    $AdminuserName=$TestInputs[0]
    $password=$TestInputs[1]
    $proxyHost=$TestInputs[2]
    $proxyPort=$TestInputs[3]
    $proxyUsr=$TestInputs[4]
    $proxyPass=$TestInputs[5]
    $nickNam=$TestInputs[6]
    $monitorUser=$TestInputs[7]
    $monitorPassword=$TestInputs[8]

    if($monitorUser -eq 'none'){
        $monitorUser='eGservicmon'
        $monitorPassword='eGservicmon@2019'
    }  
}else{
    $nickNam='none'
}
$grp="eGMonitoring-role"
$runningManually=$true
$egInstallpath=Get-ChildItem Env:EGURKHA_INSTALL_DIR |Select Value
$egurkhaPath=$egInstallpath.Value.ToString()
$chkDir=$egurkhaPath+'\agent'
if((Test-Path -Path $chkDir)){
    $runningManually=$False
}

function validateBoxesAndCombos(){
     $checkPassword=$mntrPassTxtBx.Text
     if(!($checkPassword.length -gt 8) -and !($checkPassword –cmatch '[^a-zA-Z0-9]') -and !($checkPassword -cmatch " "))
     {
       $result = [System.Windows.Forms.MessageBox]::Show('Please provide strong password', 'Alert', 'OK', 'Warning')
     }
}

$isRunGraphOnly=$false
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
if($TestInputs.Count -eq 0){
     ######***GUI  form ****#######
    $form = New-Object System.Windows.Forms.Form
    $flowlayoutpanel = New-Object System.Windows.Forms.FlowLayoutPanel
    $buttonOK = New-Object System.Windows.Forms.Button

    $O365DtlsLbl=New-Object System.Windows.Forms.Label
    $O365UsrLbl=New-Object System.Windows.Forms.Label
    $O365PassLbl=New-Object System.Windows.Forms.Label
    $O365UsrTxtBx=New-Object System.Windows.Forms.TextBox
    $O365PassTxtBx=New-Object System.Windows.Forms.TextBox 
    
    $prxyDtlsLbl=New-Object System.Windows.Forms.Label
    $prxyHostLbl=New-Object System.Windows.Forms.Label
    $prxyPortLbl=New-Object System.Windows.Forms.Label
    $prxyUsrLbl=New-Object System.Windows.Forms.Label
    $prxyPassLbl=New-Object System.Windows.Forms.Label
    $prxyHostTxtBx=New-Object System.Windows.Forms.TextBox
    $prxyPortTxtBx=New-Object System.Windows.Forms.TextBox
    $prxyUsrTxtBx=New-Object System.Windows.Forms.TextBox
    $prxyPassTxtBx=New-Object System.Windows.Forms.TextBox
    
    $grphAPIChkbx= New-object System.Windows.Forms.CheckBox
      
    $monitorlabel=New-Object System.Windows.Forms.Label
    $RadioButton1 = New-Object System.Windows.Forms.RadioButton
    $RadioButton2 = New-Object System.Windows.Forms.RadioButton
    $mntrUsrLbl=New-Object System.Windows.Forms.Label
    $mntrUsrTxtBx=New-Object System.Windows.Forms.TextBox    
    $mntrPassLbl=New-Object System.Windows.Forms.Label
    $mntrPassTxtBx=New-Object System.Windows.Forms.TextBox
    $mntrRoleLbl=New-Object System.Windows.Forms.Label
    $mntrRoleTxtBx=New-Object System.Windows.Forms.TextBox

    $infoLabel=New-Object System.Windows.Forms.Label
    $infoLabel1=New-Object System.Windows.Forms.Label
    $infoLabel2=New-Object System.Windows.Forms.Label
  
    $formsize = 455
    $form.Controls.Add($O365DtlsLbl)
    $form.Controls.Add($O365UsrLbl)
    $form.Controls.Add($O365UsrTxtBx)
    $form.Controls.Add($O365PassLbl)
    $form.Controls.Add($O365PassTxtBx)

    $form.Controls.Add($prxyDtlsLbl)
    $form.Controls.Add($prxyHostLbl)
    $form.Controls.Add($prxyHostTxtBx)
    $form.Controls.Add($prxyPortLbl)
    $form.Controls.Add($prxyPortTxtBx)
    $form.Controls.Add($prxyUsrLbl)
    $form.Controls.Add($prxyUsrTxtBx)
    $form.Controls.Add($prxyPassLbl)
    $form.Controls.Add($prxyPassTxtBx)

    $form.Controls.Add($grphAPIChkbx)

    $form.Controls.Add($RadioButton1)
    $form.Controls.Add($RadioButton2)

    $form.Controls.Add($monitorlabel)
    $form.Controls.Add($mntrUsrLbl)
    $form.Controls.Add($mntrUsrTxtBx)
    $form.Controls.Add($mntrPassLbl)
    $form.Controls.Add($mntrPassTxtBx)
    $form.Controls.Add($mntrRoleLbl)
    $form.Controls.Add($mntrRoleTxtBx)

    $form.Controls.Add($infoLabel)
    $form.Controls.Add($infoLabel1)

    $form.Controls.Add($buttonOK)

    $form.AcceptButton = $buttonOK
    $form.AutoScaleDimensions = '8, 17'
    $form.AutoScaleMode = 'Font'
    $form.ClientSize = "428 , $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 Set Roles and Permissions'
    $form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D

    $O365DtlsLbl.Location="38,15"
    $O365DtlsLbl.Anchor="Bottom, Left"
    $O365DtlsLbl.Text="&Global Admin Credentails:"
    $O365DtlsLbl.Size="200,20"
    $O365UsrLbl.Location="58,38"
    $O365UsrLbl.Anchor="Bottom, Left"
    $O365UsrLbl.Text="&Username"
    $O365UsrLbl.Size="115,20"
    $O365UsrTxtBx.Location="175,38"
    $O365UsrTxtBx.Name="O365User"
    $O365UsrTxtBx.Size="200,20"
    $O365UsrTxtBx.Text=""
    $O365PassLbl.Location="58,67"
    $O365PassLbl.Anchor="Bottom, Left"
    $O365PassLbl.Text="&Password"
    $O365PassLbl.Size="115,20"
    $O365PassTxtBx.Location="175,67"
    $O365PassTxtBx.Name="O365Pass"
    $O365PassTxtBx.Size="200,20"
    $O365PassTxtBx.Text=""
    $O365PassTxtBx.PasswordChar='*'

    $prxyDtlsLbl.Location="38,95"
    $prxyDtlsLbl.Anchor="Bottom, Left"
    $prxyDtlsLbl.Text="&Proxy Details :"
    $prxyDtlsLbl.Size="100,20"
    $prxyHostLbl.Location="58,118"
    $prxyHostLbl.Anchor="Bottom, Left"
    $prxyHostLbl.Text="&Host IP"
    $prxyHostLbl.Size="115,20"
    $prxyHostTxtBx.Location="175,118"
    $prxyHostTxtBx.Name="ProxyHost"
    $prxyHostTxtBx.Size="120,20"
    $prxyHostTxtBx.Text="none"
    $prxyPortLbl.Location="298,119"
    $prxyPortLbl.Anchor="Bottom, Left"
    $prxyPortLbl.Text="&Port"
    $prxyPortLbl.Size="25,20"
    $prxyPortTxtBx.Location="325,118"
    $prxyPortTxtBx.Name="Port"
    $prxyPortTxtBx.Size="50,20"
    $prxyPortTxtBx.Text="none"
    $prxyUsrLbl.Location="58,145"
    $prxyUsrLbl.Anchor="Bottom, Left"
    $prxyUsrLbl.Text="&Username"
    $prxyUsrLbl.Size="115,20"
    $prxyUsrTxtBx.Location="175,145"
    $prxyUsrTxtBx.Name="ProxyUser"
    $prxyUsrTxtBx.Size="200,20"
    $prxyUsrTxtBx.Text="none"
    $prxyPassLbl.Location="58,173"
    $prxyPassLbl.Anchor="Bottom, Left"
    $prxyPassLbl.Text="&Password"
    $prxyPassLbl.Size="115,20"
    $prxyPassTxtBx.Location="175,173"
    $prxyPassTxtBx.Name="ProxyPass"
    $prxyPassTxtBx.Size="200,20"
    $prxyPassTxtBx.Text="none"
    $prxyPassTxtBx.PasswordChar='*'

    $grphAPIChkbx.Location="38,205"
    $grphAPIChkbx.Text="Create ONLY MS Graph App"
    $grphAPIChkbx.Size="200,20"
    $grphAPIChkbx.Add_CheckStateChanged({  
        if($grphAPIChkbx.Checked -eq $False){
            $monitorlabel.Enabled = $true
            $RadioButton1.Enabled = $true
            $RadioButton2.Enabled = $true
            $mntrUsrLbl.Enabled = $true       
            $mntrUsrTxtBx.Enabled = $true
            $mntrPassLbl.Enabled = $true
            $mntrPassTxtBx.Enabled = $true
            $mntrRoleLbl.Enabled = $true
            $mntrRoleTxtBx.Enabled = $true
            $infoLabel.Enabled = $true
            $infoLabel1.Enabled = $true

        }else{
            $monitorlabel.Enabled = $False
            $RadioButton1.Enabled = $False
            $RadioButton2.Enabled = $False
            $mntrUsrLbl.Enabled = $False       
            $mntrUsrTxtBx.Enabled = $False
            $mntrPassLbl.Enabled = $False
            $mntrPassTxtBx.Enabled = $False
            $mntrRoleLbl.Enabled = $False
            $mntrRoleTxtBx.Enabled = $False
            $infoLabel.Enabled = $False
            $infoLabel1.Enabled = $False
        }
    })

    $monitorlabel.Location="38,235"  
    $monitorlabel.Anchor="Bottom, Left"
    $monitorlabel.Text="&eG Monitor User Credentails:"
    $monitorlabel.Size="200,20"

    $RadioButton1.Location ="58,255"
    $RadioButton1.Size ="115,20"
    $RadioButton1.Checked = $true
    $RadioButton1.text = "New User"
    $RadioButton2.Location ="175,255"
    $RadioButton2.Size ="115,20"
    $RadioButton2.Checked = $false
    $RadioButton2.text = "Existing User"

    $RadioButton1.Add_Click({
        $mntrPassLbl.Enabled=$true
        $mntrPassTxtBx.Enabled=$true
        $mntrUsrTxtBx.Text="eGmonitor"
        $infoLabel.Location="58,358"
        $infoLabel.Anchor="Bottom, Left"
        $infoLabel.Text="&*"
        $infoLabel.Font=New-Object System.Drawing.Font("Lucida Console",13,[System.Drawing.FontStyle]::Regular)
        $infoLabel.Size="17,10"
        $infoLabel.ForeColor='Red'
        $infoLabel1.Location="72,358"
        $infoLabel1.Anchor="Bottom, Left"
        $infoLabel1.Text="&New user and MSGraph App will be created with the required roles/permissions"#
        $infoLabel1.Size="375,25"
        $infoLabel1.ForeColor='blue'
    })
    $RadioButton2.Add_Click({
        $mntrPassLbl.Enabled=$false
        $mntrPassTxtBx.Enabled=$false
        $mntrUsrTxtBx.Text=""
        $infoLabel.Location="58,358"
        $infoLabel.Anchor="Bottom, Left"
        $infoLabel.Text="&*"
        $infoLabel.Font=New-Object System.Drawing.Font("Lucida Console",13,[System.Drawing.FontStyle]::Regular)
        $infoLabel.Size="17,10"
        $infoLabel.ForeColor='Red'
        $infoLabel1.Location="72,358"
        $infoLabel1.Anchor="Bottom, Left"
        $infoLabel1.Text="&Existing user and MSGraph App will be provided the required roles/permissions"
        $infoLabel1.Size="375,25"
        $infoLabel1.ForeColor='blue'
    })

    $mntrUsrLbl.Location="58,279"  
    $mntrUsrLbl.Anchor="Bottom, Left"
    $mntrUsrLbl.Text="&Monitoring User:"
    $mntrUsrLbl.Size="115,20"
    $mntrUsrTxtBx.Location="175,279"  
    $mntrUsrTxtBx.Name="monitorUser"
    $mntrUsrTxtBx.Size="200,20"
    $mntrUsrTxtBx.Text="eGmonitor"
    $mntrPassLbl.Location="58,307" 
    $mntrPassLbl.Anchor="Bottom, Left"
    $mntrPassLbl.Text="&Monitoring Password:"
    $mntrPassLbl.Size="115,20"
    $mntrPassTxtBx.Location="175,307"
    $mntrPassTxtBx.Name="monitorPassword"
    $mntrPassTxtBx.Size="200,20"
    $mntrPassTxtBx.Text=""
    $mntrPassTxtBx.PasswordChar='*'
    $mntrPassTxtBx.MaxLength = 16
    $mntrPassTxtBx.Add_Leave({validateBoxesAndCombos})
    $mntrRoleLbl.Location="58,335" 
    $mntrRoleLbl.Anchor="Bottom, Left"
    $mntrRoleLbl.Text="&Monitoring Rolename:"
    $mntrRoleLbl.Size="115,20"
    $mntrRoleTxtBx.Location="175,335"   
    $mntrRoleTxtBx.Name="monitorUser"
    $mntrRoleTxtBx.Size="200,20"
    $mntrRoleTxtBx.Text="eGMonitoring-role"

    $infoLabel.Location="58,362"
    $infoLabel.Anchor="Bottom, Left"
    $infoLabel.Text="&*"
    $infoLabel.Font=New-Object System.Drawing.Font("Lucida Console",13,[System.Drawing.FontStyle]::Regular)
    $infoLabel.Size="17,10"
    $infoLabel.ForeColor='Red'
    $infoLabel1.Location="72,362"
    $infoLabel1.Anchor="Bottom, Left"
    $infoLabel1.Text="&New user and MSGraph App will be created with the required roles/permissions"
    $infoLabel1.Size="375,25"
    $infoLabel1.ForeColor='blue'
    
    $buttonOK.Anchor = 'Bottom, Right'
    $buttonOK.DialogResult = 'OK'
    $buttonOK.Location = "175, 403"
    $buttonOK.Margin = '4, 4, 4, 4'
    $buttonOK.Name = 'buttonOK'
    $buttonOK.Size = '100, 30'
    $buttonOK.TabIndex = 0
    $buttonOK.Text = '&OK'
    $frmDialog=$form.ShowDialog()

    if($frmDialog -eq 'OK' ){
        $proxyHost=$prxyHostTxtBx.Text
        $proxyPort=$prxyPortTxtBx.Text
        $proxyUsr=$prxyUsrTxtBx.Text
        $proxyPass=$prxyPassTxtBx.Text
        $AdminuserName=$O365UsrTxtBx.Text
        $password=$O365PassTxtBx.Text
        $monitorUser=$mntrUsrTxtBx.Text
        $monitorPassword=$mntrPassTxtBx.Text
        $grp=$mntrRoleTxtBx.Text

        if($grphAPIChkbx.Checked -eq $true){
            $isRunGraphOnly=$true
        }
        if($proxyHost -eq "" -or $proxyport -eq "" -or $proxyUsr -eq "" -or $AdminuserName -eq "" -or $password -eq "" )
        {
            Write-Host "Re-run the script with all the inputs...." -ForegroundColor Red 
            #O365-WriteLog -writString  "Re-run the script with all the inputs...." -LogPath $logFile -ReportingName 'ERROR'
            Exit
        }
    }
    else{
        Write-Host 'Exiting...'
        #O365-WriteLog -writString "Exiting..." -LogPath $logFile -ReportingName 'ClOSE'
        exit
    }
}


Function GetRequiredPermissions($requiredDelegatedPermissions, $requiredApplicationPermissions, $reqsp) {
    $sp = $reqsp
    $appid = $sp.AppId
    $requiredAccess = New-Object Microsoft.Open.AzureAD.Model.RequiredResourceAccess
    $requiredAccess.ResourceAppId = $appid
    $requiredAccess.ResourceAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]
    if ($requiredDelegatedPermissions) {
        AddResourcePermission $requiredAccess -exposedPermissions $sp.Oauth2Permissions -requiredAccesses $requiredDelegatedPermissions -permissionType "Scope"
    } 
    if ($requiredApplicationPermissions) {
        AddResourcePermission $requiredAccess -exposedPermissions $sp.AppRoles -requiredAccesses $requiredApplicationPermissions -permissionType "Role"
    }
    return $requiredAccess
}
$mn=O365-Enc -str $monitorUser
function O365-Enc(){
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true, Position=1)]
        [String]$str
    )
    Process
    {
        $j=124;
        $eStr=[System.Text.Encoding]::UTF8
        $byt=$eStr.GetBytes($str)
        $bytArr=@()
        for($i=0;$i -lt $byt.count ;$i++){  
            $k=$j-$byt[$i]+$i*3
            $bt=[System.BitConverter]::GetBytes($k)
            $bytArr+=$bt[0]
        }
        $encStr=''
        for($i=$bytArr.count;$i -ge 0 ;$i--){
            $encStr+=$bytArr[$i]
            if($bytArr[$i] -ne 0){
                $encStr+=':'
            }
        }
        $encStr=$encStr.Substring(1,$encStr.Length-2)
        return $encStr
    }
}

Function AddResourcePermission($requiredAccess, $exposedPermissions, $requiredAccesses, $permissionType) {
    foreach ($permission in $requiredAccesses) {
        $reqPermission = $null
        $reqPermission = $exposedPermissions | Where-Object {$_.Value -contains $permission.Value}
        #Write-Host "Collected information for $($reqPermission.Value) of type $permissionType" -ForegroundColor Green
        $resourceAccess = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
        $resourceAccess.Type = $permissionType
        $resourceAccess.Id = $reqPermission.Id    
        $requiredAccess.ResourceAccess.Add($resourceAccess)
    }
}

clear

#INPUT - for user-roles and  role-group and role-group roles 
$assgingUserRoles="Global Reader","Service Support Administrator","SharePoint Service Administrator"
$roleslist="View-Only Audit Logs","Mailbox Import Export","Mail Recipients","View-Only Recipients"   #,"View-Only Recipients"

#INPUT - for graph api
$applicationName='eGMsGraphRpt'
$KeyDesc='SecreteG'
$identyUri='https://eGMsGraphRpt.com'
$srchStrArr=@("Graph#Microsoft Graph","WinAzure#Windows Azure Active Directory","SPO#Office 365 SharePoint Online","O365MAPI#Office 365 Management APIs")
$reqPermissionArr=@("GraphRead all usage reportsApp","GraphRead all users' full profilesApp","GraphRead all groupsApp","GraphSign in and read user profileDel","WinAzureSign in and read user profileDel","SPORead items in all site collectionsApp","SPORead and write user filesDel","SPORead user filesDel","O365MAPIRead service health information for your organizationApp")


$m=O365-Enc -str $AdminuserName
if($runningManually){
    # Write Output in file
    $driveRoot=''
    $drives=Get-PSDrive
    foreach($drive in $drives){
        if(($drive.Name).ToLower() -eq 'c'){
            $driveRoot=$drive.Root
            break;
        }elseif(($drive.Name).ToLower() -eq 'd'){
            $driveRoot=$drive.Root
            break;
        }elseif(($drive.Name).ToLower() -eq 'e'){
            $driveRoot=$drive.Root
            break;
        }
    }
    $fileDir=$driveRoot+'egurkha'
    if(!(Test-Path -Path $fileDir)){
        $null=New-Item -ItemType directory -Path $fileDir
    }
    $filePath=$fileDir+'\O365Dtls.txt'
    #if(!(Test-Path -Path $filePath -PathType Leaf)){
    #    $null=New-Item -ItemType File -Path $filePath 
    #}
    #Write-Host 'OutFile writing path -- '$filePath

    #LOGFILE
    $logFile=$fileDir+'\O365.log'
}
else{
    $egEncryPath=$egurkhaPath+"\lib\EGFileEncryption.psm1"
    Import-Module $egEncryPath

    $writDir=$egurkhaPath+'\agent\O365\MsGraph'
    
    if(!(Test-Path -Path $writDir)){
        $null=New-Item -ItemType directory -Path $writDir
    }
    $logFile=$writDir+'\O365.log'
}

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 
    }
}

O365-WriteLog -writString  "**************************************************" -LogPath $logFile -ReportingName 'INFO'
#O365-WriteLog -writString  "OutFile writing path is $filePath" -LogPath $logFile -ReportingName 'INFO'



$cn=@('AzureChinaCloud','https://partner.outlook.cn/PowerShell')
$com=@('AzureCloud','https://outlook.office365.com/powershell-liveid/')
$de=@('AzureGermanyCloud','https://outlook.office.de/powershell-liveid/')
$us=@('USGovernment','None')
$s=O365-Enc -str $password
$azureCloud=$AdminuserName.Substring($AdminuserName.LastIndexOf('.')+1) 
$azureCloudArr=@()
if($monitorPassword -ne $null -and $monitorPassword -ne ''){
    $pn=O365-Enc -str $monitorPassword
}
if($azureCloud -eq 'com'){$azureCloudArr=$com}
elseif($azureCloud -eq 'cn'){$azureCloudArr=$cn}
elseif($azureCloud -eq 'de'){$azureCloudArr=$de}
elseif($azureCloud -eq 'us'){$azureCloudArr=$us}  
else{$azureCloudArr=$com}

$proxyserverip=$proxyHost+':'+$proxyPort
$y=$m+':991:'+$s
if(!$proxyserverip.ToString().ToLower().Contains('none')){
    $proxyserver='http://'+$proxyserverip
    [system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy($proxyserver)
    if($proxyUsr.ToString().ToLower() -ne 'none' -and $proxyPass.ToString().ToLower() -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.CredentialCache]::DefaultNetworkCredentials
        [system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $true
    }
}

# 1.Installation - AzureAD,MSOnline
$insMod=@()
$installedModule=Get-InstalledModule | Where-Object{$_.Name -in @('AzureAD','MSOnline')} | Sort-Object -Property Name
if($installedModule.Count -ne 0){
    if($installedModule.Count -eq 1 ){
        if($installedModule[0].Name -eq 'AzureAD'){
            write-host 'Azure AD module is already installed'
            O365-WriteLog -writString "Azure AD module is already installed" -LogPath $logFile -ReportingName 'INFO'
            $insMod+='MSOnline'
        }else{
            write-host 'MSOnline module is already installed'
            O365-WriteLog -writString "MSOnline module is already installed" -LogPath $logFile -ReportingName 'INFO'
            $insMod+='AzureAD'
        }
    }else{
        write-host 'AzureAD and MSOnline modules are already installed'
        O365-WriteLog -writString "AzureAD and MSOnline modules are already installed" -LogPath $logFile -ReportingName 'INFO'
    }
}else{
    $insMod+='MSOnline'
    $insMod+='AzureAD'
}
$i=$b+'~'+$y
if($insMod.Count -ne 0){
    Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
    foreach($ins in $insMod){
        if($proxyHost -ne 'none'){
            if($proxyUsr -ne 'none'){
                Install-Module $ins -Scope AllUsers -AllowClobber -Force -Proxy $proxyserver -ProxyCredential $proxyCred
            }else{
                Install-Module $ins -Scope AllUsers -AllowClobber -Force -Proxy $proxyserver
            }
        }else{
            Install-Module $ins -Scope AllUsers -AllowClobber -Force
        }
    }
}

$isGAdmin=$false
$c=$i+$a
$domain=''
$credential = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $AdminuserName, $(convertto-securestring $password -asplaintext -force)
try{
    Import-Module MsOnline
    Connect-MsolService -Credential $credential -AzureEnvironment $azureCloudArr[0] 
    
    $chkGAdmin=Get-MsolRoleMember -RoleObjectId $(Get-MsolRole -RoleName "Company Administrator").ObjectId -ErrorAction SilentlyContinue |Select-Object -Property EmailAddress
    write-host $chkGAdmin[0]
    
    if($runningManually){
        O365-WriteLog -writString "Checking the permissions of the user provided. $c" -LogPath $logFile -ReportingName 'Info'
    }else{
        $timenow = [int][double]::Parse((Get-Date -UFormat %s)) 
        if($nickNam-ne $null -and $nickNam -ne 'none' -and $nickNam -ne ''){
            $adminWritDir=$egurkhaPath+'\agent\O365\'+$nickNam
            if(!(Test-Path -Path $adminWritDir)){
                $null=New-Item -ItemType directory -Path $adminWritDir
            }
        }else{
            $adminWritDir=$egurkhaPath+'\agent\O365\MsGraph'
        }
        $adminKeyFileNam='\KeGServic'+$timenow+'.dat'
        $adminWritPath=$adminWritDir+'\eGServic'+$timenow+'.txt'
        $null=$c | Add-Content $adminWritPath
        $ADkey=Get-CryptoKey -FileDir $adminWritDir -FileName $adminKeyFileNam
        $null=Protect-File $adminWritPath -Algorithm AES -KeyAsPlainText $ADkey -RemoveSource      
    }
    foreach($GA in $chkGAdmin){
        if($GA.EmailAddress -eq $AdminuserName){
            $isGAdmin=$true
            $measure=Get-MsolDomain |select Name,IsInitial
            if($measure){
                $azureEnv= $measure|where{$_.IsInitial -eq $true}|select Name
                $domain=$azureEnv.Name
                if($monitorUser.Contains('@')){
                    $userdomain=$monitorUser.Split('@')[1].trim()
                    if(!$domain.Contains($userdomain))
                    {
                        Write-Error "Given user $monitorUser domain does not exist in the tenant domain"
                        O365-WriteLog -writString "Given user $monitorUser domain does not exist in the tenant domain" -LogPath $logFile -ReportingName 'ERROR'
                        exit
                    }
                 }
                 else{
                    $monitorUser=$monitorUser+'@'+$domain
                 }
                $domainNam=$domain.Substring(0,$domain.IndexOf('.')).trim()
            }
            else{
                Write-Error "Intial domain is not found "
                O365-WriteLog -writString "Intial domain is not found " -LogPath $logFile -ReportingName 'ERROR'
                O365-WriteLog -writString "Re-run the script and give admin user along with domain name (Ex:- abc@eg.com)" -LogPath $logFile -ReportingName 'INFO'
                exit  
            }
            break;
        }
    }
}Catch{
    $message= $_.Exception.Message + $_.ScriptStackTrace 
    Write-Host $message
    O365-WriteLog -writString "Error while checking provided user having global admin role  $message " -LogPath $logFile -ReportingName 'Exception'
    $isGAdmin=$false
}

$replyUrl='https://'+$domainNam+'-my.sharepoint.com/'
if($isGAdmin){
    if($isRunGraphOnly -eq $False){  
        #for session
        try{
            Write-host "Creating new session..."
            O365-WriteLog -writString "Creating new session..." -LogPath $logFile -ReportingName 'INFO'
            $sessionOption = New-PSSessionOption -SkipRevocationCheck
            if($proxyUsr.ToString().ToLower() -ne 'none' -and $proxyPass.ToString().ToLower() -ne 'none'){
                $sessionOption = New-PSSessionOption -SkipRevocationCheck -ProxyAccessType WinHttpConfig -ProxyAuthentication basic -ProxyCredential $proxyCred
            }
            $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $azureCloudArr[1] -Credential $credential -Authentication Basic -AllowRedirection -SessionOption $sessionOption # -WarningAction SilentlyContinue
            $null = Import-PSSession $session -AllowClobber -WarningAction SilentlyContinue -DisableNameChecking
        }catch{
            $message= $_.Exception.Message + $_.ScriptStackTrace 
            Write-Error "Error while creating session -> $message "
            O365-WriteLog -writString "Error while creating session is -> $message " -LogPath $logFile -ReportingName 'EXCEPTION'
            O365-WriteLog -writString "Exiting the script execution please check prerequsities and admin user credentials" -LogPath $logFile -ReportingName 'INFO'
            exit
        }

        Try{
            Enable-OrganizationCustomization
        }Catch{}

        #2.USER CREATION, SETTING ROLES AND PERMISSIONS
        #creating user
        $user=$monitorUser
        $userlicence=$false
        $displayname=$user.Split('@')[0]
        $userprincipleName=$user
        $userprincipleName=$userprincipleName.ToString().trim()
        $UsageLocation=(Get-MsolUser -UserPrincipalName $AdminuserName | select UsageLocation).UsageLocation
        $userdetais=Get-MsolUser -UserPrincipalName $userprincipleName -ErrorAction SilentlyContinue | select * 
        if(!$userdetais){
            if($monitorPassword){
                Write-host "User $userprincipleName do not exist, so creating the user ..."
                O365-WriteLog -writString  "User $userprincipleName do not exist, so creating the user ..." -LogPath $logFile -ReportingName 'INFO'
                $userdetais=New-MsolUser -UserPrincipalName $userprincipleName -Password $monitorPassword -DisplayName $displayname -FirstName $displayname -UsageLocation $UsageLocation -ForceChangePassword $false
                Write-host "user $userprincipleName  is created without licence " -ForegroundColor Green
                O365-WriteLog -writString  "User $userprincipleName  created without licence " -LogPath $logFile -ReportingName 'INFO'
            }else{
                Write-error  "User $userprincipleName do not exist, re-run the script with right existing user ..."
                O365-WriteLog -writString  "User $userprincipleName do not exist, re-run the script with existing user ..." -LogPath $logFile -ReportingName 'WARN'

            }       
        }
        else{
            $displayname=$userdetais.DisplayName
            O365-WriteLog -writString  "User $userprincipleName  is already existing" -LogPath $logFile -ReportingName 'INFO'
            Write-host "User $userprincipleName is already existing" -ForegroundColor Green
        }
        if(!$userdetais){
            Write-Host "Unable to create user $userprincipleName $Error" -ForegroundColor Red 
            O365-WriteLog -writString  "Unable to create user $userprincipleName $Error" -LogPath $logFile -ReportingName 'ERROR'
            exit
        }

        #Assigning user roles
        try{
            Write-host "Assigning user roles to $userprincipleName... " -ForegroundColor Magenta        
            $existeduserroles=(Get-MsolUserRole -UserPrincipalName $userprincipleName | select Name).Name
            foreach($Usrrole in $assgingUserRoles){
                $Usrrole=$Usrrole.ToString().trim()
                if($existeduserroles){
                    if(!$existeduserroles.contains($Usrrole)){
                        Add-MsolRoleMember -RoleName $Usrrole -RoleMemberEmailAddress $userprincipleName
                        Write-host " Assigned $Usrrole role to $userprincipleName..." -ForegroundColor Green
                        O365-WriteLog -writString  "Assigned $Usrrole role to $userprincipleName..." -LogPath $logFile -ReportingName 'INFO'
                    }
                }
                else{
                    Add-MsolRoleMember -RoleName $Usrrole -RoleMemberEmailAddress $userprincipleName   
                    Write-host "Assigned $Usrrole role to $userprincipleName..." -ForegroundColor Green
                    O365-WriteLog -writString  "Assigned $Usrrole role to $userprincipleName..." -LogPath $logFile -ReportingName 'INFO'
                }
            }
        }catch{
            $message= $_.Exception.Message + $_.ScriptStackTrace 
            Write-Host -Message "Error while assigning the user roles $message..." -ForegroundColor Red 
            O365-WriteLog -writString "Error while assigning the user roles -> $message " -LogPath $logFile -ReportingName 'EXCEPTION'    
        }

        #Creating role group and assinging roles
                                                                                                                                                                                                                                                                try{
        Write-host "Working on role group and assigining roles..." -ForegroundColor Green
        O365-WriteLog -writString  "Working on role group  and assigining roles..." -LogPath $logFile -ReportingName 'INFO'
        $existedrolegroups=Get-RoleGroup | select Members,Roles,Identity
        if($grp){         
            $rolegroupdetails=$existedrolegroups | Where-Object {($_.Identity) -eq $grp} | select *
            if($rolegroupdetails){
                Write-host "$grp Role group already exists..."
                O365-WriteLog -writString  "$grp Role Group already exists..." -LogPath $logFile -ReportingName 'INFO'
                $existedroleslist=$rolegroupdetails.Roles
                foreach($role in $roleslist){
                    if(!$existedroleslist.contains($role)){
                        New-ManagementRoleAssignment -Role $role -SecurityGroup $grp
                        O365-WriteLog -writString  "Added role $role to role group $grp..." -LogPath $logFile -ReportingName 'INFO'
                        Write-host "Added role $role to role group $grp..." -ForegroundColor Green
                    }
                }
                $existedmembers=$rolegroupdetails.Members
                if(!$existedmembers.contains($displayname)){
                    $Error.clear()
                    Start-sleep -Seconds 60
                    Add-RoleGroupMember $grp -Member $userprincipleName 
                    $count=0
                    while($Error){
                        Write-Host 'Sleeping for 30 seconds for adding role group member (Add-RoleGroupMember)' # to make user availble for commandlets
                        Start-sleep -Seconds 30
                        $Error.clear()
                        Add-RoleGroupMember $grp -Member $userprincipleName 
                        $count++
                        if($count -gt 10){
                            Write-host "Failed to add $userprincipleName as member to role group $grp, please re-run the script with same inputs..." -ForegroundColor Green
                            O365-WriteLog -writString  "Failed to add $userprincipleName as member to role group $grp, please re-run the script with same inputs..." -LogPath $logFile -ReportingName 'ERROR'
                            exit
                        }
                    }
                    O365-WriteLog -writString  "Added $userprincipleName as member to role group $grp" -LogPath $logFile -ReportingName 'INFO'
                    Write-host "Added $userprincipleName as member to role group $grp" -ForegroundColor Green
                }
            }
            else{
                Start-sleep -Seconds 60
                $breaklimit=10
                Try{
                    $result=New-RoleGroup -Name $grp -Roles $roleslist -Members $userprincipleName -ManagedBy $AdminuserName -ErrorAction SilentlyContinue 
                }Catch{}
                while(!$result){
                    Write-Host 'sleep for 30 seconds for working on New-RoleGroup' # to make user availble for commandlets
                    Start-sleep -Seconds 30
                    Try{
                        $result=New-RoleGroup -Name $grp -Roles $roleslist -Members $userprincipleName -ManagedBy $AdminuserName -ErrorAction SilentlyContinue 
                    }Catch{}
                    $result
                    $breaklimit--
                    if($breaklimit -lt 1){
                        break
                    }  
                }
                Write-host "Created $grp role group with roles $roleslist..." -ForegroundColor Green
                O365-WriteLog -writString  "Created $grp role group with roles $roleslist..." -LogPath $logFile -ReportingName 'INFO'
            }
        }
    }
            catch{
                $message= $_.Exception.Message + $_.ScriptStackTrace 
                Write-Error -Message "Error while creating or assigining the role group and roles $message..." 
                O365-WriteLog -writString "Error while creating or assigning the role group and roles -> $message..." -LogPath $logFile -ReportingName 'EXCEPTION'    
            }
            $an='~'+$mn+':751:'+$pn
            O365-WriteLog -writString  "All permissions are set successfully for user $userprincipleName" -LogPath $logFile -ReportingName 'DONE'
            Write-host "All permissions are set successfully for user $userprincipleName"


            #TESTING
            Write-host  "checking user $userprincipleName existed or not....." 
            O365-WriteLog -writString  "checking user $userprincipleName existing or not" -LogPath $logFile -ReportingName 'TESTING'

            $chkAcc=$false
            $userdetais=Get-MsolUser -UserPrincipalName $userprincipleName -ErrorAction SilentlyContinue | select *    
                                                                                                                                                                                                                                                                                                                                                    if($userdetais){
            $chkAcc=$true
            $displayname=$userdetais.DisplayName   
            try{                    
                $existeduserroles=(Get-MsolUserRole -UserPrincipalName $userprincipleName | select Name).Name
                if($existeduserroles){

                    foreach($requirerole in $assgingUserRoles)
                    {
                       if(!$existeduserroles.contains($requirerole)){
                            Write-Host "$requirerole user role is not assigned to $userprincipleName user" -ForegroundColor Red
                            O365-WriteLog -writString  "$requirerole user role is not assigned to $userprincipleName user " -LogPath $logFile -ReportingName 'WARN'
                       }else{
                            Write-Host "$requirerole user role assigned to $userprincipleName user" -ForegroundColor Magenta
                            O365-WriteLog -writString  "$requirerole user role is assigned to $userprincipleName user " -LogPath $logFile -ReportingName 'INFO'
                       }
                    }
                    Write-Host "Assigned user roles for  $userprincipleName user is "
                    O365-WriteLog -writString  "Assigned user roles for  $userprincipleName user is $existeduserroles " -LogPath $logFile -ReportingName 'INFO'
                    $existeduserroles
                }
                else{
                    Write-Host "No user roles assigned for $userprincipleName user " -ForegroundColor Red
                    O365-WriteLog -writString  "No user roles assigned for $userprincipleName user, re-run the script " -LogPath $logFile -ReportingName 'WARN'
                }
            }
            catch{
                $message= $_.Exception.Message + $_.ScriptStackTrace 
                Write-Error -Message "Error while getting the user roles $message..."
                O365-WriteLog -writString  "Error while getting the user roles $message..." -LogPath $logFile -ReportingName 'ERROR'
            }

            try{

                $existedrolegroups=Get-RoleGroup | select Members,Roles,Identity
                $rolegroupdetails=$existedrolegroups | Where-Object {($_.Identity) -eq $grp} | select *  
            
                if($rolegroupdetails){
                    $existedroleslist=$rolegroupdetails.Roles
                    foreach($role in $roleslist){
                        if(!$existedroleslist.contains($role)){
                            O365-WriteLog -writString  "role $role is not availble in  $grp role group..." -LogPath $logFile -ReportingName 'WARN'
                            Write-host "role $role is not availble in $grp role group..." -ForegroundColor Red
                        }else{
                            O365-WriteLog -writString  "role $role is availble in  $grp role group..." -LogPath $logFile -ReportingName 'INFO'
                            Write-host "role $role is availble in $grp role group..." -ForegroundColor Magenta
                        }
                    }

                    $existedmembers=$rolegroupdetails.Members
                    if(!$existedmembers.contains($displayname)){
                            O365-WriteLog -writString  " $userprincipleName user is not member to  $grp rol group..." -LogPath $logFile -ReportingName 'WARN'
                            Write-host "$userprincipleName user is not member to $grp rol group..." -ForegroundColor Red
                    }else{
                            O365-WriteLog -writString  " $userprincipleName user is member to $grp role group..." -LogPath $logFile -ReportingName 'INFO'
                            Write-host "$userprincipleName user is member to $grp role group..." -ForegroundColor Magenta
                    }

                    Write-Host "Assigned roles for $grp group  is "
                    O365-WriteLog -writString  "Assigned roles for $grp group is $rolegroupdetails.Roles " -LogPath $logFile -ReportingName 'INFO'
                    $rolegroupdetails
                }
                else{
                    write-host "Role $grp group does not exist-ForegroundColor Red"
                    O365-WriteLog -writString  "Role $grp group does not exist,re-run the script" -LogPath $logFile -ReportingName 'TESTING'
                }
            }
            catch{
                $message= $_.Exception.Message + $_.ScriptStackTrace 
                Write-Error -Message "Error while checking the assiged roles for the $grp group $message..."
                O365-WriteLog -writString  "Error while checking the assiged roles for the $grp group $message..." -LogPath $logFile -ReportingName 'ERROR'

            } 
    
            if($chkAcc){
                if($monitorPassword -ne $null -and $monitorPassword -ne ''){
                    $encPasswrd=O365-Enc -str $monitorPassword  
                }    
                if($runningManually){
                    #"["+$applicationName+"-"+$domain+"]"| Add-Content $filePath
                    #'Username~'+$monitorUser | Add-Content $filePath
                    #'password~'+$encPasswrd | Add-Content $filePath
                    #O365-WriteLog -writString  $an -LogPath $logFile -ReportingName 'INFO'
                }
                Write-Host '**Username~'$monitorUser
                Write-Host '**password~'$encPasswrd
                O365-WriteLog -writString  $an -LogPath $logFile -ReportingName 'INFO'
                #O365-WriteLog -writString  "Username is $monitorUser" -LogPath $logFile -ReportingName 'INFO'
                #O365-WriteLog -writString  "Password is $encPasswrd" -LogPath $logFile -ReportingName 'INFO'
            }             
        }
            else{
                O365-WriteLog -writString  "Unable to create user $userprincipleName, please re-run the script" -LogPath $logFile -ReportingName 'WARN'
                Write-host " Unable to create user $userprincipleName, please re-run the script " -ForegroundColor Red
                exit
            }

            Get-PSSession | Remove-PSSession -Confirm:$false
    }

    # 3.GRAPH API - GENERATING CILENTID AND SECRECT AND SET APP, DELEGATE PERMISSIONS
    $startDate = (Get-Date).AddDays(-1)
    $endDate = $startDate.AddMonths(24)
    $spArr=[System.Collections.ArrayList]@()
    O365-WriteLog -writString  "GRAPH API - started" -LogPath $logFile -ReportingName 'INFO'
    Connect-AzureAd  -AzureEnvironment $azureCloudArr[0] -Credential $credential
    $existingapp = $null
    $existingapp = get-azureadapplication -Filter "DisplayName eq '$applicationName'"
    if ($existingapp) {
        Remove-Azureadapplication -ObjectId $existingApp.objectId
    }
    $requiredResourcesAccess = New-Object System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.RequiredResourceAccess]

    foreach($str in $srchStrArr){
        $srchStr=$str -split('#')
        $appArray = [System.Collections.ArrayList]@()
        $delArray = [System.Collections.ArrayList]@()
        $svcPrincipal=Get-AzureADServicePrincipal -SearchString $srchStr[1] | Where-Object {$_.DisplayName -eq $srchStr[1]}

        $spArr.Add($svcPrincipal)
        for($i=0;$i -lt $reqPermissionArr.Length;$i++ ){
            if($reqPermissionArr[$i].StartsWith($srchStr[0])){
                $grStr=$srchStr[0].ToString().Length
                $tmpnam=$srchStr[0]
                while($true){
                    if($reqPermissionArr[$i].StartsWith($tmpnam) -and $reqPermissionArr[$i].EndsWith('App')){
                        $displayNam=$reqPermissionArr[$i].Substring($grStr)
                        $appIdx=$displayNam.Length-3
                        $displayNam=$displayNam.Substring(0,$appIdx)
                        $appArray.Add($displayNam) 
                        if($i -lt $reqPermissionArr.Length-1){
                            $i++
                        }else{break;}
                    }else{
                        break;
                    }
                }
                while($true){
                    if($reqPermissionArr[$i].StartsWith($tmpnam) -and $reqPermissionArr[$i].EndsWith('Del')){     
                        $displayNam=$reqPermissionArr[$i].Substring($grStr)
                        $appIdx=$displayNam.Length-3
                        $displayNam=$displayNam.Substring(0,$appIdx)
                        $delArray.Add($displayNam)
                        if($i -lt $reqPermissionArr.Length-1){
                            $i++
                        }else{break;}
                    }else{
                        break;
                    }
                }
                $appValue=$svcPrincipal.AppRoles | Where-Object{$_.DisplayName -in $appArray}
                $delValue=$svcPrincipal.Oauth2Permissions | Where-Object{$_.AdminConsentDisplayName -in $delArray}
                $azureAppPermissions = GetRequiredPermissions -reqsp $svcPrincipal -requiredApplicationPermissions $appValue -requiredDelegatedPermissions $delValue
                $requiredResourcesAccess.Add($azureAppPermissions)
            }
        }
    }

    #create new Application
    $aadApplication = New-AzureADApplication -DisplayName $applicationName -ReplyUrls $replyUrl -RequiredResourceAccess $requiredResourcesAccess -IdentifierUris $identyUri
    $null=Get-AzureADOAuth2PermissionGrant -All $true
    O365-WriteLog -writString  "New Application created" -LogPath $logFile -ReportingName 'INFO'

    #set the secret key for application
    $tmpCreVal=New-AzureADApplicationPasswordCredential -ObjectId $aadApplication.ObjectId -StartDate $startDate -EndDate $endDate -CustomKeyIdentifier $KeyDesc
    O365-WriteLog -writString  "Secret key generated" -LogPath $logFile -ReportingName 'INFO'

    #Assign application permissions to the application
    $servicePrincipal = New-AzureADServicePrincipal -AppId $aadApplication.AppId      
    foreach ($app in $requiredResourcesAccess){
        
        $reqAppSP = $spArr | Where-Object {$_.appid -contains $app.ResourceAppId}
        #Write-Host "Assigning Application permissions for $($reqAppSP.displayName)" -ForegroundColor DarkYellow 
         
        foreach ($resource in $app.ResourceAccess) {
            if ($resource.Type -match "Role") {
                New-AzureADServiceAppRoleAssignment -ObjectId $serviceprincipal.ObjectId -PrincipalId $serviceprincipal.ObjectId -ResourceId $reqAppSP.ObjectId -Id $resource.Id
            }
        }      
    }
    O365-WriteLog -writString  "App or Delegate permissions assigned" -LogPath $logFile -ReportingName 'INFO'

    #grant oauth2permissions
    Get-AzureADOAuth2PermissionGrant -All $true
    O365-WriteLog -writString  "App or Delegate permissions granted" -LogPath $logFile -ReportingName 'INFO'

    $client_id=$aadApplication.AppId
    $client_secret=$tmpCreVal.Value
    $tenantName=$domain #(Get-AzureADTenantDetail).VerifiedDomains.Name
    $authority = "https://login.microsoftonline.com/"
    $resource = "https://graph.microsoft.com"

    if($runningManually){
        if($client_id -ne $null -and $client_id -ne '' -and $client_secret -ne $null -and $client_secret -ne ''){
            O365-WriteLog -writString  "applicationName~$applicationName" -LogPath $logFile -ReportingName 'INFO'
            O365-WriteLog -writString  "client_id~$client_id" -LogPath $logFile -ReportingName 'INFO'
            O365-WriteLog -writString  "client_secret~$client_secret" -LogPath $logFile -ReportingName 'INFO'
            O365-WriteLog -writString  "TenantName~$tenantName" -LogPath $logFile -ReportingName 'INFO'
            O365-WriteLog -writString  "Authority~$authority" -LogPath $logFile -ReportingName 'INFO'
            O365-WriteLog -writString  "Resource~$resource" -LogPath $logFile -ReportingName 'INFO'
        }
    }
    else{
        $keyFileNam='\GraphDetailsKey.dat'
                $keyPath=$writDir+$keyFileNam
                $unProtFile=$writDir+'\GraphDetails.dat'
                if(Test-Path $unProtFile -PathType Leaf){
                    $unProtPath=$writDir+'\GraphDetails.dat'
                    $kvalue=Get-Content -Path $keyPath
                    Unprotect-File $unProtPath -Algorithm AES -KeyAsPlainText $kvalue -DstSuffix '.txt'
                }

                $chkNam="-"+$tenantName+"]"
                $writPath=$writDir+'\GraphDetails.txt'
                if(Test-Path $writPath -PathType Leaf){
                    $dtls=Get-Content -Path $writPath
                    $j=0
                    $wpath1=$writDir+'\GraphDetails1.txt'
                    for($i=0;$i -lt $dtls.Length;$i++){
                        if($dtls[$i] -match $chkNam){
                            $i=$i+8
                        }
                        Add-Content -Path $wpath1 -Value $dtls[$i]
                    }
                    Remove-Item $writPath
                    if(Test-Path $wpath1 -PathType Leaf){
                        Rename-Item $wpath1 'GraphDetails.txt'
                    }
                }

                '['+$applicationName+'-'+$tenantName+']'| Add-Content $writPath -PassThru
                'client_id~'+$client_id| Add-Content $writPath -PassThru
                'client_secret~'+$client_secret| Add-Content $writPath -PassThru
                'TenantName~'+$tenantName| Add-Content $writPath -PassThru
                'Authority~'+$authority| Add-Content $writPath -PassThru
                'Resource~'+$resource| Add-Content $writPath -PassThru
                "`n"| Add-Content $writPath

                $key=Get-CryptoKey -FileDir $writDir -FileName $keyFileNam
                $null=Protect-File $writPath -Algorithm AES -KeyAsPlainText $key -RemoveSource

                Write-Host 'Permissions provided successfully'
    }

    Write-Host 'Graph API Permissions provided successfully'
    O365-WriteLog -writString  "Graph API APP registered and Permissions provided successfully" -LogPath $logFile -ReportingName 'INFO'
}
else{
    Write-Host 'Given O365 Account is invalid or not in Global Administrator role'
    O365-WriteLog -writString  "Given O365 Account is invalid or not in Global Administrator role" -LogPath $logFile -ReportingName 'ERROR'
}




# SIG # Begin signature block
# MIIcdAYJKoZIhvcNAQcCoIIcZTCCHGECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUkMYd1ovY4H37ZIMvkxFpSx5y
# AKqggherMIIFMDCCBBigAwIBAgIQBAkYG1/Vu2Z1U0O1b5VQCDANBgkqhkiG9w0B
# AQsFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk
# IElEIFJvb3QgQ0EwHhcNMTMxMDIyMTIwMDAwWhcNMjgxMDIyMTIwMDAwWjByMQsw
# CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
# ZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQg
# Q29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
# +NOzHH8OEa9ndwfTCzFJGc/Q+0WZsTrbRPV/5aid2zLXcep2nQUut4/6kkPApfmJ
# 1DcZ17aq8JyGpdglrA55KDp+6dFn08b7KSfH03sjlOSRI5aQd4L5oYQjZhJUM1B0
# sSgmuyRpwsJS8hRniolF1C2ho+mILCCVrhxKhwjfDPXiTWAYvqrEsq5wMWYzcT6s
# cKKrzn/pfMuSoeU7MRzP6vIK5Fe7SrXpdOYr/mzLfnQ5Ng2Q7+S1TqSp6moKq4Tz
# rGdOtcT3jNEgJSPrCGQ+UpbB8g8S9MWOD8Gi6CxR93O8vYWxYoNzQYIH5DiLanMg
# 0A9kczyen6Yzqf0Z3yWT0QIDAQABo4IBzTCCAckwEgYDVR0TAQH/BAgwBgEB/wIB
# ADAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwMweQYIKwYBBQUH
# AQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYI
# KwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFz
# c3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmw0
# LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaG
# NGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RD
# QS5jcmwwTwYDVR0gBEgwRjA4BgpghkgBhv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0
# dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCgYIYIZIAYb9bAMwHQYDVR0OBBYE
# FFrEuXsqCqOl6nEDwGD5LfZldQ5YMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6en
# IZ3zbcgPMA0GCSqGSIb3DQEBCwUAA4IBAQA+7A1aJLPzItEVyCx8JSl2qB1dHC06
# GsTvMGHXfgtg/cM9D8Svi/3vKt8gVTew4fbRknUPUbRupY5a4l4kgU4QpO4/cY5j
# DhNLrddfRHnzNhQGivecRk5c/5CxGwcOkRX7uq+1UcKNJK4kxscnKqEpKBo6cSgC
# PC6Ro8AlEeKcFEehemhor5unXCBc2XGxDI+7qPjFEmifz0DLQESlE/DmZAwlCEIy
# sjaKJAL+L3J+HNdJRZboWR3p+nRka7LrZkPas7CM1ekN3fYBIM6ZMWM9CBoYs4Gb
# T8aTEAb8B4H6i9r5gkn3Ym6hU/oSlBiFLpKR6mhsRDKyZqHnGKSaZFHvMIIFNDCC
# BBygAwIBAgIQAuEYSxAWnqD3sU8D3BMzUjANBgkqhkiG9w0BAQsFADByMQswCQYD
# VQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGln
# aWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgQ29k
# ZSBTaWduaW5nIENBMB4XDTE4MDcxMDAwMDAwMFoXDTIxMDkxNTEyMDAwMFowcTEL
# MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxDzANBgNVBAcTBklzZWxp
# bjEdMBsGA1UEChMUZUcgSW5ub3ZhdGlvbnMsIEluYy4xHTAbBgNVBAMTFGVHIElu
# bm92YXRpb25zLCBJbmMuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
# oNt7XWB1y9xwtvCGO/XipXallOkZ3ScdXunWCONnBzryRdCj7C/WX9s1CU8KkjRP
# FjWW+BOXvvC4ZUqw0Ad2uJAXyBY2/lV9eaoTRFB6Kb2/tJzG3je7Vcu8MxGJlwzP
# QQrr6icEJeqAPFE7vmzThVbd9H1n5Zdmwx20WCFe2V9qyVYHt7/6GS7WB2CwwjT6
# iVmiKP8HZXgr3tHZeAEb7tdQqd5//9e+8Mp8anb8ZdNgC9PQjBmbrQ/wH3kV65gK
# L+5kbgRvIfsmYxXiU1IFkq4rSQ+tfsDtYqBhGfovef9Gt8ZTjx7S4fortxwR7tlz
# i+wLO5m8I9sm4I2ouyIOQQIDAQABo4IBxTCCAcEwHwYDVR0jBBgwFoAUWsS5eyoK
# o6XqcQPAYPkt9mV1DlgwHQYDVR0OBBYEFD3yRqdsw6UIddfMPwhUMv2AaGRAMA4G
# A1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzB3BgNVHR8EcDBuMDWg
# M6Axhi9odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcx
# LmNybDA1oDOgMYYvaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl
# ZC1jcy1nMS5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAwEwKjAoBggrBgEFBQcC
# ARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBBAEwgYQGCCsG
# AQUFBwEBBHgwdjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t
# ME4GCCsGAQUFBzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl
# cnRTSEEyQXNzdXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADAN
# BgkqhkiG9w0BAQsFAAOCAQEAP1QnJ6TEczaeGxVokMinsKam1mJB+zDk4B9rfm31
# iaZe9OeNvR/UJAs+5b0gKBZF9NmTVdayAYV74vZU5IElRo59q6hbg/20Wu87UyoE
# Yjwrv2DxHgl3z80piuLllmoe79vEu/bYvreBamzZmHlyxRP0us2KRfEsLBH23y1o
# zBATLc3yBu+mCfDg9E1RfhpKyD1iMHkbC90To6bpOlP9Pd6R4WEAFROILgm2bofQ
# ZhN4UNKbJ1uLCvV2NiUbU7+YSC3NP9SdphaDBiOnUWiK8MjTIPZbhh3QjI5f342q
# cUiR4LGx/Z/6pq4w6YHWd8c1czexD7xVCom7ZafCOKFWyzCCBmowggVSoAMCAQIC
# EAMBmgI6/1ixa9bV6uYX8GYwDQYJKoZIhvcNAQEFBQAwYjELMAkGA1UEBhMCVVMx
# FTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNv
# bTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBDQS0xMB4XDTE0MTAyMjAw
# MDAwMFoXDTI0MTAyMjAwMDAwMFowRzELMAkGA1UEBhMCVVMxETAPBgNVBAoTCERp
# Z2lDZXJ0MSUwIwYDVQQDExxEaWdpQ2VydCBUaW1lc3RhbXAgUmVzcG9uZGVyMIIB
# IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo2Rd/Hyz4II14OD2xirmSXU7
# zG7gU6mfH2RZ5nxrf2uMnVX4kuOe1VpjWwJJUNmDzm9m7t3LhelfpfnUh3SIRDsZ
# yeX1kZ/GFDmsJOqoSyyRicxeKPRktlC39RKzc5YKZ6O+YZ+u8/0SeHUOplsU/UUj
# joZEVX0YhgWMVYd5SEb3yg6Np95OX+Koti1ZAmGIYXIYaLm4fO7m5zQvMXeBMB+7
# NgGN7yfj95rwTDFkjePr+hmHqH7P7IwMNlt6wXq4eMfJBi5GEMiN6ARg27xzdPpO
# 2P6qQPGyznBGg+naQKFZOtkVCVeZVjCT88lhzNAIzGvsYkKRrALA76TwiRGPdwID
# AQABo4IDNTCCAzEwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0l
# AQH/BAwwCgYIKwYBBQUHAwgwggG/BgNVHSAEggG2MIIBsjCCAaEGCWCGSAGG/WwH
# ATCCAZIwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMw
# ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA
# aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA
# ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA
# aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA
# eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA
# YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA
# cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA
# eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMB8GA1UdIwQYMBaA
# FBUAEisTmLKZB+0e36K+Vw0rZwLNMB0GA1UdDgQWBBRhWk0ktkkynUoqeRqDS/Qe
# icHKfTB9BgNVHR8EdjB0MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20v
# RGlnaUNlcnRBc3N1cmVkSURDQS0xLmNybDA4oDagNIYyaHR0cDovL2NybDQuZGln
# aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwdwYIKwYBBQUHAQEE
# azBpMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYB
# BQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3Vy
# ZWRJRENBLTEuY3J0MA0GCSqGSIb3DQEBBQUAA4IBAQCdJX4bM02yJoFcm4bOIyAP
# gIfliP//sdRqLDHtOhcZcRfNqRu8WhY5AJ3jbITkWkD73gYBjDf6m7GdJH7+IKRX
# rVu3mrBgJuppVyFdNC8fcbCDlBkFazWQEKB7l8f2P+fiEUGmvWLZ8Cc9OB0obzpS
# CfDscGLTYkuw4HOmksDTjjHYL+NtFxMG7uQDthSr849Dp3GdId0UyhVdkkHa+Q+B
# 0Zl0DSbEDn8btfWg8cZ3BigV6diT5VUW8LsKqxzbXEgnZsijiwoc5ZXarsQuWaBh
# 3drzbaJh6YoLbewSGL33VVRAA5Ira8JRwgpIr7DUbuD0FAo6G+OPPcqvao173NhE
# MIIGzTCCBbWgAwIBAgIQBv35A5YDreoACus/J7u6GzANBgkqhkiG9w0BAQUFADBl
# MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
# d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
# b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMjExMTEwMDAwMDAwWjBiMQswCQYDVQQG
# EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
# cnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBBc3N1cmVkIElEIENBLTEwggEiMA0G
# CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDogi2Z+crCQpWlgHNAcNKeVlRcqcTS
# QQaPyTP8TUWRXIGf7Syc+BZZ3561JBXCmLm0d0ncicQK2q/LXmvtrbBxMevPOkAM
# Rk2T7It6NggDqww0/hhJgv7HxzFIgHweog+SDlDJxofrNj/YMMP/pvf7os1vcyP+
# rFYFkPAyIRaJxnCI+QWXfaPHQ90C6Ds97bFBo+0/vtuVSMTuHrPyvAwrmdDGXRJC
# geGDboJzPyZLFJCuWWYKxI2+0s4Grq2Eb0iEm09AufFM8q+Y+/bOQF1c9qjxL6/s
# iSLyaxhlscFzrdfx2M8eCnRcQrhofrfVdwonVnwPYqQ/MhRglf0HBKIJAgMBAAGj
# ggN6MIIDdjAOBgNVHQ8BAf8EBAMCAYYwOwYDVR0lBDQwMgYIKwYBBQUHAwEGCCsG
# AQUFBwMCBggrBgEFBQcDAwYIKwYBBQUHAwQGCCsGAQUFBwMIMIIB0gYDVR0gBIIB
# yTCCAcUwggG0BgpghkgBhv1sAAEEMIIBpDA6BggrBgEFBQcCARYuaHR0cDovL3d3
# dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsGAQUF
# BwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABDAGUA
# cgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABhAGMA
# YwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQByAHQA
# IABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBnACAA
# UABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABsAGkA
# bQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABpAG4A
# YwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBlAGYA
# ZQByAGUAbgBjAGUALjALBglghkgBhv1sAxUwEgYDVR0TAQH/BAgwBgEB/wIBADB5
# BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0
# LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp
# Z2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0
# cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNy
# bDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl
# ZElEUm9vdENBLmNybDAdBgNVHQ4EFgQUFQASKxOYspkH7R7for5XDStnAs0wHwYD
# VR0jBBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDQYJKoZIhvcNAQEFBQADggEB
# AEZQPsm3KCSnOB22WymvUs9S6TFHq1Zce9UNC0Gz7+x1H3Q48rJcYaKclcNQ5IK5
# I9G6OoZyrTh4rHVdFxc0ckeFlFbR67s2hHfMJKXzBBlVqefj56tizfuLLZDCwNK1
# lL1eT7EF0g49GqkUW6aGMWKoqDPkmzmnxPXOHXh2lCVz5Cqrz5x2S+1fwksW5Etw
# TACJHvzFebxMElf+X+EevAJdqP77BzhPDcZdkbkPZ0XN1oPt55INjbFpjE/7WeAj
# D9KqrgB87pxCDs+R1ye3Fu4Pw718CqDuLAhVhSK46xgaTfwqIa1JMYNHlXdx3LEb
# S0scEJx3FMGdTy9alQgpECYxggQzMIIELwIBATCBhjByMQswCQYDVQQGEwJVUzEV
# MBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t
# MTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgQ29kZSBTaWduaW5n
# IENBAhAC4RhLEBaeoPexTwPcEzNSMAkGBSsOAwIaBQCgcDAQBgorBgEEAYI3AgEM
# MQIwADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4w
# DAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQUHwEfSOoSv0h9iboZAVv/9a+L
# 8N0wDQYJKoZIhvcNAQEBBQAEggEAD5ohOnQGObNSCv147P3M1WeTKtrLEmpvu+7f
# eKSkh8AduCwMA8wVTLoOhyEe/f8lGCPI1rDNNwpB3TJXV4vFAtKzOjdI3nYjuR99
# utm15C1zjPF8RIs98fNkdIGSdq6x/aCw3FTyZPu2ieoREUk1Wvpu643UFk/csQrH
# FuKdL3oGnvkXm8N5G1PoNtrtp9rNQ9Osdeu5HhTgW+fZu3rczioEOHja7Lb4qNY6
# aLxBmRFb7ZrL4GGQkyjIKk4lK9UySpay3qdwIWhJVjdx0KnZn2oFnB4Mz1Z+Mb/7
# lwhqblVqjBMyofGiklJZODPXQd2wtCS7AqW1QSSqNCRwNcURUaGCAg8wggILBgkq
# hkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxE
# aWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMT
# GERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGaAjr/WLFr1tXq5hfwZjAJBgUr
# DgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx
# DxcNMjAwNzIzMDIwNDExWjAjBgkqhkiG9w0BCQQxFgQU34cQTWYJu6p0vKWbIDUq
# wqD0Fa0wDQYJKoZIhvcNAQEBBQAEggEAHge++a7aghVg1taUR5v+yyLWM/yY3Mh3
# 5s5fTfHVO8grP6bXyRkITAPdCOHduAtaL+pIg5Yj834g+UFidNi4fnGUNSEBqO9L
# wAb6BbFMnBaCA3+kDxr813Dbsdt9/xfZKsGF8DUyxvnL3UQLXQTjIZhMGne861Ti
# uRgrEH5vA7cHvjgJrZ63Ald+LSunGh0JvT9OR+LfOBVe5txLa8bqq8wLxbFeZZ/5
# KFUIgx6/NcNGy94hPfvjvB8Z0KTy2Nony5RR6NF5NqlMlV1i0sC7Pdv5msCMVsIh
# Vycqow4oua0VfQ5bw74Mc3lb9VlLR8UHMT+Q1lFCi8nLBiOmrVEfCg==
# SIG # End signature block
