MyPSFunctions.MgGraph.ps1
<#
=========================================================================== Created with: SAPIEN Technologies, Inc., PowerShell Studio 2021 v5.8.196 Created on: 10/26/2023 7:46 PM Created by: John@MyPSFunctions.com Organization: MyPSFunctions Filename: MyPSFunctions.MgGraph.psm1 ------------------------------------------------------------------------- Module Name: MyPSFunctions.MgGraph =========================================================================== #> #region Basics #################################################### ############################## Basics ################ #################################################### Function Find-MgScopesOfCMDlet { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CMDlet ) Find-MgGraphCommand -Command $CMDlet | Select -First 1 -ExpandProperty Permissions } Function Get-MgToken { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$TenantID, [Parameter(Mandatory = $true, Position = 2)] [String]$AppID, [Parameter(Mandatory = $true, Position = 3)] [string]$AppSecret ) # Construct URI and body needed for authentication $URI = "https://login.microsoftonline.com/" + $TenantID + "/oauth2/v2.0/token" $Body = @{ Grant_Type = "client_credentials" Scope = "https://graph.microsoft.com/.default" Client_Id = $AppID Client_Secret = $AppSecret } # Get OAuth 2.0 Token $connection = Invoke-RestMethod -Uri $URI -Method POST -Body $body # Unpack Access Token $Token = $connection.access_token Return $Token } #endregion #region Users #################################################### ###################### Users ######################## #################################################### Function Generate-MgUserMicrosoft365GroupMembership { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$UPN ) $MgGroups = Get-MgUserMemberOf -UserId $UPN #Initiate the Hash Table $Table = $Null $Table = @() foreach ($MgGroup in $MgGroups) { $MgGroupID = $Null $MgGroupID = $MgGroup.ID $FoundMgGroup = $Null $MgGroup_DisplayName = $Null $MgGroup_Mail = $Null $MgGroup_MailEnabled = $Null $MgGroup_SecurityEnabled = $Null Try { $FoundMgGroup = Get-mgGroup -GroupId $MgGroupID -ErrorAction Stop $MgGroup_DisplayName = $FoundMgGroup.DisplayName $MgGroup_Mail = $FoundMgGroup.Mail $MgGroup_MailEnabled = $FoundMgGroup.MailEnabled $MgGroup_SecurityEnabled = $FoundMgGroup.SecurityEnabled } Catch { $ErrorMessage = $Error[0].Exception.Message $FoundMgGroup = "Not Found - Failed with Error : $ErrorMessage" $MgGroup_DisplayName = "Not Found - Failed with Error : $ErrorMessage" $MgGroup_Mail = "Not Found - Failed with Error : $ErrorMessage" $MgGroup_MailEnabled = "Not Found - Failed with Error : $ErrorMessage" $MgGroup_SecurityEnabled = "Not Found - Failed with Error : $ErrorMessage" } $Table += New-object PSobject -Property ([Ordered] @{ GroupID = $MgGroupID; DisplayName = $MgGroup_DisplayName; MailEnabled = $MgGroup_MailEnabled; Mail = $MgGroup_Mail; SecurityEnabled = $MgGroup_SecurityEnabled; }) } $Table } Function Check-MgAllUsersStats { [CmdletBinding()] param () Connect-MgGraph -Scopes 'User.Read.All' -NoWelcome $MgContext = Get-MgContext $MgScopes = $MgContext.Scopes -join ";" Write-Log Info -Message "Connected to MgGraph with the following scopes: $MgScopes" # All MgUsers $AllMgUsers = Get-MgUser -all -Property DisplayName, UserPrincipalName, UserType, AccountEnabled # All Member MgUsers $AllMemberMgUsers = $AllMgUsers | where { $_.UserType -ne "Guest" } # All Enabled MgUsers $AllEnabledMgUsers = $AllMgUsers | where { $_.UserType -ne "Guest" -and $_.AccountEnabled -eq $True } # All Disabled MgUsers $AllDisabledMgUsers = $AllMgUsers | where { $_.UserType -ne "Guest" -and $_.AccountEnabled -eq $false } #Counts $AllMgUsersCount = ($AllMgUsers | Measure).count $AllMemberMgUsersCount = ($AllMemberMgUsers | Measure).count $AllEnabledMgUsersCount = ($AllEnabledMgUsers | Measure).count $AllDisabledMgUsersCount = ($AllDisabledMgUsers | Measure).count $Table = $Null $Table = @() $Table += New-object PSobject -Property ([Ordered] @{ AllMgUsersCount = $AllMgUsersCount; AllMemberMgUsersCount = $AllMemberMgUsersCount; AllEnabledMgUsersCount = $AllEnabledMgUsersCount; AllDisabledMgUsersCount = $AllDisabledMgUsersCount; }) $Table | fl } Function Generate-MyMgBetaUserSignInActivities { Read-Host "Are you Connect to Beta MgGrap ?" ############################################################################################################################################################################### #################################################################### Variable ##################################################################### ############################################################################################################################################################################### $Date = get-date -UFormat %d%m%Y $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ServerName = [Environment]::MachineName ###### Create Root Folder $RootFolder = $psscriptRoot + "\Users_Reports" ###### Create folder Variable $LogPathFolder = $RootFolder + "\Log\" $LogFile = $LogPathFolder + "Progress_" + $Date + ".log" $ReportPathFolder = $RootFolder + "\Reports\" ###### Create Folder Create-Folder $RootFolder Create-Folder $LogPathFolder Create-Folder $ReportPathFolder $Transcript_File = $LogPathFolder + "Transcript_" + $Date + ".txt" Start-Transcript -Path $Transcript_File -Append -Force ########### Initiate the Process log file when the script started ############ $Initiat_LogA = "#################### starting the Script #####################" $Startat = "### The Script has been launch at $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")" $Startwith = "The Script has been start with the following Account:" + [Environment]::UserName $Starton = "The Script has been start on the following Computer:" + [Environment]::MachineName $Initiat_LogB = "##############################################################" $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogA | Out-File -FilePath $LogFile -Append $Startat | Out-File -FilePath $LogFile -Append $Startwith | Out-File -FilePath $LogFile -Append $Starton | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append ############################################################################################################################################################################### #################################################################### Main Script ##################################################################### ############################################################################################################################################################################### # Found MgUsers Try { #Read-Host "The script going to retreive all users from the tenant" # All Users $Users = Get-MgBetaUser -all -filter "usertype ne 'Guest'" -Countvariable CountVar -ConsistencyLevel eventual -Property SignInActivity, SignInSessionsValidFromDateTime, RefreshTokensValidFromDateTime, DisplayName, UserPrincipalName $ReportFile = $ReportPathFolder + "All_Report_Users_SigninActivities_" + $DateFull + ".xlsx" Write-Log -Level INFO -Message "The script find All Users from the tenant" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -LogPath $LogFile -Message "Failed to Find MgUsers" Write-Log -Level Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" Write-Log -Level Error -LogPath $LogFile -Message "The Script will stop" # Exit the script Read-Host "End of Script" } # Loop $UsersInfo = $Null $UsersInfo = @() [Int]$i = 1 $Count = ($Users | Measure).count foreach ($UserData in $Users) { $UserUPN = $UserData.UserPrincipalName Write-Log -Level warning -LogPath $LogFile -Message "The script is analyzing $UserUPN --- $i/$Count" # MgUser Write-log Warning -Message "The Script is searching for the MgUser: $UserUPN" $FoundMgUserStatus = "Yes" $LastNonInteractiveSignInDateTime = $Null $LastSignInDateTime = $Null $LastSuccessfulSignInDateTime = $Null $SignInSessionsValidFromDateTime = $Null $RefreshTokensValidFromDateTime = $Null If ($UserData.signinActivity.LastNonInteractiveSignInDateTime.DateTime) { $LastNonInteractiveSignInDateTime = Get-Date ($UserData.signinActivity.LastNonInteractiveSignInDateTime.DateTime) -Format "G" $LastNonInteractiveSignInDateTime = [datetime]::Parse($LastNonInteractiveSignInDateTime) } If ($UserData.SignInActivity.LastSignInDateTime.DateTime) { $LastSignInDateTime = Get-Date ($UserData.SignInActivity.LastSignInDateTime.DateTime) -Format "G" $LastSignInDateTime = [datetime]::Parse($LastSignInDateTime) } If ($UserData.SignInActivity.LastSuccessfulSignInDateTime.DateTime) { $LastSuccessfulSignInDateTime = Get-Date ($UserData.SignInActivity.LastSuccessfulSignInDateTime.DateTime) -Format "G" $LastSuccessfulSignInDateTime = [datetime]::Parse($LastSuccessfulSignInDateTime) } If ($UserData.SignInSessionsValidFromDateTime.DateTime) { $SignInSessionsValidFromDateTime = Get-Date ($UserData.SignInSessionsValidFromDateTime.DateTime) -Format "G" $SignInSessionsValidFromDateTime = [datetime]::Parse($SignInSessionsValidFromDateTime) } If ($UserData.RefreshTokensValidFromDateTime.DateTime) { $RefreshTokensValidFromDateTime = Get-Date ($UserData.RefreshTokensValidFromDateTime.DateTime) -Format "G" $RefreshTokensValidFromDateTime = [datetime]::Parse($RefreshTokensValidFromDateTime) } $DisplayName = $UserData.DisplayName $UserPrincipalName = $UserData.UserPrincipalName $UsersInfo += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; UserPrincipalName = $UserPrincipalName; LastSuccessfulSignInDateTime = $LastSuccessfulSignInDateTime; LastNonInteractiveSignInDateTime = $LastNonInteractiveSignInDateTime; LastSignInDateTime = $LastSignInDateTime; SignInSessionsValidFromDateTime = $SignInSessionsValidFromDateTime; RefreshTokensValidFromDateTime = $RefreshTokensValidFromDateTime; }) $i++ } $UsersInfo | Export-Excel $ReportFile -TableName "SignInActivities" -Title "SignIn Activities" -TitleBold -WorksheetName "SignInActivities" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFile" } Function Generate-MyMgBetaUserReport { param ( [Parameter(Mandatory = $true)] [ValidateSet('All', 'Enable', 'Disable')] [String]$Type ) Read-Host "Are you Connect to Beta MgGraph and EXO?" ############################################################################################################################################################################### #################################################################### Variable ##################################################################### ############################################################################################################################################################################### $Date = get-date -UFormat %d%m%Y $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ServerName = [Environment]::MachineName ###### Create Root Folder $RootFolder = $psscriptRoot + "\Users_Reports" ###### Create folder Variable $LogPathFolder = $RootFolder + "\Log\" $LogFile = $LogPathFolder + "Progress_" + $Date + ".log" $ReportPathFolder = $RootFolder + "\Reports\" ###### Create Folder Create-Folder $RootFolder Create-Folder $LogPathFolder Create-Folder $ReportPathFolder $Transcript_File = $LogPathFolder + "Transcript_" + $Date + ".txt" Start-Transcript -Path $Transcript_File -Append -Force ########### Initiate the Process log file when the script started ############ $Initiat_LogA = "#################### starting the Script #####################" $Startat = "### The Script has been launch at $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")" $Startwith = "The Script has been start with the following Account:" + [Environment]::UserName $Starton = "The Script has been start on the following Computer:" + [Environment]::MachineName $Initiat_LogB = "##############################################################" $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogA | Out-File -FilePath $LogFile -Append $Startat | Out-File -FilePath $LogFile -Append $Startwith | Out-File -FilePath $LogFile -Append $Starton | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append ############################################################################################################################################################################### #################################################################### Main Script ##################################################################### ############################################################################################################################################################################### #Found License Name Try { $LocalPath = ".\MapSKUID.csv" If (!(Test-Path $LocalPath)) { Write-Log warning -Message "The script Download Microsoft Licensing CSV File" $URL = "https://download.microsoft.com/download/e/3/e/e3e9faf2-f28b-490a-9ada-c6089a1fc5b0/Product%20names%20and%20service%20plan%20identifiers%20for%20licensing.csv" $LocalPath = ".\MapSKUID.csv" Invoke-WebRequest -Uri $URL -OutFile $LocalPath } Else { Write-Log warning -Message "The folder $LocalPath is already exist" } $MicrosoftSKUs = Import-Csv $LocalPath } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to download $LocalPath" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } # Found MgUsers Try { #Read-Host "The script going to retreive all users from the tenant" # All Users If ($Type -eq "All") { $Users = Get-MgBetaUser -all -filter "usertype ne 'Guest'" -Countvariable CountVar -ConsistencyLevel eventual -Property SignInSessionsValidFromDateTime, RefreshTokensValidFromDateTime,CreatedDateTime, OnPremisesDistinguishedName, OnPremisesImmutableId, OnPremisesLastSyncDateTime, OnPremisesSamAccountName, OnPremisesSyncEnabled, OnPremisesUserPrincipalName, SignInActivity, MailNickname, UserType, AssignedLicenses, DisplayName, UserPrincipalName, JobTitle, Department, AccountEnabled, Mail, LastPasswordChangeDateTime, OnPremisesExtensionAttributes $ReportFile = $ReportPathFolder + "All_Report_Users_" + $DateFull + ".xlsx" Write-Log -Level INFO -Message "The script find All Users from the tenant" } # All Enable Users If ($Type -eq "Enable") { $Users = Get-MgBetaUser -all -filter "accountenabled eq true and usertype ne 'Guest'" -Countvariable CountVar -ConsistencyLevel eventual -Property SignInSessionsValidFromDateTime, RefreshTokensValidFromDateTime,CreatedDateTime, OnPremisesDistinguishedName, OnPremisesImmutableId, OnPremisesLastSyncDateTime, OnPremisesSamAccountName, OnPremisesSyncEnabled, OnPremisesUserPrincipalName, SignInActivity, MailNickname, UserType, AssignedLicenses, DisplayName, UserPrincipalName, JobTitle, Department, AccountEnabled, Mail, LastPasswordChangeDateTime, OnPremisesExtensionAttributes $ReportFile = $ReportPathFolder + "Enable_Report_Users_" + $DateFull + ".xlsx" Write-Log -Level INFO -Message "The script find all Enable Users from the tenant" } # All Disabled Users If ($Type -eq "Disable") { $Users = Get-MgBetaUser -all -filter "accountenabled eq false and usertype ne 'Guest'" -Countvariable CountVar -ConsistencyLevel eventual -Property SignInSessionsValidFromDateTime, RefreshTokensValidFromDateTime,CreatedDateTime, OnPremisesDistinguishedName, OnPremisesImmutableId, OnPremisesLastSyncDateTime, OnPremisesSamAccountName, OnPremisesSyncEnabled, OnPremisesUserPrincipalName, SignInActivity, MailNickname, UserType, AssignedLicenses, DisplayName, UserPrincipalName, JobTitle, Department, AccountEnabled, Mail, LastPasswordChangeDateTime, OnPremisesExtensionAttributes $ReportFile = $ReportPathFolder + "Disable_Report_Users_" + $DateFull + ".xlsx" Write-Log -Level INFO -Message "The script find all Disable Users from the tenant" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -LogPath $LogFile -Message "Failed to Find MgUsers" Write-Log -Level Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" Write-Log -Level Error -LogPath $LogFile -Message "The Script will stop" # Exit the script Read-Host "End of Script" } # Loop $UsersInfo = $Null $UsersInfo = @() [Int]$i = 1 $Count = ($Users | Measure).count foreach ($UserData in $Users) { $UserUPN = $UserData.UserPrincipalName Write-Log -Level warning -LogPath $LogFile -Message "The script is analyzing $UserUPN --- $i/$Count" # MgUser Write-log Warning -Message "The Script is searching for the MgUser: $UserUPN" $FoundMgUserStatus = "Yes" $LastNonInteractiveSignInDateTime = $Null $LastSignInDateTime = $Null $LastSuccessfulSignInDateTime = $Null $SignInSessionsValidFromDateTime = $Null $RefreshTokensValidFromDateTime = $Null $CreatedDateTime = $Null $OnPremisesDistinguishedName = $Null $OnPremisesImmutableId = $Null $OnPremisesLastSyncDateTime = $Null $OnPremisesSamAccountName = $Null $OnPremisesSyncEnabled = $Null $OnPremisesUserPrincipalName = $Null $MailNickname = $Null $DisplayName = $Null $UserPrincipalName = $Null $Department = $Null $Tittle = $Null $AccountEnabled = $Null $Mail = $Null $LastPasswordChangeDateTime = $Null $UserType = $Null $AssignedLicenses = $Null $Licenses = $Null $OnPremisesExtensionAttributes_ExtensionAttribute1 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute2 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute3 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute4 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute5 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute6 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute7 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute8 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute9 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute10 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute11 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute12 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute13 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute14 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute15 = $Null If ($UserData.signinActivity.LastNonInteractiveSignInDateTime.DateTime) { $LastNonInteractiveSignInDateTime = Get-Date ($UserData.signinActivity.LastNonInteractiveSignInDateTime.DateTime) -Format "G" $LastNonInteractiveSignInDateTime = [datetime]::Parse($LastNonInteractiveSignInDateTime) } If ($UserData.SignInActivity.LastSignInDateTime.DateTime) { $LastSignInDateTime = Get-Date ($UserData.SignInActivity.LastSignInDateTime.DateTime) -Format "G" $LastSignInDateTime = [datetime]::Parse($LastSignInDateTime) } If ($UserData.SignInActivity.LastSuccessfulSignInDateTime.DateTime) { $LastSuccessfulSignInDateTime = Get-Date ($UserData.SignInActivity.LastSuccessfulSignInDateTime.DateTime) -Format "G" $LastSuccessfulSignInDateTime = [datetime]::Parse($LastSuccessfulSignInDateTime) } If ($UserData.SignInSessionsValidFromDateTime.DateTime) { $SignInSessionsValidFromDateTime = Get-Date ($UserData.SignInSessionsValidFromDateTime.DateTime) -Format "G" $SignInSessionsValidFromDateTime = [datetime]::Parse($SignInSessionsValidFromDateTime) } If ($UserData.RefreshTokensValidFromDateTime.DateTime) { $RefreshTokensValidFromDateTime = Get-Date ($UserData.RefreshTokensValidFromDateTime.DateTime) -Format "G" $RefreshTokensValidFromDateTime = [datetime]::Parse($RefreshTokensValidFromDateTime) } $CreatedDateTime = $UserData.CreatedDateTime $OnPremisesDistinguishedName = $UserData.OnPremisesDistinguishedName $OnPremisesImmutableId = $UserData.OnPremisesImmutableId $OnPremisesLastSyncDateTime = $UserData.OnPremisesLastSyncDateTime $OnPremisesSamAccountName = $UserData.OnPremisesSamAccountName $OnPremisesSyncEnabled = $UserData.OnPremisesSyncEnabled $OnPremisesUserPrincipalName = $UserData.OnPremisesUserPrincipalName $MailNickname = $UserData.MailNickname $DisplayName = $UserData.DisplayName $UserPrincipalName = $UserData.UserPrincipalName $Department = $UserData.Department $Tittle = $UserData.JobTitle $AccountEnabled = $UserData.AccountEnabled $Mail = $UserData.Mail $LastPasswordChangeDateTime = $UserData.LastPasswordChangeDateTime $UserType = $UserData.UserType $AssignedLicenses = $UserData.AssignedLicenses $OnPremisesExtensionAttributes_ExtensionAttribute1 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute1 $OnPremisesExtensionAttributes_ExtensionAttribute2 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute2 $OnPremisesExtensionAttributes_ExtensionAttribute3 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute3 $OnPremisesExtensionAttributes_ExtensionAttribute4 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute4 $OnPremisesExtensionAttributes_ExtensionAttribute5 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute5 $OnPremisesExtensionAttributes_ExtensionAttribute6 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute6 $OnPremisesExtensionAttributes_ExtensionAttribute7 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute7 $OnPremisesExtensionAttributes_ExtensionAttribute8 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute8 $OnPremisesExtensionAttributes_ExtensionAttribute9 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute9 $OnPremisesExtensionAttributes_ExtensionAttribute10 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute10 $OnPremisesExtensionAttributes_ExtensionAttribute11 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute11 $OnPremisesExtensionAttributes_ExtensionAttribute12 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute12 $OnPremisesExtensionAttributes_ExtensionAttribute13 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute13 $OnPremisesExtensionAttributes_ExtensionAttribute14 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute14 $OnPremisesExtensionAttributes_ExtensionAttribute15 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute15 $CreatedDateTime = $UserData.CreatedDateTime $UserLicenses = @() foreach ($AssignedLicense in $AssignedLicenses) { $SkuId = $Null $SkuId = $AssignedLicense.SkuId $UserLicenses += ($MicrosoftSKUs | where { $_.GUID -eq $SkuId } | Select -first 1).Product_Display_Name } $Licenses = $UserLicenses -join ";" # Recipient $FoundRecipientStatus = "No" $DeletedItemCount = "Not a Mailbox" $ItemCount = "Not a Mailbox" $TotalDeletedItemSize = "Not a Mailbox" $TotalItemSize = "Not a Mailbox" $FoundMailboxStatisticsStatus = "Not a Mailbox" $IsMailboxEnabled = "Not a Mailbox" $Recipient = $Null Try { Write-log Warning -Message "The Script is searching for the Recipient: $UserUPN" $Recipient = Get-Recipient $UserUPN If ($Recipient) { Write-Log Info -Message "The script find the recipient $UserUPN" $FoundRecipientStatus = "Yes" $PrimarySmtpAddress = $Recipient.PrimarySmtpAddress $RecipientTypeDetails = $Recipient.RecipientTypeDetails $IsDirSynced = $Recipient.IsDirSynced $WhenMailboxCreated = $Recipient.WhenMailboxCreated $WhenSoftDeleted = $Recipient.WhenSoftDeleted $WhenCreated = $Recipient.WhenCreated } Else { Write-Log Info -Message "The script find the recipient $UserUPN" $FoundRecipientStatus = "Not a Recipient" $PrimarySmtpAddress = "Not a Recipient" $RecipientTypeDetails = "Not a Recipient" $IsDirSynced = "Not a Recipient" $WhenMailboxCreated = "Not a Recipient" $WhenSoftDeleted = "Not a Recipient" $WhenCreated = "Not a Recipient" } If ($RecipientTypeDetails -like "*Mailbox") { #Mailbox Data $IsMailboxEnabled = "No Data Found" $FoundMailboxDataStatus = "No" Try { Write-Log warning -Message "The script retreive Mailbox Data for $PrimarySmtpAddress" $MailboxData = $Null $MailboxData = Get-Mailbox $PrimarySmtpAddress $IsMailboxEnabled = $MailboxData.IsMailboxEnabled Write-Log Info -Message "The script retreived Mailbox Data for $PrimarySmtpAddress" $FoundMailboxDataStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive Mailbox Data for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxDataStatus = "Failed with Error:$ErrorMessage" } #MailboxStatistics $DeletedItemCount = "No Data Found" $ItemCount = "No Data Found" $TotalDeletedItemSize = "No Data Found" $TotalItemSize = "No Data Found" Try { Write-Log warning -Message "The script search Mailbox Statistics for $PrimarySmtpAddress" $MailboxStatistics = Get-EXOMailboxStatistics $PrimarySmtpAddress $DeletedItemCount = $MailboxStatistics.DeletedItemCount $ItemCount = $MailboxStatistics.ItemCount $TotalDeletedItemSize = $MailboxStatistics.TotalDeletedItemSize $TotalItemSize = $MailboxStatistics.TotalItemSize Write-Log Info -Message "The script found Mailbox Statistics info for $PrimarySmtpAddress" $FoundMailboxStatisticsStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Retreive MailboxStatistics for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxStatisticsStatus = "Failed with Error:$ErrorMessage" $DeletedItemCount = "Failed" $ItemCount = "Failed" $TotalDeletedItemSize = "Failed" $TotalItemSize = "Failed" } #Mailbox Permissions $MailboxPermissionUsers = "No Data Found" $MailboxPermissionAccessRights = "No Data Found" $RecipientPermissionTrustees = "No Data Found" $RecipientPermissionAccessRights = "No Data Found" Try { Write-Log warning -Message "The script search Mailbox Permissions for $PrimarySmtpAddress" $EXORecipientPermissions = Get-EXORecipientPermission $PrimarySmtpAddress $EXOMailboxPermissions = Get-EXOMailboxPermission $PrimarySmtpAddress $MailboxPermissionUsers = $EXOMailboxPermissions.User -join ";" $MailboxPermissionAccessRights = $EXOMailboxPermissions.AccessRights -join ";" $RecipientPermissionTrustees = $EXORecipientPermissions.Trustee -join ";" $RecipientPermissionAccessRights = $EXORecipientPermissions.AccessRights -join ";" Write-Log Info -Message "The script found Mailbox Permissions info for $PrimarySmtpAddress" $FoundMailboxStatisticsStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Retreive MailboxStatistics for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxStatisticsStatus = "Failed with Error:$ErrorMessage" $MailboxPermissionUsers = "Failed" $MailboxPermissionAccessRights = "Failed" $RecipientPermissionTrustees = "Failed" $RecipientPermissionAccessRights = "Failed" } } Else { $DeletedItemCount = "Not a Mailbox" $ItemCount = "Not a Mailbox" $TotalDeletedItemSize = "Not a Mailbox" $TotalItemSize = "Not a Mailbox" $MailboxPermissionUsers = "Not a Mailbox" $MailboxPermissionAccessRights = "Not a Mailbox" $RecipientPermissionTrustees = "Not a Mailbox" $RecipientPermissionAccessRights = "Not a Mailbox" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to find MgUser $UserUPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundRecipientStatus = "Failed with Error:$ErrorMessage" } $UsersInfo += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Tittle = $Tittle; Department = $Department; AccountEnabled = $AccountEnabled; Mail = $Mail; UserPrincipalName = $UserPrincipalName; LastSuccessfulSignInDateTime = $LastSuccessfulSignInDateTime; LastNonInteractiveSignInDateTime = $LastNonInteractiveSignInDateTime; LastSignInDateTime = $LastSignInDateTime; SignInSessionsValidFromDateTime = $SignInSessionsValidFromDateTime; RefreshTokensValidFromDateTime = $RefreshTokensValidFromDateTime; LastPasswordChangeDateTime = $LastPasswordChangeDateTime; OnPremisesDistinguishedName = $OnPremisesDistinguishedName; OnPremisesImmutableId = $OnPremisesImmutableId; OnPremisesLastSyncDateTime = $OnPremisesLastSyncDateTime; OnPremisesSamAccountName = $OnPremisesSamAccountName; OnPremisesSyncEnabled = $OnPremisesSyncEnabled; OnPremisesUserPrincipalName = $OnPremisesUserPrincipalName; OnPremisesExtensionAttributes_ExtensionAttribute1 = $OnPremisesExtensionAttributes_ExtensionAttribute1; OnPremisesExtensionAttributes_ExtensionAttribute2 = $OnPremisesExtensionAttributes_ExtensionAttribute2; OnPremisesExtensionAttributes_ExtensionAttribute3 = $OnPremisesExtensionAttributes_ExtensionAttribute3; OnPremisesExtensionAttributes_ExtensionAttribute4 = $OnPremisesExtensionAttributes_ExtensionAttribute4; OnPremisesExtensionAttributes_ExtensionAttribute5 = $OnPremisesExtensionAttributes_ExtensionAttribute5; OnPremisesExtensionAttributes_ExtensionAttribute6 = $OnPremisesExtensionAttributes_ExtensionAttribute6; OnPremisesExtensionAttributes_ExtensionAttribute7 = $OnPremisesExtensionAttributes_ExtensionAttribute7; OnPremisesExtensionAttributes_ExtensionAttribute8 = $OnPremisesExtensionAttributes_ExtensionAttribute8; OnPremisesExtensionAttributes_ExtensionAttribute9 = $OnPremisesExtensionAttributes_ExtensionAttribute9; OnPremisesExtensionAttributes_ExtensionAttribute10 = $OnPremisesExtensionAttributes_ExtensionAttribute10; OnPremisesExtensionAttributes_ExtensionAttribute11 = $OnPremisesExtensionAttributes_ExtensionAttribute11; OnPremisesExtensionAttributes_ExtensionAttribute12 = $OnPremisesExtensionAttributes_ExtensionAttribute12; OnPremisesExtensionAttributes_ExtensionAttribute13 = $OnPremisesExtensionAttributes_ExtensionAttribute13; OnPremisesExtensionAttributes_ExtensionAttribute14 = $OnPremisesExtensionAttributes_ExtensionAttribute14; OnPremisesExtensionAttributes_ExtensionAttribute15 = $OnPremisesExtensionAttributes_ExtensionAttribute15; CreatedDateTime = $CreatedDateTime; MailNickname = $MailNickname; UserType = $UserType; Licenses = $Licenses; FoundRecipient = $FoundRecipientStatus; PrimarySmtpAddress = $PrimarySmtpAddress; RecipientTypeDetails = $RecipientTypeDetails; IsDirSynced = $IsDirSynced; IsMailboxEnabled = $IsMailboxEnabled; WhenMailboxCreated = $WhenMailboxCreated; WhenSoftDeleted = $WhenSoftDeleted; WhenCreated = $WhenCreated; FoundMailboxStatistics = $FoundMailboxStatisticsStatus; DeletedItemCount = $DeletedItemCount; ItemCount = $ItemCount; TotalDeletedItemSize = $TotalDeletedItemSize; TotalItemSize = $TotalItemSize; MailboxPermissionUsers = $MailboxPermissionUsers; MailboxPermissionAccessRights = $MailboxPermissionAccessRights; RecipientPermissionTrustees = $RecipientPermissionTrustees; RecipientPermissionAccessRights = $RecipientPermissionAccessRights; }) $i++ } $UsersInfo | Export-Excel $ReportFile -TableName "UsersReport" -Title "Users Report" -TitleBold -WorksheetName "UsersReport" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFile" } Function Generate-MyMgUserReport { param ( [Parameter(Mandatory = $true)] [ValidateSet('All', 'Enable', 'Disable')] [String]$Type ) Read-Host "Are you Connect to MgGraph and EXO?" ############################################################################################################################################################################### #################################################################### Variable ##################################################################### ############################################################################################################################################################################### $Date = get-date -UFormat %d%m%Y $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ServerName = [Environment]::MachineName ###### Create Root Folder $RootFolder = $psscriptRoot + "\Users_Reports" ###### Create folder Variable $LogPathFolder = $RootFolder + "\Log\" $LogFile = $LogPathFolder + "Progress_" + $Date + ".log" $ReportPathFolder = $RootFolder + "\Reports\" ###### Create Folder Create-Folder $RootFolder Create-Folder $LogPathFolder Create-Folder $ReportPathFolder $Transcript_File = $LogPathFolder + "Transcript_" + $Date + ".txt" Start-Transcript -Path $Transcript_File -Append -Force ########### Initiate the Process log file when the script started ############ $Initiat_LogA = "#################### starting the Script #####################" $Startat = "### The Script has been launch at $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")" $Startwith = "The Script has been start with the following Account:" + [Environment]::UserName $Starton = "The Script has been start on the following Computer:" + [Environment]::MachineName $Initiat_LogB = "##############################################################" $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogA | Out-File -FilePath $LogFile -Append $Startat | Out-File -FilePath $LogFile -Append $Startwith | Out-File -FilePath $LogFile -Append $Starton | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append ############################################################################################################################################################################### #################################################################### Main Script ##################################################################### ############################################################################################################################################################################### #Found License Name Try { $LocalPath = ".\MapSKUID.csv" If (!(Test-Path $LocalPath)) { Write-Log warning -Message "The script Download Microsoft Licensing CSV File" $URL = "https://download.microsoft.com/download/e/3/e/e3e9faf2-f28b-490a-9ada-c6089a1fc5b0/Product%20names%20and%20service%20plan%20identifiers%20for%20licensing.csv" $LocalPath = ".\MapSKUID.csv" Invoke-WebRequest -Uri $URL -OutFile $LocalPath } Else { Write-Log warning -Message "The folder $LocalPath is already exist" } $MicrosoftSKUs = Import-Csv $LocalPath } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to download $LocalPath" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } # Found MgUsers Try { #Read-Host "The script going to retreive all users from the tenant" # All Users If ($Type -eq "All") { $Users = Get-MgUser -all -filter "usertype ne 'Guest'" -Countvariable CountVar -ConsistencyLevel eventual -Property SignInSessionsValidFromDateTime, RefreshTokensValidFromDateTime,CreatedDateTime, OnPremisesDistinguishedName, OnPremisesImmutableId, OnPremisesLastSyncDateTime, OnPremisesSamAccountName, OnPremisesSyncEnabled, OnPremisesUserPrincipalName, SignInActivity, MailNickname, UserType, AssignedLicenses, DisplayName, UserPrincipalName, JobTitle, Department, AccountEnabled, Mail, LastPasswordChangeDateTime, OnPremisesExtensionAttributes $ReportFile = $ReportPathFolder + "All_Report_Users_" + $DateFull + ".xlsx" Write-Log -Level INFO -Message "The script find All Users from the tenant" } # All Enable Users If ($Type -eq "Enable") { $Users = Get-MgUser -all -filter "accountenabled eq true and usertype ne 'Guest'" -Countvariable CountVar -ConsistencyLevel eventual -Property SignInSessionsValidFromDateTime, RefreshTokensValidFromDateTime,CreatedDateTime, OnPremisesDistinguishedName, OnPremisesImmutableId, OnPremisesLastSyncDateTime, OnPremisesSamAccountName, OnPremisesSyncEnabled, OnPremisesUserPrincipalName, SignInActivity, MailNickname, UserType, AssignedLicenses, DisplayName, UserPrincipalName, JobTitle, Department, AccountEnabled, Mail, LastPasswordChangeDateTime, OnPremisesExtensionAttributes $ReportFile = $ReportPathFolder + "Enable_Report_Users_" + $DateFull + ".xlsx" Write-Log -Level INFO -Message "The script find all Enable Users from the tenant" } # All Disabled Users If ($Type -eq "Disable") { $Users = Get-MgUser -all -filter "accountenabled eq false and usertype ne 'Guest'" -Countvariable CountVar -ConsistencyLevel eventual -Property SignInSessionsValidFromDateTime, RefreshTokensValidFromDateTime,CreatedDateTime, OnPremisesDistinguishedName, OnPremisesImmutableId, OnPremisesLastSyncDateTime, OnPremisesSamAccountName, OnPremisesSyncEnabled, OnPremisesUserPrincipalName, SignInActivity, MailNickname, UserType, AssignedLicenses, DisplayName, UserPrincipalName, JobTitle, Department, AccountEnabled, Mail, LastPasswordChangeDateTime, OnPremisesExtensionAttributes $ReportFile = $ReportPathFolder + "Disable_Report_Users_" + $DateFull + ".xlsx" Write-Log -Level INFO -Message "The script find all Disable Users from the tenant" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -LogPath $LogFile -Message "Failed to Find MgUsers" Write-Log -Level Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" Write-Log -Level Error -LogPath $LogFile -Message "The Script will stop" # Exit the script Read-Host "End of Script" } # Loop $UsersInfo = $Null $UsersInfo = @() [Int]$i = 1 $Count = ($Users | Measure).count foreach ($UserData in $Users) { $UserUPN = $UserData.UserPrincipalName Write-Log -Level warning -LogPath $LogFile -Message "The script is analyzing $UserUPN --- $i/$Count" # MgUser Write-log Warning -Message "The Script is searching for the MgUser: $UserUPN" $FoundMgUserStatus = "Yes" $LastNonInteractiveSignInDateTime = $Null $LastSignInDateTime = $Null $SignInSessionsValidFromDateTime = $Null $RefreshTokensValidFromDateTime = $Null $CreatedDateTime = $Null $OnPremisesDistinguishedName = $Null $OnPremisesImmutableId = $Null $OnPremisesLastSyncDateTime = $Null $OnPremisesSamAccountName = $Null $OnPremisesSyncEnabled = $Null $OnPremisesUserPrincipalName = $Null $MailNickname = $Null $DisplayName = $Null $UserPrincipalName = $Null $Department = $Null $Tittle = $Null $AccountEnabled = $Null $Mail = $Null $LastPasswordChangeDateTime = $Null $UserType = $Null $AssignedLicenses = $Null $Licenses = $Null $OnPremisesExtensionAttributes_ExtensionAttribute1 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute2 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute3 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute4 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute5 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute6 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute7 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute8 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute9 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute10 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute11 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute12 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute13 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute14 = $Null $OnPremisesExtensionAttributes_ExtensionAttribute15 = $Null If ($UserData.signinActivity.LastNonInteractiveSignInDateTime.DateTime) { $LastNonInteractiveSignInDateTime = Get-Date ($UserData.signinActivity.LastNonInteractiveSignInDateTime.DateTime) -Format "G" $LastNonInteractiveSignInDateTime = [datetime]::Parse($LastNonInteractiveSignInDateTime) } If ($UserData.SignInActivity.LastSignInDateTime.DateTime) { $LastSignInDateTime = Get-Date ($UserData.SignInActivity.LastSignInDateTime.DateTime) -Format "G" $LastSignInDateTime = [datetime]::Parse($LastSignInDateTime) } If ($UserData.SignInSessionsValidFromDateTime.DateTime) { $SignInSessionsValidFromDateTime = Get-Date ($UserData.SignInSessionsValidFromDateTime.DateTime) -Format "G" $SignInSessionsValidFromDateTime = [datetime]::Parse($SignInSessionsValidFromDateTime) } If ($UserData.RefreshTokensValidFromDateTime.DateTime) { $RefreshTokensValidFromDateTime = Get-Date ($UserData.RefreshTokensValidFromDateTime.DateTime) -Format "G" $RefreshTokensValidFromDateTime = [datetime]::Parse($RefreshTokensValidFromDateTime) } $OnPremisesDistinguishedName = $UserData.OnPremisesDistinguishedName $OnPremisesImmutableId = $UserData.OnPremisesImmutableId $OnPremisesLastSyncDateTime = $UserData.OnPremisesLastSyncDateTime $OnPremisesSamAccountName = $UserData.OnPremisesSamAccountName $OnPremisesSyncEnabled = $UserData.OnPremisesSyncEnabled $OnPremisesUserPrincipalName = $UserData.OnPremisesUserPrincipalName $MailNickname = $UserData.MailNickname $DisplayName = $UserData.DisplayName $UserPrincipalName = $UserData.UserPrincipalName $Department = $UserData.Department $Tittle = $UserData.JobTitle $AccountEnabled = $UserData.AccountEnabled $Mail = $UserData.Mail $LastPasswordChangeDateTime = $UserData.LastPasswordChangeDateTime $UserType = $UserData.UserType $AssignedLicenses = $UserData.AssignedLicenses $OnPremisesExtensionAttributes_ExtensionAttribute1 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute1 $OnPremisesExtensionAttributes_ExtensionAttribute2 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute2 $OnPremisesExtensionAttributes_ExtensionAttribute3 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute3 $OnPremisesExtensionAttributes_ExtensionAttribute4 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute4 $OnPremisesExtensionAttributes_ExtensionAttribute5 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute5 $OnPremisesExtensionAttributes_ExtensionAttribute6 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute6 $OnPremisesExtensionAttributes_ExtensionAttribute7 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute7 $OnPremisesExtensionAttributes_ExtensionAttribute8 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute8 $OnPremisesExtensionAttributes_ExtensionAttribute9 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute9 $OnPremisesExtensionAttributes_ExtensionAttribute10 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute10 $OnPremisesExtensionAttributes_ExtensionAttribute11 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute11 $OnPremisesExtensionAttributes_ExtensionAttribute12 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute12 $OnPremisesExtensionAttributes_ExtensionAttribute13 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute13 $OnPremisesExtensionAttributes_ExtensionAttribute14 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute14 $OnPremisesExtensionAttributes_ExtensionAttribute15 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute15 $CreatedDateTime = $UserData.CreatedDateTime $UserLicenses = @() foreach ($AssignedLicense in $AssignedLicenses) { $SkuId = $Null $SkuId = $AssignedLicense.SkuId $UserLicenses += ($MicrosoftSKUs | where { $_.GUID -eq $SkuId } | Select -first 1).Product_Display_Name } $Licenses = $UserLicenses -join ";" # Recipient $FoundRecipientStatus = "No" $DeletedItemCount = "Not a Mailbox" $ItemCount = "Not a Mailbox" $TotalDeletedItemSize = "Not a Mailbox" $TotalItemSize = "Not a Mailbox" $FoundMailboxStatisticsStatus = "Not a Mailbox" $IsMailboxEnabled = "Not a Mailbox" $Recipient = $Null $FoundRecipientStatus = "No" Try { Write-log Warning -Message "The Script is searching for the Recipient: $UserUPN" $Recipient = $Recipient = Get-Recipient $UserUPN Write-Log Info -Message "The script find the recipient $UserUPN" $FoundRecipientStatus = "Yes" $PrimarySmtpAddress = $Recipient.PrimarySmtpAddress $RecipientTypeDetails = $Recipient.RecipientTypeDetails $IsDirSynced = $Recipient.IsDirSynced $WhenMailboxCreated = $Recipient.WhenMailboxCreated $WhenSoftDeleted = $Recipient.WhenSoftDeleted $WhenCreated = $Recipient.WhenCreated $DeletedItemCount = "Not a Mailbox" $ItemCount = "Not a Mailbox" $TotalDeletedItemSize = "Not a Mailbox" $TotalItemSize = "Not a Mailbox" $FoundMailboxStatisticsStatus = "Not a Mailbox" $IsMailboxEnabled = "Not a Mailbox" If ($RecipientTypeDetails -like "*Mailbox") { #Mailbox Data $IsMailboxEnabled = "No Data Found" Try { Write-Log warning -Message "The script retreive Mailbox Data for $PrimarySmtpAddress" $MailboxData = $Null $MailboxData = Get-Mailbox $PrimarySmtpAddress $IsMailboxEnabled = $MailboxData.IsMailboxEnabled Write-Log Info -Message "The script retreived Mailbox Data for $PrimarySmtpAddress" $FoundMailboxDataStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive Mailbox Data for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxDataStatus = "Failed with Error:$ErrorMessage" } #MailboxStatistics $DeletedItemCount = "No Data Found" $ItemCount = "No Data Found" $TotalDeletedItemSize = "No Data Found" $TotalItemSize = "No Data Found" Try { Write-Log warning -Message "The script search Mailbox Statistics for $PrimarySmtpAddress" $MailboxStatistics = Get-EXOMailboxStatistics $PrimarySmtpAddress $DeletedItemCount = $MailboxStatistics.DeletedItemCount $ItemCount = $MailboxStatistics.ItemCount $TotalDeletedItemSize = $MailboxStatistics.TotalDeletedItemSize $TotalItemSize = $MailboxStatistics.TotalItemSize Write-Log Info -Message "The script found Mailbox Statistics info for $PrimarySmtpAddress" $FoundMailboxStatisticsStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Retreive MailboxStatistics for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxStatisticsStatus = "Failed with Error:$ErrorMessage" $DeletedItemCount = "Failed" $ItemCount = "Failed" $TotalDeletedItemSize = "Failed" $TotalItemSize = "Failed" } #Mailbox Permissions $MailboxPermissionUsers = "No Data Found" $MailboxPermissionAccessRights = "No Data Found" $RecipientPermissionTrustees = "No Data Found" $RecipientPermissionAccessRights = "No Data Found" Try { Write-Log warning -Message "The script search Mailbox Permissions for $PrimarySmtpAddress" $EXORecipientPermissions = Get-EXORecipientPermission $PrimarySmtpAddress $EXOMailboxPermissions = Get-EXOMailboxPermission $PrimarySmtpAddress $MailboxPermissionUsers = $EXOMailboxPermissions.User -join ";" $MailboxPermissionAccessRights = $EXOMailboxPermissions.AccessRights -join ";" $RecipientPermissionTrustees = $EXORecipientPermissions.Trustee -join ";" $RecipientPermissionAccessRights = $EXORecipientPermissions.AccessRights -join ";" Write-Log Info -Message "The script found Mailbox Permissions info for $PrimarySmtpAddress" $FoundMailboxStatisticsStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Retreive MailboxStatistics for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxStatisticsStatus = "Failed with Error:$ErrorMessage" $MailboxPermissionUsers = "Failed" $MailboxPermissionAccessRights = "Failed" $RecipientPermissionTrustees = "Failed" $RecipientPermissionAccessRights = "Failed" } } Else { $DeletedItemCount = "Not a Mailbox" $ItemCount = "Not a Mailbox" $TotalDeletedItemSize = "Not a Mailbox" $TotalItemSize = "Not a Mailbox" $MailboxPermissionUsers = "Not a Mailbox" $MailboxPermissionAccessRights = "Not a Mailbox" $RecipientPermissionTrustees = "Not a Mailbox" $RecipientPermissionAccessRights = "Not a Mailbox" } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to find MgUser $UserUPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundRecipientStatus = "Failed with Error:$ErrorMessage" } $UsersInfo += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Tittle = $Tittle; Department = $Department; AccountEnabled = $AccountEnabled; Mail = $Mail; UserPrincipalName = $UserPrincipalName; LastNonInteractiveSignInDateTime = $LastNonInteractiveSignInDateTime; LastSignInDateTime = $LastSignInDateTime; SignInSessionsValidFromDateTime = $SignInSessionsValidFromDateTime; RefreshTokensValidFromDateTime = $RefreshTokensValidFromDateTime; LastPasswordChangeDateTime = $LastPasswordChangeDateTime; OnPremisesDistinguishedName = $OnPremisesDistinguishedName; OnPremisesImmutableId = $OnPremisesImmutableId; OnPremisesLastSyncDateTime = $OnPremisesLastSyncDateTime; OnPremisesSamAccountName = $OnPremisesSamAccountName; OnPremisesSyncEnabled = $OnPremisesSyncEnabled; OnPremisesUserPrincipalName = $OnPremisesUserPrincipalName; OnPremisesExtensionAttributes_ExtensionAttribute1 = $OnPremisesExtensionAttributes_ExtensionAttribute1; OnPremisesExtensionAttributes_ExtensionAttribute2 = $OnPremisesExtensionAttributes_ExtensionAttribute2; OnPremisesExtensionAttributes_ExtensionAttribute3 = $OnPremisesExtensionAttributes_ExtensionAttribute3; OnPremisesExtensionAttributes_ExtensionAttribute4 = $OnPremisesExtensionAttributes_ExtensionAttribute4; OnPremisesExtensionAttributes_ExtensionAttribute5 = $OnPremisesExtensionAttributes_ExtensionAttribute5; OnPremisesExtensionAttributes_ExtensionAttribute6 = $OnPremisesExtensionAttributes_ExtensionAttribute6; OnPremisesExtensionAttributes_ExtensionAttribute7 = $OnPremisesExtensionAttributes_ExtensionAttribute7; OnPremisesExtensionAttributes_ExtensionAttribute8 = $OnPremisesExtensionAttributes_ExtensionAttribute8; OnPremisesExtensionAttributes_ExtensionAttribute9 = $OnPremisesExtensionAttributes_ExtensionAttribute9; OnPremisesExtensionAttributes_ExtensionAttribute10 = $OnPremisesExtensionAttributes_ExtensionAttribute10; OnPremisesExtensionAttributes_ExtensionAttribute11 = $OnPremisesExtensionAttributes_ExtensionAttribute11; OnPremisesExtensionAttributes_ExtensionAttribute12 = $OnPremisesExtensionAttributes_ExtensionAttribute12; OnPremisesExtensionAttributes_ExtensionAttribute13 = $OnPremisesExtensionAttributes_ExtensionAttribute13; OnPremisesExtensionAttributes_ExtensionAttribute14 = $OnPremisesExtensionAttributes_ExtensionAttribute14; OnPremisesExtensionAttributes_ExtensionAttribute15 = $OnPremisesExtensionAttributes_ExtensionAttribute15; CreatedDateTime = $CreatedDateTime; MailNickname = $MailNickname; UserType = $UserType; Licenses = $Licenses; FoundRecipient = $FoundRecipientStatus; PrimarySmtpAddress = $PrimarySmtpAddress; RecipientTypeDetails = $RecipientTypeDetails; IsDirSynced = $IsDirSynced; IsMailboxEnabled = $IsMailboxEnabled; WhenMailboxCreated = $WhenMailboxCreated; WhenSoftDeleted = $WhenSoftDeleted; WhenCreated = $WhenCreated; FoundMailboxStatistics = $FoundMailboxStatisticsStatus; DeletedItemCount = $DeletedItemCount; ItemCount = $ItemCount; TotalDeletedItemSize = $TotalDeletedItemSize; TotalItemSize = $TotalItemSize; MailboxPermissionUsers = $MailboxPermissionUsers; MailboxPermissionAccessRights = $MailboxPermissionAccessRights; RecipientPermissionTrustees = $RecipientPermissionTrustees; RecipientPermissionAccessRights = $RecipientPermissionAccessRights; }) $i++ } $UsersInfo | Export-Excel $ReportFile -TableName "UsersReport" -Title "Users Report" -TitleBold -WorksheetName "UsersReport" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFile" } Function Disable-UserMailboxForDepartureUsingCSV { param ( [Parameter(Mandatory = $true, Position = 1)] [String]$CSVFile, [Parameter(Mandatory = $true, Position = 2)] [String]$Admin ) ############################################################################################################################################################################### #################################################################### Variable ##################################################################### ############################################################################################################################################################################### $Date = get-date -UFormat %d%m%Y $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ServerName = [Environment]::MachineName ###### Create Root Folder $RootFolder = $psscriptRoot + "\DisabledUsers" ###### Create folder Variable $LogPathFolder = $RootFolder + "\Log\" $LogFile = $LogPathFolder + "Progress_" + $Date + ".log" $ReportPathFolder = $RootFolder + "\Reports\" $ReportFile = $ReportPathFolder + "DisabledUsers_" + $DateFull + ".xlsx" ###### Create Folder Create-Folder $RootFolder Create-Folder $LogPathFolder Create-Folder $ReportPathFolder $Transcript_File = $LogPathFolder + "Transcript_" + $Date + ".txt" Start-Transcript -Path $Transcript_File -Append -Force ########### Initiate the Process log file when the script started ############ $Initiat_LogA = "#################### starting the Script #####################" $Startat = "### The Script has been launch at $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")" $Startwith = "The Script has been start with the following Account:" + [Environment]::UserName $Starton = "The Script has been start on the following Computer:" + [Environment]::MachineName $Initiat_LogB = "##############################################################" $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogA | Out-File -FilePath $LogFile -Append $Startat | Out-File -FilePath $LogFile -Append $Startwith | Out-File -FilePath $LogFile -Append $Starton | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append $Initiat_LogB | Out-File -FilePath $LogFile -Append ############################################################################################################################################################################### #################################################################### Main Script ##################################################################### ############################################################################################################################################################################### # Import CSVFile Try { Read-Host "Expected CSV Column: UPN" $Users = Import-Csv $CSVFile Write-Log -Level INFO -LogPath $LogFile -Message "The script import successfully :$CSVFile" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log -Level Error -LogPath $LogFile -Message "Failed to import $CSVFile " Write-Log -Level Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log -Level Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" Write-Log -Level Error -LogPath $LogFile -Message "The Script will stop" # Exit the script Read-Host "End of Script" } #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $Count = ($Users | Measure).count foreach ($User in $Users) { $Primary = $null $Primary = $User.UPN # Disable MgUser Try { Write-Log warning -LogPath $LogFile -Message "The script will Disable MgUser $Primary --- $i/$Count" Disable-MgAccount -UPN $Primary -Confirm Write-Log Info -LogPath $LogFile -Message "The script Disable MgUser $Primary" $DisabledMgUserStatus = "success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -LogPath $LogFile -Message "Failed to Disable MgUser $Primary" Write-Log Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" $DisabledMgUserStatus = "Failed with Error:$ErrorMessage" } # Get Mailbox Data Try { Write-Log warning -LogPath $LogFile -Message "The script will get $Primary to Maiblox Data" $Mailbox = $Null $Mailbox = Get-Mailbox $Primary Write-Log Info -LogPath $LogFile -Message "The script get Mailbox Data for $Primary" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -LogPath $LogFile -Message "Failed to get Mailbox Data for $Primary" Write-Log Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" $GetMailboxDataStatus = "Failed with Error:$ErrorMessage" } # Change Name Try { $DisplayName = $Null $Name = $Null $DisplayName = $Mailbox.DisplayName $Name = $Mailbox.Name $NewDisplayName = $Null $NewName = $Null $NewDisplayName = "[Disable] - " + $DisplayName $NewName = "[Disable] - " + $Name Write-Log warning -LogPath $LogFile -Message "The script will change $Primary DisplayName From $DisplayName to $NewDisplayName - Name from $Name to $NewName" Set-Mailbox $Primary -DisplayName $NewDisplayName -Name $NewName Write-Log Info -LogPath $LogFile -Message "The script changed $Primary DisplayName From $DisplayName to $NewDisplayName - Name from $Name to $NewName" $ChangeNamesStatus = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -LogPath $LogFile -Message "Failed to change $Primary DisplayName From $DisplayName to $NewDisplayName - Name from $Name to $NewName" Write-Log Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" $ChangeNamesStatus = "Failed with Error:$ErrorMessage" } # Convert to shared Try { Write-Log warning -LogPath $LogFile -Message "The script will convert $Primary to Shared mailbox" Set-Mailbox $Primary -Type Shared Write-Log Info -LogPath $LogFile -Message "The script converted $Primary to shared mailbox" $ConvertToSharedStatus = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -LogPath $LogFile -Message "Failed to convert $Primary to Shared Mailbox" Write-Log Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" $ConvertToSharedStatus = "Failed with Error:$ErrorMessage" } # Disable Mail Flow Try { Write-Log warning -LogPath $LogFile -Message "The script will disable Mail Flow for $Primary" Set-Mailbox $Primary -RequireSenderAuthenticationEnabled $True -AcceptMessagesOnlyFrom $Primary Write-Log Info -LogPath $LogFile -Message "The script disabled Mail Flow for $Primary" $DisableMailFlowStatus = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -LogPath $LogFile -Message "Failed to disable Mail Flow for $Primary" Write-Log Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" $DisableMailFlowStatus = "Failed with Error:$ErrorMessage" } # Hide from the GAL Try { Write-Log warning -LogPath $LogFile -Message "The script will hide the mailbox $Primary from the GAL" Set-Mailbox $Primary -RequireSenderAuthenticationEnabled $True -HiddenFromAddressListsEnabled $True -AcceptMessagesOnlyFrom $Primary Write-Log Info -LogPath $LogFile -Message "The script hid the mailbox $Primary from the GAL" $HiddenFromGALStatus = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -LogPath $LogFile -Message "Failed to hide the mailbox $Primary from the GAL" Write-Log Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" $HiddenFromGALStatus = "Failed with Error:$ErrorMessage" } # Full Access Permission without AutoMapping Try { Write-Log warning -LogPath $LogFile -Message "The script will grant $Admin Full Access without AutoMapping to $Primary" Add-MailboxPermission -Identity $Primary -User $Admin -AccessRights FullAccess -AutoMapping:$false Write-Log Info -LogPath $LogFile -Message "The script disabled Mail Flow and hide the mailbox from the GAL" $GrantFullAccessStatus = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -LogPath $LogFile -Message "Failed to disable Mail Flow and hide the mailbox from the GAL" Write-Log Error -LogPath $LogFile -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -LogPath $LogFile -Message "Failed with Error:$ErrorMessage" $GrantFullAccessStatus = "Failed with Error:$ErrorMessage" } $Table += New-object PSobject -Property ([Ordered] @{ Primary = $Primary; DisplayName = $DisplayName; NewDisplayName = $NewDisplayName; Name = $Name; NewName = $NewName; DisabledMgUserStatus = $DisabledMgUserStatus; ChangeNamesStatus = $ChangeNamesStatus; ConvertToSharedStatus = $ConvertToSharedStatus; DisableMailFlowStatus = $DisableMailFlowStatus; HiddenFromGALStatus = $HiddenFromGALStatus; GrantFullAccessStatus = $GrantFullAccessStatus }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_DisabledUsers_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "DisabledUsers" -Title "Disabled Users" -TitleBold -WorksheetName "DisabledUsers" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -LogPath $LogFile -Message "Generate the following Report: $ReportFilexlsx" } Function Get-MgRecipientUser { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$UPN ) $MgRecipientUser = @() #Found License Name Try { $LocalPath = ".\MapSKUID.csv" If (!(Test-Path $LocalPath)) { Write-Log warning -Message "The script Download Microsoft Licensing CSV File" $URL = "https://download.microsoft.com/download/e/3/e/e3e9faf2-f28b-490a-9ada-c6089a1fc5b0/Product%20names%20and%20service%20plan%20identifiers%20for%20licensing.csv" $LocalPath = ".\MapSKUID.csv" Invoke-WebRequest -Uri $URL -OutFile $LocalPath } Else { Write-Log warning -Message "The folder $LocalPath is already exist" } $MicrosoftSKUs = Import-Csv $LocalPath } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to download $LocalPath" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } # MgUser $FoundMgUserStatus = "No" Try { Write-log Warning -Message "The Script is searching for the MgUser: $UPN" $User = Get-MgUser -UserId $UPN $UserIdentity = $User.ID $UserData = Get-MgUser -UserId $UserIdentity -Property SignInSessionsValidFromDateTime, RefreshTokensValidFromDateTime, CreatedDateTime, OnPremisesDistinguishedName, OnPremisesImmutableId, OnPremisesLastSyncDateTime, OnPremisesSamAccountName, OnPremisesSyncEnabled, OnPremisesUserPrincipalName, SignInActivity, MailNickname, UserType, AssignedLicenses, DisplayName, UserPrincipalName, JobTitle, Department, AccountEnabled, Mail, LastPasswordChangeDateTime, OnPremisesExtensionAttributes Write-Log Info -Message "The script find the MgUser $UPN (DN: $UserIdentity)" $FoundMgUserStatus = "Yes" If ($UserData.signinActivity.LastNonInteractiveSignInDateTime.DateTime) { $LastNonInteractiveSignInDateTime = Get-Date ($UserData.signinActivity.LastNonInteractiveSignInDateTime.DateTime) -Format "G" $LastNonInteractiveSignInDateTime = [datetime]::Parse($LastNonInteractiveSignInDateTime) } If ($UserData.SignInActivity.LastSignInDateTime.DateTime) { $LastSignInDateTime = Get-Date ($UserData.SignInActivity.LastSignInDateTime.DateTime) -Format "G" $LastSignInDateTime = [datetime]::Parse($LastSignInDateTime) } If ($UserData.SignInSessionsValidFromDateTime.DateTime) { $SignInSessionsValidFromDateTime = Get-Date ($UserData.SignInSessionsValidFromDateTime.DateTime) -Format "G" $SignInSessionsValidFromDateTime = [datetime]::Parse($SignInSessionsValidFromDateTime) } If ($UserData.RefreshTokensValidFromDateTime.DateTime) { $RefreshTokensValidFromDateTime = Get-Date ($UserData.RefreshTokensValidFromDateTime.DateTime) -Format "G" $RefreshTokensValidFromDateTime = [datetime]::Parse($RefreshTokensValidFromDateTime) } $OnPremisesDistinguishedName = $UserData.OnPremisesDistinguishedName $OnPremisesImmutableId = $UserData.OnPremisesImmutableId $OnPremisesLastSyncDateTime = $UserData.OnPremisesLastSyncDateTime $OnPremisesSamAccountName = $UserData.OnPremisesSamAccountName $OnPremisesSyncEnabled = $UserData.OnPremisesSyncEnabled $OnPremisesUserPrincipalName = $UserData.OnPremisesUserPrincipalName $MailNickname = $UserData.MailNickname $DisplayName = $UserData.DisplayName $UserPrincipalName = $UserData.UserPrincipalName $Department = $UserData.Department $Tittle = $UserData.JobTitle $AccountEnabled = $UserData.AccountEnabled $Mail = $UserData.Mail $LastPasswordChangeDateTime = $UserData.LastPasswordChangeDateTime $UserType = $UserData.UserType $AssignedLicenses = $UserData.AssignedLicenses $OnPremisesExtensionAttributes_ExtensionAttribute1 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute1 $OnPremisesExtensionAttributes_ExtensionAttribute2 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute2 $OnPremisesExtensionAttributes_ExtensionAttribute3 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute3 $OnPremisesExtensionAttributes_ExtensionAttribute4 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute4 $OnPremisesExtensionAttributes_ExtensionAttribute5 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute5 $OnPremisesExtensionAttributes_ExtensionAttribute6 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute6 $OnPremisesExtensionAttributes_ExtensionAttribute7 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute7 $OnPremisesExtensionAttributes_ExtensionAttribute8 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute8 $OnPremisesExtensionAttributes_ExtensionAttribute9 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute9 $OnPremisesExtensionAttributes_ExtensionAttribute10 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute10 $OnPremisesExtensionAttributes_ExtensionAttribute11 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute11 $OnPremisesExtensionAttributes_ExtensionAttribute12 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute12 $OnPremisesExtensionAttributes_ExtensionAttribute13 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute13 $OnPremisesExtensionAttributes_ExtensionAttribute14 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute14 $OnPremisesExtensionAttributes_ExtensionAttribute15 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute15 $CreatedDateTime = $UserData.CreatedDateTime $UserLicenses = @() foreach ($AssignedLicense in $AssignedLicenses) { $SkuId = $Null $SkuId = $AssignedLicense.SkuId $UserLicenses += ($MicrosoftSKUs | where { $_.GUID -eq $SkuId } | Select -first 1).Product_Display_Name } $Licenses = $UserLicenses -join ";" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to find MgUser $UPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMgUserStatus = "Failed with Error:$ErrorMessage" } # Recipient $FoundRecipientStatus = "No" Try { Write-log Warning -Message "The Script is searching for the Recipient: $UPN" $Recipient = $Recipient = Get-Recipient $UPN Write-Log Info -Message "The script find the recipient $UPN (DN: $UserIdentity)" $FoundRecipientStatus = "Yes" $PrimarySmtpAddress = $Recipient.PrimarySmtpAddress $RecipientTypeDetails = $Recipient.RecipientTypeDetails $IsDirSynced = $Recipient.IsDirSynced $WhenMailboxCreated = $Recipient.WhenMailboxCreated $WhenSoftDeleted = $Recipient.WhenSoftDeleted $WhenCreated = $Recipient.WhenCreated $DeletedItemCount = "Not a Mailbox" $ItemCount = "Not a Mailbox" $TotalDeletedItemSize = "Not a Mailbox" $TotalItemSize = "Not a Mailbox" $FoundMailboxStatisticsStatus = "Not a Mailbox" $IsMailboxEnabled = "Not a Mailbox" If ($RecipientTypeDetails -like "*Mailbox") { #Mailbox Data $IsMailboxEnabled = "No Data Found" Try { Write-Log warning -Message "The script retreive Mailbox Data for $PrimarySmtpAddress" $MailboxData = $Null $MailboxData = Get-Mailbox $PrimarySmtpAddress $IsMailboxEnabled = $MailboxData.IsMailboxEnabled Write-Log Info -Message "The script retreived Mailbox Data for $PrimarySmtpAddress" $FoundMailboxDataStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive Mailbox Data for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxDataStatus = "Failed with Error:$ErrorMessage" } #MailboxStatistics $DeletedItemCount = "No Data Found" $ItemCount = "No Data Found" $TotalDeletedItemSize = "No Data Found" $TotalItemSize = "No Data Found" Try { Write-Log warning -Message "The script search Mailbox Statistics for $PrimarySmtpAddress" $MailboxStatistics = Get-EXOMailboxStatistics $PrimarySmtpAddress $DeletedItemCount = $MailboxStatistics.DeletedItemCount $ItemCount = $MailboxStatistics.ItemCount $TotalDeletedItemSize = $MailboxStatistics.TotalDeletedItemSize $TotalItemSize = $MailboxStatistics.TotalItemSize Write-Log Info -Message "The script found Mailbox Statistics info for $PrimarySmtpAddress" $FoundMailboxStatisticsStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Retreive MailboxStatistics for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxStatisticsStatus = "Failed with Error:$ErrorMessage" $DeletedItemCount = "Failed" $ItemCount = "Failed" $TotalDeletedItemSize = "Failed" $TotalItemSize = "Failed" } #Mailbox Permissions $MailboxPermissionUsers = "No Data Found" $MailboxPermissionAccessRights = "No Data Found" $RecipientPermissionTrustees = "No Data Found" $RecipientPermissionAccessRights = "No Data Found" Try { Write-Log warning -Message "The script search Mailbox Permissions for $PrimarySmtpAddress" $EXORecipientPermissions = Get-EXORecipientPermission $PrimarySmtpAddress $EXOMailboxPermissions = Get-EXOMailboxPermission $PrimarySmtpAddress $MailboxPermissionUsers = $EXOMailboxPermissions.User -join ";" $MailboxPermissionAccessRights = $EXOMailboxPermissions.AccessRights -join ";" $RecipientPermissionTrustees = $EXORecipientPermissions.Trustee -join ";" $RecipientPermissionAccessRights = $EXORecipientPermissions.AccessRights -join ";" Write-Log Info -Message "The script found Mailbox Permissions info for $PrimarySmtpAddress" $FoundMailboxStatisticsStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Retreive MailboxStatistics for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxStatisticsStatus = "Failed with Error:$ErrorMessage" $MailboxPermissionUsers = "Failed" $MailboxPermissionAccessRights = "Failed" $RecipientPermissionTrustees = "Failed" $RecipientPermissionAccessRights = "Failed" } } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to find MgUser $UPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundRecipientStatus = "Failed with Error:$ErrorMessage" } $MgRecipientUser += New-object PSobject -Property ([Ordered] @{ UPN = $UPN; Identity = $UserIdentity; FoundMgUser = $FoundMgUserStatus; DisplayName = $DisplayName; Tittle = $Tittle; Department = $Department; AccountEnabled = $AccountEnabled; Mail = $Mail; UserPrincipalName = $UserPrincipalName; LastNonInteractiveSignInDateTime = $LastNonInteractiveSignInDateTime; LastSignInDateTime = $LastSignInDateTime; SignInSessionsValidFromDateTime = $SignInSessionsValidFromDateTime; RefreshTokensValidFromDateTime = $RefreshTokensValidFromDateTime; LastPasswordChangeDateTime = $LastPasswordChangeDateTime; OnPremisesDistinguishedName = $OnPremisesDistinguishedName; OnPremisesImmutableId = $OnPremisesImmutableId; OnPremisesLastSyncDateTime = $OnPremisesLastSyncDateTime; OnPremisesSamAccountName = $OnPremisesSamAccountName; OnPremisesSyncEnabled = $OnPremisesSyncEnabled; OnPremisesUserPrincipalName = $OnPremisesUserPrincipalName; OnPremisesExtensionAttributes_ExtensionAttribute1 = $OnPremisesExtensionAttributes_ExtensionAttribute1; OnPremisesExtensionAttributes_ExtensionAttribute2 = $OnPremisesExtensionAttributes_ExtensionAttribute2; OnPremisesExtensionAttributes_ExtensionAttribute3 = $OnPremisesExtensionAttributes_ExtensionAttribute3; OnPremisesExtensionAttributes_ExtensionAttribute4 = $OnPremisesExtensionAttributes_ExtensionAttribute4; OnPremisesExtensionAttributes_ExtensionAttribute5 = $OnPremisesExtensionAttributes_ExtensionAttribute5; OnPremisesExtensionAttributes_ExtensionAttribute6 = $OnPremisesExtensionAttributes_ExtensionAttribute6; OnPremisesExtensionAttributes_ExtensionAttribute7 = $OnPremisesExtensionAttributes_ExtensionAttribute7; OnPremisesExtensionAttributes_ExtensionAttribute8 = $OnPremisesExtensionAttributes_ExtensionAttribute8; OnPremisesExtensionAttributes_ExtensionAttribute9 = $OnPremisesExtensionAttributes_ExtensionAttribute9; OnPremisesExtensionAttributes_ExtensionAttribute10 = $OnPremisesExtensionAttributes_ExtensionAttribute10; OnPremisesExtensionAttributes_ExtensionAttribute11 = $OnPremisesExtensionAttributes_ExtensionAttribute11; OnPremisesExtensionAttributes_ExtensionAttribute12 = $OnPremisesExtensionAttributes_ExtensionAttribute12; OnPremisesExtensionAttributes_ExtensionAttribute13 = $OnPremisesExtensionAttributes_ExtensionAttribute13; OnPremisesExtensionAttributes_ExtensionAttribute14 = $OnPremisesExtensionAttributes_ExtensionAttribute14; OnPremisesExtensionAttributes_ExtensionAttribute15 = $OnPremisesExtensionAttributes_ExtensionAttribute15; CreatedDateTime = $CreatedDateTime; MailNickname = $MailNickname; UserType = $UserType; Licenses = $Licenses; FoundRecipient = $FoundRecipientStatus; PrimarySmtpAddress = $PrimarySmtpAddress; RecipientTypeDetails = $RecipientTypeDetails; IsDirSynced = $IsDirSynced; IsMailboxEnabled = $IsMailboxEnabled; WhenMailboxCreated = $WhenMailboxCreated; WhenSoftDeleted = $WhenSoftDeleted; WhenCreated = $WhenCreated; FoundMailboxStatistics = $FoundMailboxStatisticsStatus; DeletedItemCount = $DeletedItemCount; ItemCount = $ItemCount; TotalDeletedItemSize = $TotalDeletedItemSize; TotalItemSize = $TotalItemSize; MailboxPermissionUsers = $MailboxPermissionUsers; MailboxPermissionAccessRights = $MailboxPermissionAccessRights; RecipientPermissionTrustees = $RecipientPermissionTrustees; RecipientPermissionAccessRights = $RecipientPermissionAccessRights; }) Return $MgRecipientUser } Function Get-MgBetaRecipientUser { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$UPN ) $MgRecipientUser = @() #Found License Name Try { $LocalPath = ".\MapSKUID.csv" If (!(Test-Path $LocalPath)) { Write-Log warning -Message "The script Download Microsoft Licensing CSV File" $URL = "https://download.microsoft.com/download/e/3/e/e3e9faf2-f28b-490a-9ada-c6089a1fc5b0/Product%20names%20and%20service%20plan%20identifiers%20for%20licensing.csv" $LocalPath = ".\MapSKUID.csv" Invoke-WebRequest -Uri $URL -OutFile $LocalPath } Else { Write-Log warning -Message "The folder $LocalPath is already exist" } $MicrosoftSKUs = Import-Csv $LocalPath } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to download $LocalPath" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } # MgUser $FoundMgUserStatus = "No" Try { Write-log Warning -Message "The Script is searching for the MgUser: $UPN" $User = Get-MgBetaUser -UserId $UPN $UserIdentity = $User.ID $UserData = Get-MgBetaUser -UserId $UserIdentity -Property SignInSessionsValidFromDateTime, RefreshTokensValidFromDateTime,CreatedDateTime, OnPremisesDistinguishedName, OnPremisesImmutableId, OnPremisesLastSyncDateTime, OnPremisesSamAccountName, OnPremisesSyncEnabled, OnPremisesUserPrincipalName, SignInActivity, MailNickname, UserType, AssignedLicenses, DisplayName, UserPrincipalName, JobTitle, Department, AccountEnabled, Mail, LastPasswordChangeDateTime, OnPremisesExtensionAttributes Write-Log Info -Message "The script find the MgUser $UPN (DN: $UserIdentity)" $FoundMgUserStatus = "Yes" If ($UserData.signinActivity.LastNonInteractiveSignInDateTime.DateTime) { $LastNonInteractiveSignInDateTime = Get-Date ($UserData.signinActivity.LastNonInteractiveSignInDateTime.DateTime) -Format "G" $LastNonInteractiveSignInDateTime = [datetime]::Parse($LastNonInteractiveSignInDateTime) } If ($UserData.SignInActivity.LastSignInDateTime.DateTime) { $LastSignInDateTime = Get-Date ($UserData.SignInActivity.LastSignInDateTime.DateTime) -Format "G" $LastSignInDateTime = [datetime]::Parse($LastSignInDateTime) } If ($UserData.SignInActivity.LastSuccessfulSignInDateTime.DateTime) { $LastSuccessfulSignInDateTime = Get-Date ($UserData.SignInActivity.LastSuccessfulSignInDateTime.DateTime) -Format "G" $LastSuccessfulSignInDateTime = [datetime]::Parse($LastSuccessfulSignInDateTime) } If ($UserData.SignInSessionsValidFromDateTime.DateTime) { $SignInSessionsValidFromDateTime = Get-Date ($UserData.SignInSessionsValidFromDateTime.DateTime) -Format "G" $SignInSessionsValidFromDateTime = [datetime]::Parse($SignInSessionsValidFromDateTime) } If ($UserData.RefreshTokensValidFromDateTime.DateTime) { $RefreshTokensValidFromDateTime = Get-Date ($UserData.RefreshTokensValidFromDateTime.DateTime) -Format "G" $RefreshTokensValidFromDateTime = [datetime]::Parse($RefreshTokensValidFromDateTime) } $OnPremisesDistinguishedName = $UserData.OnPremisesDistinguishedName $OnPremisesImmutableId = $UserData.OnPremisesImmutableId $OnPremisesLastSyncDateTime = $UserData.OnPremisesLastSyncDateTime $OnPremisesSamAccountName = $UserData.OnPremisesSamAccountName $OnPremisesSyncEnabled = $UserData.OnPremisesSyncEnabled $OnPremisesUserPrincipalName = $UserData.OnPremisesUserPrincipalName $MailNickname = $UserData.MailNickname $DisplayName = $UserData.DisplayName $UserPrincipalName = $UserData.UserPrincipalName $Department = $UserData.Department $Tittle = $UserData.JobTitle $AccountEnabled = $UserData.AccountEnabled $Mail = $UserData.Mail $LastPasswordChangeDateTime = $UserData.LastPasswordChangeDateTime $UserType = $UserData.UserType $AssignedLicenses = $UserData.AssignedLicenses $OnPremisesExtensionAttributes_ExtensionAttribute1 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute1 $OnPremisesExtensionAttributes_ExtensionAttribute2 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute2 $OnPremisesExtensionAttributes_ExtensionAttribute3 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute3 $OnPremisesExtensionAttributes_ExtensionAttribute4 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute4 $OnPremisesExtensionAttributes_ExtensionAttribute5 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute5 $OnPremisesExtensionAttributes_ExtensionAttribute6 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute6 $OnPremisesExtensionAttributes_ExtensionAttribute7 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute7 $OnPremisesExtensionAttributes_ExtensionAttribute8 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute8 $OnPremisesExtensionAttributes_ExtensionAttribute9 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute9 $OnPremisesExtensionAttributes_ExtensionAttribute10 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute10 $OnPremisesExtensionAttributes_ExtensionAttribute11 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute11 $OnPremisesExtensionAttributes_ExtensionAttribute12 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute12 $OnPremisesExtensionAttributes_ExtensionAttribute13 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute13 $OnPremisesExtensionAttributes_ExtensionAttribute14 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute14 $OnPremisesExtensionAttributes_ExtensionAttribute15 = $UserData.OnPremisesExtensionAttributes.ExtensionAttribute15 $CreatedDateTime = $UserData.CreatedDateTime $UserLicenses = @() foreach ($AssignedLicense in $AssignedLicenses) { $SkuId = $Null $SkuId = $AssignedLicense.SkuId $UserLicenses += ($MicrosoftSKUs | where { $_.GUID -eq $SkuId } | Select -first 1).Product_Display_Name } $Licenses = $UserLicenses -join ";" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to find MgUser $UPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMgUserStatus = "Failed with Error:$ErrorMessage" } # Recipient $FoundRecipientStatus = "No" Try { Write-log Warning -Message "The Script is searching for the Recipient: $UPN" $Recipient = $Recipient = Get-Recipient $UPN Write-Log Info -Message "The script find the recipient $UPN (DN: $UserIdentity)" $FoundRecipientStatus = "Yes" $PrimarySmtpAddress = $Recipient.PrimarySmtpAddress $RecipientTypeDetails = $Recipient.RecipientTypeDetails $IsDirSynced = $Recipient.IsDirSynced $WhenMailboxCreated = $Recipient.WhenMailboxCreated $WhenSoftDeleted = $Recipient.WhenSoftDeleted $WhenCreated = $Recipient.WhenCreated $DeletedItemCount = "Not a Mailbox" $ItemCount = "Not a Mailbox" $TotalDeletedItemSize = "Not a Mailbox" $TotalItemSize = "Not a Mailbox" $FoundMailboxStatisticsStatus = "Not a Mailbox" $IsMailboxEnabled = "Not a Mailbox" If ($RecipientTypeDetails -like "*Mailbox") { #Mailbox Data $IsMailboxEnabled = "No Data Found" Try { Write-Log warning -Message "The script retreive Mailbox Data for $PrimarySmtpAddress" $MailboxData = $Null $MailboxData = Get-Mailbox $PrimarySmtpAddress $IsMailboxEnabled = $MailboxData.IsMailboxEnabled Write-Log Info -Message "The script retreived Mailbox Data for $PrimarySmtpAddress" $FoundMailboxDataStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive Mailbox Data for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxDataStatus = "Failed with Error:$ErrorMessage" } #MailboxStatistics $DeletedItemCount = "No Data Found" $ItemCount = "No Data Found" $TotalDeletedItemSize = "No Data Found" $TotalItemSize = "No Data Found" Try { Write-Log warning -Message "The script search Mailbox Statistics for $PrimarySmtpAddress" $MailboxStatistics = Get-EXOMailboxStatistics $PrimarySmtpAddress $DeletedItemCount = $MailboxStatistics.DeletedItemCount $ItemCount = $MailboxStatistics.ItemCount $TotalDeletedItemSize = $MailboxStatistics.TotalDeletedItemSize $TotalItemSize = $MailboxStatistics.TotalItemSize Write-Log Info -Message "The script found Mailbox Statistics info for $PrimarySmtpAddress" $FoundMailboxStatisticsStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Retreive MailboxStatistics for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxStatisticsStatus = "Failed with Error:$ErrorMessage" $DeletedItemCount = "Failed" $ItemCount = "Failed" $TotalDeletedItemSize = "Failed" $TotalItemSize = "Failed" } #Mailbox Permissions $MailboxPermissionUsers = "No Data Found" $MailboxPermissionAccessRights = "No Data Found" $RecipientPermissionTrustees = "No Data Found" $RecipientPermissionAccessRights = "No Data Found" Try { Write-Log warning -Message "The script search Mailbox Permissions for $PrimarySmtpAddress" $EXORecipientPermissions = Get-EXORecipientPermission $PrimarySmtpAddress $EXOMailboxPermissions = Get-EXOMailboxPermission $PrimarySmtpAddress $MailboxPermissionUsers = $EXOMailboxPermissions.User -join ";" $MailboxPermissionAccessRights = $EXOMailboxPermissions.AccessRights -join ";" $RecipientPermissionTrustees = $EXORecipientPermissions.Trustee -join ";" $RecipientPermissionAccessRights = $EXORecipientPermissions.AccessRights -join ";" Write-Log Info -Message "The script found Mailbox Permissions info for $PrimarySmtpAddress" $FoundMailboxStatisticsStatus = "Yes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Retreive MailboxStatistics for $PrimarySmtpAddress" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundMailboxStatisticsStatus = "Failed with Error:$ErrorMessage" $MailboxPermissionUsers = "Failed" $MailboxPermissionAccessRights = "Failed" $RecipientPermissionTrustees = "Failed" $RecipientPermissionAccessRights = "Failed" } } } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to find MgUser $UPN" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $FoundRecipientStatus = "Failed with Error:$ErrorMessage" } $MgRecipientUser += New-object PSobject -Property ([Ordered] @{ UPN = $UPN; Identity = $UserIdentity; FoundMgUser = $FoundMgUserStatus; DisplayName = $DisplayName; Tittle = $Tittle; Department = $Department; AccountEnabled = $AccountEnabled; Mail = $Mail; UserPrincipalName = $UserPrincipalName; LastSuccessfulSignInDateTime = $LastSuccessfulSignInDateTime; LastNonInteractiveSignInDateTime = $LastNonInteractiveSignInDateTime; LastSignInDateTime = $LastSignInDateTime; SignInSessionsValidFromDateTime = $SignInSessionsValidFromDateTime; RefreshTokensValidFromDateTime = $RefreshTokensValidFromDateTime; LastPasswordChangeDateTime = $LastPasswordChangeDateTime; OnPremisesDistinguishedName = $OnPremisesDistinguishedName; OnPremisesImmutableId = $OnPremisesImmutableId; OnPremisesLastSyncDateTime = $OnPremisesLastSyncDateTime; OnPremisesSamAccountName = $OnPremisesSamAccountName; OnPremisesSyncEnabled = $OnPremisesSyncEnabled; OnPremisesUserPrincipalName = $OnPremisesUserPrincipalName; OnPremisesExtensionAttributes_ExtensionAttribute1 = $OnPremisesExtensionAttributes_ExtensionAttribute1; OnPremisesExtensionAttributes_ExtensionAttribute2 = $OnPremisesExtensionAttributes_ExtensionAttribute2; OnPremisesExtensionAttributes_ExtensionAttribute3 = $OnPremisesExtensionAttributes_ExtensionAttribute3; OnPremisesExtensionAttributes_ExtensionAttribute4 = $OnPremisesExtensionAttributes_ExtensionAttribute4; OnPremisesExtensionAttributes_ExtensionAttribute5 = $OnPremisesExtensionAttributes_ExtensionAttribute5; OnPremisesExtensionAttributes_ExtensionAttribute6 = $OnPremisesExtensionAttributes_ExtensionAttribute6; OnPremisesExtensionAttributes_ExtensionAttribute7 = $OnPremisesExtensionAttributes_ExtensionAttribute7; OnPremisesExtensionAttributes_ExtensionAttribute8 = $OnPremisesExtensionAttributes_ExtensionAttribute8; OnPremisesExtensionAttributes_ExtensionAttribute9 = $OnPremisesExtensionAttributes_ExtensionAttribute9; OnPremisesExtensionAttributes_ExtensionAttribute10 = $OnPremisesExtensionAttributes_ExtensionAttribute10; OnPremisesExtensionAttributes_ExtensionAttribute11 = $OnPremisesExtensionAttributes_ExtensionAttribute11; OnPremisesExtensionAttributes_ExtensionAttribute12 = $OnPremisesExtensionAttributes_ExtensionAttribute12; OnPremisesExtensionAttributes_ExtensionAttribute13 = $OnPremisesExtensionAttributes_ExtensionAttribute13; OnPremisesExtensionAttributes_ExtensionAttribute14 = $OnPremisesExtensionAttributes_ExtensionAttribute14; OnPremisesExtensionAttributes_ExtensionAttribute15 = $OnPremisesExtensionAttributes_ExtensionAttribute15; CreatedDateTime = $CreatedDateTime; MailNickname = $MailNickname; UserType = $UserType; Licenses = $Licenses; FoundRecipient = $FoundRecipientStatus; PrimarySmtpAddress = $PrimarySmtpAddress; RecipientTypeDetails = $RecipientTypeDetails; IsDirSynced = $IsDirSynced; IsMailboxEnabled = $IsMailboxEnabled; WhenMailboxCreated = $WhenMailboxCreated; WhenSoftDeleted = $WhenSoftDeleted; WhenCreated = $WhenCreated; FoundMailboxStatistics = $FoundMailboxStatisticsStatus; DeletedItemCount = $DeletedItemCount; ItemCount = $ItemCount; TotalDeletedItemSize = $TotalDeletedItemSize; TotalItemSize = $TotalItemSize; MailboxPermissionUsers = $MailboxPermissionUsers; MailboxPermissionAccessRights = $MailboxPermissionAccessRights; RecipientPermissionTrustees = $RecipientPermissionTrustees; RecipientPermissionAccessRights = $RecipientPermissionAccessRights; }) Return $MgRecipientUser } Function Create-MgAccount { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String]$UserName, [Parameter(Mandatory = $true, Position = 2)] [String]$FirstName, [Parameter(Mandatory = $true, Position = 3)] [String]$LastName, [Parameter(Mandatory = $true, Position = 4)] [String]$DisplayName, [Parameter(Mandatory = $true, Position = 5)] [String]$UsageLocation, [Parameter(Mandatory = $true, Position = 6)] [String]$LicenseGroupName, [Parameter(Mandatory = $true, Position = 7)] [String]$TempPassword, [Parameter(Mandatory = $true, Position = 8)] [String]$MailNickName, [Parameter(Position = 9)] [Switch]$Confirm ) If ($Confirm) { Write-Log Warning -Message "Please make sure you are connected to MgGraph using the following Scopes Domain.ReadWrite.All, Directory.ReadWrite.All, User.ReadWrite.All, Organization.Read.All, Group.ReadWrite.All" Read-Host "Are you ready to continue?" } $PasswordProfile = @{ Password = $TempPassword } # Create Users Try { Write-Log warning -Message "The script will try to create the user: $DisplayName ($UserName)" $MgUser = $Null $MgUser = New-MgUser -DisplayName $DisplayName -GivenName $FirstName -Surname $LastName -PasswordProfile $PasswordProfile -AccountEnabled -MailNickName $MailNickName -UserPrincipalName $UserName -UsageLocation $UsageLocation $MgUserID = $Null $MgUserID = $MgUser.ID Write-Log INFO -Message "The script created the user: $DisplayName ($UserName)" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to create the user: $DisplayName ($UserName)" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } #Find License Group Try { Write-Log warning -Message "The script will try find the group $LicenseGroupName" $MgLicenseGroup = Get-MgGroup -Filter "DisplayName eq '$LicenseGroupName'" $LicenseGroupNameID = $Null $LicenseGroupNameID = $MgLicenseGroup.Id } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to find the group $LicenseGroupName" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } #Add User to license Group If ($LicenseGroupNameID) { Try { Write-Log INFO -Message "The script found $LicenseGroupName" Write-Log warning -Message "The script will try to add $DisplayName ($UserPrincipalName - $MgUserID) to $LicenseGroupName" New-MgGroupMember -GroupId $LicenseGroupNameID -DirectoryObjectId $MgUserID Write-Log INFO -Message "The script added $DisplayName ($UserPrincipalName - $MgUserID) to $LicenseGroupName" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to add $DisplayName ($UserPrincipalName - $MgUserID) to $LicenseGroupName" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } } Else { Write-Log Error -Message "Failed to find the group $LicenseGroupName" } } Function Disable-MgAccount { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$UPN, [Parameter(Position = 2)] [switch]$Confirm ) # Find User Try { $MgUser = Get-MgUser -UserId $UPN $DisplayName = $MgUser.DisplayName $UserID = $MgUser.ID Write-Host "The script find the user: $DisplayName (UPN:$UPN) with the following ObjectID: $UserID" -ForegroundColor Green If (!($Confirm)) { Read-Host "Are you sure you want to Disable the AAD Account & revoke all Azure Tokens of $DisplayName? Press Any Key to continue or CTRL+C to Cancel" } } Catch { $ErrorMessage = $Error[0].Exception.Message Write-Host "Failed with Error:$ErrorMessage" -ForegroundColor Red Write-Host "The script will stop" -ForegroundColor Red } # Disable AAD Account Try { Update-MgUser -UserId $UserID -AccountEnabled:$false Write-Host "The script disabled AAD Account $UPN" -ForegroundColor green } Catch { $ErrorMessage = $Error[0].Exception.Message; Write-Host "Failed with Error:$ErrorMessage" -ForegroundColor Red } # Revoke AAD Tokens Try { Revoke-MgUserSignInSession -UserId $UserID Write-Host "The script revoke all tokens for $UPN" -ForegroundColor Green } Catch { $ErrorMessage = $Error[0].Exception.Message; Write-Host "Failed with Error:$ErrorMessage" -ForegroundColor Red } } Function Check-MgADConnectLastSync { $MgOrganization = Get-MgOrganization | select OnPremisesLastSyncDateTime $Time = $MgOrganization.OnPremisesLastSyncDateTime $NextTime = $Time.Addminutes(30) $ToTimeZoneObj = [system.timezoneinfo]::GetSystemTimeZones() | Where-Object { $_.id -eq "Eastern Standard Time" } $TargetZoneTime = [system.timezoneinfo]::ConvertTime($Time, $ToTimeZoneObj) $NextTargetZoneTime = [system.timezoneinfo]::ConvertTime($NextTime, $ToTimeZoneObj) Write-host "The Last Synchronization was : " -NoNewline; Write-host "$TargetZoneTime" -ForegroundColor Green Write-host "The Next Synchronization will be at : " -NoNewline; Write-host "$NextTargetZoneTime" -ForegroundColor Yellow } #endregion #region Licenses #################################################### ##################### Licenses ######################## #################################################### Function Generate-MgLicenseReportPerSKU { $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" # Generate list of available licenses on the tenant $URL = "https://download.microsoft.com/download/e/3/e/e3e9faf2-f28b-490a-9ada-c6089a1fc5b0/Product%20names%20and%20service%20plan%20identifiers%20for%20licensing.csv" $LocalPath = ".\MapSKUID_" + $DateFull + ".csv" Invoke-WebRequest -Uri $URL -OutFile $LocalPath $MicrosoftSKUs = Import-Csv $LocalPath $TenantSKUs = Get-MgSubscribedSku $TenantName = $TenantSKUs.AccountName | select -First 1 $SKUs = $Null $SKUs = @() foreach ($TenantSKU in $TenantSKUs) { $TenantSKU_SkuId = $Null $TenantSKU_Name = $Null $TenantSKU_ConsumedUnits = $Null $TenantSKU_SkuPartNumber = $Null $TenantSKU_SkuId = $TenantSKU.SkuId $TenantSKU_ConsumedUnits = $TenantSKU.ConsumedUnits $TenantSKU_SkuPartNumber = $TenantSKU.SkuPartNumber $TenantSKU_Name = ($MicrosoftSKUs | where { $_.GUID -eq $TenantSKU_SkuId } | Select -first 1).Product_Display_Name $SKUs += New-object PSobject -Property ([Ordered] @{ Name = $TenantSKU_Name; ConsumedUnits = $TenantSKU_ConsumedUnits; SkuPartNumber = $TenantSKU_SkuPartNumber; SkuId = $TenantSKU_SkuId; }) } #Generate for selected SKU $SKUs | ft $SelectedSKU = $SKUs | Out-GridView -PassThru $SelectedSKUGUID = $SelectedSKU.Skuid $SelectedSKUName = $SelectedSKU.Name $SelectedSkuPartNumber = $SelectedSKU.SkuPartNumber Write-Log warning -Message "Selected SKU is: $SelectedSKUName" [Array]$MgUsers = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable Records -All -Property displayName, userPrincipalName, country, department, assignedlicenses, createdDateTime, jobTitle | Sort-Object DisplayName $Users = $Null $Users = @() Foreach ($MgUser in $MgUsers) { $displayName = $Null $userPrincipalName = $Null $country = $Null $department = $Null $assignedlicenses = $Null $createdDateTime = $Null $jobTitle = $Null $displayName = $MgUser.displayName $userPrincipalName = $MgUser.userPrincipalName $country = $MgUser.country $department = $MgUser.department $assignedlicenses = $MgUser.assignedlicenses.Skuid -join ";" $createdDateTime = $MgUser.createdDateTime $jobTitle = $MgUser.jobTitle $Users += New-object PSobject -Property ([Ordered] @{ displayName = $displayName; userPrincipalName = $userPrincipalName; country = $country; department = $department; assignedlicenses = $assignedlicenses; createdDateTime = $createdDateTime; jobTitle = $jobTitle; }) } $UsersCount = ($Users | Measure).count Write-Log warning -Message "The tenant has $UsersCount users" $LicensedUsers = $Users | where { $_.AssignedLicenses -like "*$($SelectedSKUGUID)*" } | select displayName, userPrincipalName, country, department, createdDateTime, jobTitle $LicensedUsersCount = ($LicensedUsers | Measure).count Write-Log warning -Message "The selected SKU $SelectedSKUName has $LicensedUsersCount users" $ReportFilexlsx = "LicensesReport_" + $TenantName + "_" + $SelectedSkuPartNumber + "_" + $DateFull + ".xlsx" $LicensedUsers | Export-Excel $ReportFilexlsx --TableName "AssignedLicenses" -Title "Assigned Licenses" -TitleBold -WorksheetName "AssignedLicenses" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Generate-MgLicenseReport { [CmdletBinding()] param () $URL = "https://download.microsoft.com/download/e/3/e/e3e9faf2-f28b-490a-9ada-c6089a1fc5b0/Product%20names%20and%20service%20plan%20identifiers%20for%20licensing.csv" $LocalPath = ".\MapSKUID.csv" Invoke-WebRequest -Uri $URL -OutFile $LocalPath $SKUs = $LocalPath [Array]$Users = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable Records -All -Property id, displayName, userPrincipalName, country, department, assignedlicenses, createdDateTime, jobTitle, signInActivity | Sort-Object DisplayName $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" [Int]$i = 1 $Table = $Null $Table = @() $Count = ($Users | Measure).count foreach ($User in $Users) { $DisplayName = $Null $DisplayName = $User.DisplayName $id = $Null $id = $User.id $userPrincipalName = $Null $userPrincipalName = $User.userPrincipalName $AssignedLicenses = $Null $AssignedLicenses = $User.assignedlicenses $LastSigninDateTime = $Null $LastSigninDateTime = $User.signInActivity.LastSigninDateTime $LastNonInteractiveSignInDateTime = $Null $LastNonInteractiveSignInDateTime = $User.signInActivity.LastNonInteractiveSignInDateTime $jobTitle = $Null $jobTitle = $User.jobTitle $department = $Null $department = $User.department $SKU_NameData = $Null $SKU_NameData = @() write-log warning -message "Analyzing $DisplayName ($UserprincipalName) --- $i/$Count" Foreach ($AssignedLicense in $AssignedLicenses) { $AssignedLicense_SKUID = $AssignedLicense.Skuid $SKU_NameData += ($Skus | where { $_.GUID -eq $AssignedLicense_SKUID } | Select -first 1).Product_Display_Name } $SKU_Names = $SKU_NameData -join ";" $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; userPrincipalName = $userPrincipalName; id = $id; JobTitle = $jobTitle; Department = $department; SKU_Names = $SKU_Names; LastSigninDateTime = $LastSigninDateTime; LastNonInteractiveSignInDateTime = $LastNonInteractiveSignInDateTime; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_LicensedUsers_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx --TableName "LicensedUsers" -Title "Licensed Users" -TitleBold -WorksheetName "LicensedUsers" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } #endregion #region App #################################################### ###################### Apps ######################### #################################################### Function Generate-MgReportOauthAuditReportToExcel { [CmdletBinding()] param () $MissingModules = $null $MissingModules = @() If (!(Get-InstalledModule -Name "MSIdentityTools" -ErrorAction SilentlyContinue)) { Write-Log Error -Message "MS Identity Tools Powershell module is not installed. The script will try to install the module"; $MissingModules += "Missing Powershell Module MSIdentityTools" } If (!(Get-InstalledModule -Name "ImportExcel" -ErrorAction SilentlyContinue)) { Write-Log Error -Message "ImportExcel Powershell module is not installed. The script will try to install the module"; $MissingModules += "Missing Powershell Module ImportExcel" } If ($MissingModules.count -eq 0) { Write-Log Info -Message "MSIdentityTools & ImportExcel modules are installed" Try { Write-Log warning -Message "Script will prompt to connect to your tenant using MSGraph with Application.Read.all Scope" Connect-MgGraph -Scopes Directory.Read.All -NoWelcome $MgContext = Get-MgContext $MgScopes = $MgContext.Scopes -join ";" Write-Log Info -Message "Connected to MgGraph with the following scopes: $MgScopes" Write-Log Info -Message "Script connected to your tenant using MSGraph" $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFile = "ReportAppConsentGrant_" + $DateFull + ".xlsx" Export-MsIdAppConsentGrantReport -ReportOutputType Excelworkbook -ExcelWorkbookPath $ReportFile } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to " Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $Status = "Failed" } } Else { If (!(Get-InstalledModule -Name "MSIdentityTools" -ErrorAction SilentlyContinue)) { Write-Log Error -Message "MS Identity Tools Powershell module will be installed" Install-Module -Name MSIdentityTools -SkipPublisherCheck -Scope CurrentUser -Force -AllowClobber -Confirm:$False; Write-Log info -Message "MSIdentityTools Powershell module is installed" } If (!(Get-InstalledModule -Name "ImportExcel" -ErrorAction SilentlyContinue)) { Write-Log Error -Message "ImportExcel Powershell module will be installed" Install-Module -Name ImportExcel -SkipPublisherCheck -Scope CurrentUser -Force -AllowClobber -Confirm:$False; Write-Log info -Message "ImportExcel Powershell module is installed" } Generate-ReportOauthAuditReportToExcel } } Function Generate-MgEnterpriseAppsAssignmentsConsentsSettingsReport { [CmdletBinding()] param () # Get All Enterprise Applications & App Registration $Applications = Get-MgServicePrincipal -All #Initiate the Hash Table [Int]$i = 1 $Table = $Null $Table = @() $Count = ($Applications | Measure).count ForEach ($Application in $Applications) { # Name,AppID,VisibleToUser, AssignedRequired $AccountEnabled = $Application.AccountEnabled $DisplayName = $Application.DisplayName $AppDescription = $Application.AppDescription $Description = $Application.Description $Notes = $Application.Notes $AppId = $Application.Id $AppRoleAssignmentRequired = $Application.AppRoleAssignmentRequired $LoginUrl = $Application.LoginUrl $ResourceSpecificApplicationPermissions = $Application.ResourceSpecificApplicationPermissions $ServicePrincipalType = $Application.ServicePrincipalType $SignInAudience = $Application.SignInAudience $CreatedDate = $Application.AdditionalProperties.createdDateTime Write-log Warning -message "The script is analyzing $DisplayName ….. --- $i/$Count" #Assigments (Users,Groups,SPs) to ServicePrincipals $Assignments = Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $AppId -All $AssignedUsers = $Null $AssignedUsers = @() $AssignedGroups = $Null $AssignedGroups = @() $AssignedServicePrincipals = $Null $AssignedServicePrincipals = @() $AssignedOthers = $Null $AssignedOthers = @() foreach ($Assignment in $Assignments) { $PrincipalType = $Null $PrincipalType = $Assignment.PrincipalType $PrincipalDisplayName = $Null $PrincipalDisplayName = $Assignment.PrincipalDisplayName switch ($PrincipalType) { User { $AssignedUsers += New-object PSobject -Property ([Ordered] @{ DisplayName = $PrincipalDisplayName; }) } Group { $AssignedGroups += New-object PSobject -Property ([Ordered] @{ DisplayName = $PrincipalDisplayName; }) } ServicePrincipal { $AssignedServicePrincipals += New-object PSobject -Property ([Ordered] @{ DisplayName = $PrincipalDisplayName; }) } Default { $AssignedOthers += New-object PSobject -Property ([Ordered] @{ DisplayName = $PrincipalDisplayName; }) } } } $ListAssignedUsers = $AssignedUsers.DisplayName -join ";" $ListAssignedGroups = $AssignedGroups.DisplayName -join ";" $ListAssignedServicePrincipals = $AssignedServicePrincipals.DisplayName -join ";" $ListAssignedOthers = $AssignedOthers.DisplayName -join ";" # Permissions (Delegate) $Oauth2Permissions = $Null $Oauth2Permissions = Get-MgServicePrincipalOauth2PermissionGrant -ServicePrincipalId $AppId -All if ($Oauth2Permissions) { foreach ($Oauth2Permission in $Oauth2Permissions) { $ConsentType = $Null $ConsentType = $Oauth2Permission.ConsentType If ($ConsentType -eq "AllPrincipals") { $AdminConsentScopes = $null $AdminConsentScopes = $Oauth2Permission.Scope } If ($ConsentType -eq "Principal") { $UserConsentScopes = $null $UserConsentScopes = $Oauth2Permission.Scope } } } $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; Description = $Description; Notes = $Notes; ServicePrincipalType = $ServicePrincipalType; Id = $AppId; AppRoleAssignmentRequired = $AppRoleAssignmentRequired; AccountEnabled = $AccountEnabled; SignInAudience = $SignInAudience; CreatedDate = $CreatedDate; AssignedUsers = $ListAssignedUsers; AssignedGroups = $ListAssignedGroups; AssignedServicePrincipals = $ListAssignedServicePrincipals; AssignedOthers = $ListAssignedOthers; AdminConsent = $AdminConsentScopes; UserConsent = $UserConsentScopes; }) $i++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_EnterpriseApplicationsUsage_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx -TableName "" -Title "" -TitleBold -WorksheetName "" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Generate-MgEnterpriseAppsCertificatesSecretsReport { [CmdletBinding()] param () # Connect to Graph Try { Write-Log Info -Message "The script is trying to connect to Graph with the following scope Application.ReadWrite.All" Connect-MgGraph -Scopes 'Application.ReadWrite.All' $MgContext = Get-MgContext $MgScopes = $MgContext.Scopes -join ";" Write-Log Info -Message "Connected to MgGraph with the following scopes: $MgScopes" Write-Log warning -Message "The script connected to Graph with the following scope Application.ReadWrite.All" $StatusMgConnection = "Success" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Connect to MgGraph" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $StatusMgConnection = "Failed" } # Retreive Service Principals Try { Write-Log Info -Message "The script is trying to retreive all Service Principals on the tenant" $ServicePrincipals = Get-MgServicePrincipal -all Write-Log Info -Message "The script retreived all Service Principals on the tenant" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive all Service Principals on the tenant" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" Exit } # Retreive App Registrations Try { Write-Log Info -Message "The script is trying to retreive all App Registrations on the tenant" $AppRegistrations = Get-MgApplication -all Write-Log Info -Message "The script retreived all App Registrations on the tenant" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive all App Registrations on the tenant" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } #Initiate the Hash Table [Int]$i = 1 $SPTable = $Null $SPTable = @() $SPCount = ($ServicePrincipals | Measure).count [Int]$ii = 1 $ARTable = $Null $ARTable = @() $ARCount = ($AppRegistrations | Measure).count $Now = Get-Date ForEach ($ServicePrincipal in $ServicePrincipals) { $ServicePrincipal_Name = $ServicePrincipal.DisplayName $ServicePrincipal_ID = $ServicePrincipal.Id $ServicePrincipal_AppID = $ServicePrincipal.AppId Write-log Warning -message "The script is analyzing $ServicePrincipal_Name ($ServicePrincipal_ID) ….. --- $i/$SPCount" #Owners Try { Write-Log Info -Message "The script is trying to retreive Service Principal owners for $ServicePrincipal_Name ($ServicePrincipal_ID)" $Owners = $Null $Owners = Get-MgServicePrincipalOwner -ServicePrincipalId $ServicePrincipal_ID $Usernames = $Null $Usernames = $Owners.AdditionalProperties.userPrincipalName -join ';' $OwnerIDs = $Null $OwnerIDs = $Owners.Id -join ';' Write-Log Info -Message "The script retreived Service Principal owners" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive Service Principal owners of $ServicePrincipal_Name ($ServicePrincipal_ID)" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $Usernames = $Null $OwnerIDs = $Null } # Retreive Secrets and Certificates Try { Write-Log Info -Message "The script is trying to retreive Service Principal Secrets and certificates for $ServicePrincipal_Name ($ServicePrincipal_ID )" $AppCreds = $Null Write-Log Info -Message "The script retreived Service Principals Secrets and certificates" $Secrets = $Null $Secrets = $AppCreds.PasswordCredentials $Certs = $Null $Certs = $AppCreds.KeyCredentials } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive all Service Principals Secrets and certificates" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $Secrets = $Null $Certs = $Null } # Secrets foreach ($Secret in $Secrets) { $Secret_StartDate = $Null $Secret_EndDate = $Null $Secret_SecretName = $Null $Secret_StartDate = $Secret.StartDateTime $Secret_EndDate = $Secret.EndDateTime $Secret_SecretName = $Secret.DisplayName $SPTable += New-object PSobject -Property ([Ordered] @{ 'ApplicationName' = $ServicePrincipal_Name; 'Object ID' = $ServicePrincipal_ID; 'ApplicationID' = $ServicePrincipal_AppID; 'Secret Name' = $Secret_SecretName; 'Secret Start Date' = $Secret_StartDate; 'Secret End Date' = $Secret_EndDate; 'Owners' = $Usernames; 'Owner_ObjectIDs' = $OwnerIDs; }) } # Certificates foreach ($Cert in $Certs) { $Cert_StartDate = $Null $Cert_EndDate = $Null $Cert_CertName = $Null $Cert_StartDate = $Cert.StartDateTime $Cert_EndDate = $Cert.EndDateTime $Cert_CertName = $Cert.DisplayName $SPTable += New-object PSobject -Property ([Ordered] @{ 'ApplicationName' = $ServicePrincipal_Name; 'Object ID' = $ServicePrincipal_ID; 'ApplicationID' = $ServicePrincipal_AppID; 'Certificate Name' = $Cert_CertName; 'Certificate Start Date' = $Cert_StartDate; 'Certificate End Date' = $Cert_EndDate; 'Owners' = $Usernames; 'Owner_ObjectIDs' = $OwnerIDs; }) } $i++ } ForEach ($AppRegistration in $AppRegistrations) { $AppRegistration_Name = $AppRegistration.DisplayName $AppRegistration_ID = $AppRegistration.Id $AppRegistration_AppID = $AppRegistration.AppId Write-log Warning -message "The script is analyzing $AppRegistration_Name ($AppRegistration_ID) ….. --- $i/$ARCount" #Owners Try { Write-Log Info -Message "The script is trying to retreive App Registrations owners for $AppRegistration_Name ($AppRegistration_ID)" $Owners = $Null $Owners = Get-MgApplicationOwner -ApplicationId $AppRegistration_ID $Usernames = $Null $Usernames = $Owners.AdditionalProperties.userPrincipalName -join ';' $OwnerIDs = $Null $OwnerIDs = $Owners.Id -join ';' Write-Log Info -Message "The script retreived App Registrations owners" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive App Registrations owners of $AppRegistration_Name ($AppRegistration_ID)" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $Usernames = $Null $OwnerIDs = $Null } # Retreive Secrets and Certificates Try { Write-Log Info -Message "The script is trying to retreive App Registration Secrets and certificates for $AppRegistration_Name ($AppRegistration_ID )" $AppCreds = $Null $AppCreds = Get-MgApplication -ApplicationId $AppRegistration_ID | Select-Object PasswordCredentials, KeyCredentials Write-Log Info -Message "The script retreived App Registration Secrets and certificates" $Secrets = $Null $Secrets = $AppCreds.PasswordCredentials $Certs = $Null $Certs = $AppCreds.KeyCredentials } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to retreive all App Registration Secrets and certificates" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" $Secrets = $Null $Certs = $Null } # Secrets foreach ($Secret in $Secrets) { $Secret_StartDate = $Null $Secret_EndDate = $Null $Secret_SecretName = $Null $Secret_StartDate = $Secret.StartDateTime $Secret_EndDate = $Secret.EndDateTime $Secret_SecretName = $Secret.DisplayName $ARTable += New-object PSobject -Property ([Ordered] @{ 'ApplicationName' = $AppRegistration_Name; 'Object ID' = $AppRegistration_ID; 'ApplicationID' = $AppRegistration_AppID; 'Secret Name' = $Secret_SecretName; 'Secret Start Date' = $Secret_StartDate; 'Secret End Date' = $Secret_EndDate; 'Owners' = $Usernames; 'Owner_ObjectIDs' = $OwnerIDs; }) } # Certificates foreach ($Cert in $Certs) { $Cert_StartDate = $Null $Cert_EndDate = $Null $Cert_CertName = $Null $Cert_StartDate = $Cert.StartDateTime $Cert_EndDate = $Cert.EndDateTime $Cert_CertName = $Cert.DisplayName $SPTable += New-object PSobject -Property ([Ordered] @{ 'ApplicationName' = $AppRegistration_Name; 'Object ID' = $AppRegistration_ID; 'ApplicationID' = $AppRegistration_AppID; 'Certificate Name' = $Cert_CertName; 'Certificate Start Date' = $Cert_StartDate; 'Certificate End Date' = $Cert_EndDate; 'Owners' = $Usernames; 'Owner_ObjectIDs' = $OwnerIDs; }) } $ii++ } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_ServicePrincipals_AppRegistrations_" + $DateFull + ".xlsx" $SPTable | Export-Excel $ReportFilexlsx -TableName "ServicePrincipals" -Title "Service Principals" -TitleBold -WorksheetName "ServicePrincipals" -TableStyle Medium9 -AutoSize -AutoFilter $ARTable | Export-Excel $ReportFilexlsx -TableName "AppRegistrations" -Title "App Registrations" -TitleBold -WorksheetName "AppRegistrations" -TableStyle Medium9 -AutoSize -AutoFilter -Append Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Remove-MgLegacyServicePrincipal { [CmdletBinding()] param ( [String]$ID, [String]$Name ) If ($Name) { $Filter = "DisplayName eq '" + $Name + "'" $ServicePrincipal = Get-MgServicePrincipal -Filter $Filter } Else { $ServicePrincipal = Get-MgServicePrincipal -ServicePrincipalId } $ServicePrincipal | ft $Validation = Read-Host "Are you sure you want Remove this Service Principal (Service Principal will be deleted without restore options)? Y <Yes> , N <No>" If ($Validation -eq "Y") { $servicePrincipalId = $ServicePrincipal.ID Remove-MgServicePrincipal -ServicePrincipalId $servicePrincipalId } Else { Write-Host "No Action was taken" Exit } } Function Generate-MgLegacyServicePrincipalReport { [CmdletBinding()] param () Write-Log Info -Message "The script is trying to connect to Graph with the following scope Application.ReadWrite.All" Connect-MgGraph -Scopes 'Application.ReadWrite.All' $MgContext = Get-MgContext $MgScopes = $MgContext.Scopes -join ";" Write-Log Info -Message "Connected to MgGraph with the following scopes: $MgScopes" Write-Log warning -Message "The script connected to Graph with the following scope Application.ReadWrite.All" $AllServicePrincipals = Get-MgServicePrincipal -all $LegacyServicePrincipals = $AllServicePrincipals | Where { $_.ServicePrincipalType -eq "Legacy" } $Table = $Null $Table = @() foreach ($LegacyServicePrincipal in $LegacyServicePrincipals) { $ReplyUrls = $Null $ReplyUrls = $LegacyServicePrincipal.ReplyUrls $ReplyUrls = $ReplyUrls -join ";" $DisplayName = $Null $DisplayName = $LegacyServicePrincipal.DisplayName $AppId = $Null $AppId = $LegacyServicePrincipal.AppId $Id = $Null $Id = $LegacyServicePrincipal.Id $ServicePrincipal_ServicePrincipalNames = $Null $ServicePrincipalNames = $Null $ServicePrincipal_ServicePrincipalNames = $LegacyServicePrincipal.ServicePrincipalNames $ServicePrincipalNames = $ServicePrincipal_ServicePrincipalNames -join ";" $ServicePrincipalType = $Null $ServicePrincipalType = $LegacyServicePrincipal.ServicePrincipalType $CreatedDateTime = $Null $CreatedDateTime = $LegacyServicePrincipal.AdditionalProperties.createdDateTime $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; AppId = $AppId; Id = $Id; ReplyUrls = $ReplyUrls; ServicePrincipalNames = $ServicePrincipalNames; ServicePrincipalType = $ServicePrincipalType; CreatedDateTime = $CreatedDateTime; }) } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFilexlsx = ".\Report_LegacyServicePrincipals_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx --TableName "ServicePrincipals" -Title "Legacy Service Principals" -TitleBold -WorksheetName "ServicePrincipals" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } Function Generate-MgServicePrincipalReport { [CmdletBinding()] param () Write-Log Info -Message "The script is trying to connect to Graph with the following scope Application.ReadWrite.All" Connect-MgGraph -Scopes 'Application.ReadWrite.All' $MgContext = Get-MgContext $MgScopes = $MgContext.Scopes -join ";" Write-Log Info -Message "Connected to MgGraph with the following scopes: $MgScopes" Write-Log warning -Message "The script connected to Graph with the following scope Application.ReadWrite.All" $ServicePrincipals = Get-MgServicePrincipal -all $Table = $Null $Table = @() foreach ($ServicePrincipal in $ServicePrincipals) { $ReplyUrls = $Null $ReplyUrls = $ServicePrincipal.ReplyUrls $ReplyUrls = $ReplyUrls -join ";" $DisplayName = $Null $DisplayName = $ServicePrincipal.DisplayName $AppId = $Null $AppId = $ServicePrincipal.AppId $Id = $Null $Id = $ServicePrincipal.Id $ServicePrincipal_ServicePrincipalNames = $Null $ServicePrincipalNames = $Null $ServicePrincipal_ServicePrincipalNames = $ServicePrincipal.ServicePrincipalNames $ServicePrincipalNames = $ServicePrincipal_ServicePrincipalNames -join ";" $ServicePrincipalType = $Null $ServicePrincipalType = $ServicePrincipal.ServicePrincipalType $CreatedDateTime = $Null $CreatedDateTime = $ServicePrincipal.AdditionalProperties.createdDateTime $OAuthPermissions = $Null $OAuthPermissions = $ServicePrincipal.Oauth2PermissionScopes If ($OAuthPermissions) { foreach ($OAuthPermission in $OAuthPermissions) { $IsEnabled = $Null $IsEnabled = $OAuthPermission.IsEnabled $Type = $Null $Type = $OAuthPermission.Type $Value = $Null $Value = $OAuthPermission.Value $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; AppId = $AppId; Id = $Id; ReplyUrls = $ReplyUrls; ServicePrincipalNames = $ServicePrincipalNames; ServicePrincipalType = $ServicePrincipalType; CreatedDateTime = $CreatedDateTime; OAuthPermission = $Value + ":" + $Type + "(" + $IsEnabled + ")" }) } } Else { $Table += New-object PSobject -Property ([Ordered] @{ DisplayName = $DisplayName; AppId = $AppId; Id = $Id; ReplyUrls = $ReplyUrls; ServicePrincipalNames = $ServicePrincipalNames; ServicePrincipalType = $ServicePrincipalType; CreatedDateTime = $CreatedDateTime; OAuthPermission = "no Permission" }) } } $DateFull = Get-Date -Format "ddMMyyyy_HH-mm-ss" $ReportFile = ".\Mg_ServicesPrincipals_" + $DateFull + ".csv" $Table | Export-Csv $ReportFile -NoTypeInformation -Encoding UTF8 $ReportFilexlsx = ".\Report_ServicesPrincipals_" + $DateFull + ".xlsx" $Table | Export-Excel $ReportFilexlsx --TableName "ServicePrincipals" -Title "Service Principals" -TitleBold -WorksheetName "ServicePrincipals" -TableStyle Medium9 -AutoSize -AutoFilter Write-log INFO -Message "Generate the following Report: $ReportFilexlsx" } #endregion #region AAD Function Check-MgO365GroupCreationSettings { [CmdletBinding()] param () #Read-Host 'Are you connected to MgGraph Beta? using Connect-MgGraph -Scopes "Directory.ReadWrite.All", "Group.Read.All"' $GroupUnifiedSetttings = (Get-MgBetaDirectorySetting | Where { $_.DisplayName -eq "group.unified" }).values $GroupCreationAllowedGroupId = ($GroupUnifiedSetttings | where { $_.Name -eq "GroupCreationAllowedGroupId" }).Value $EnableGroupCreation = ($GroupUnifiedSetttings | where { $_.Name -eq "EnableGroupCreation" }).Value If ($GroupCreationAllowedGroupId) { $MgGroupName = (Get-MgGroup -GroupId $GroupCreationAllowedGroupId).DisplayName Write-Host "Allowed Office 365 Group Creation Name is: " -NoNewline; Write-host "$MgGroupName" -ForegroundColor Yellow Write-Host "Office 365 Group creation is enabled: " -NoNewline; Write-host "$EnableGroupCreation" -ForegroundColor Yellow } Else { Write-Host "No Group was found:" -ForegroundColor Yellow $GroupUnifiedSetttings } } Function Block-MgO365GroupCreation { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [String]$GroupName ) if ($GroupName) { # Check if group exist Write-Host "Searching for a Group with Name: " -NoNewline; Write-host "$GroupName" -ForegroundColor Yellow $FoundMgGroup = Get-MgGroup -Filter "DisplayName eq '$GroupName'" if (!$FoundMgGroup) { Write-Host "Group with Name $GroupName was not Found" # Create Group if does not exist Write-Host "Creating a new Group with Name: " -NoNewline; Write-host "$GroupName" -ForegroundColor Green $NewMgGroup = New-MgGroup -DisplayName $GroupName -MailEnabled:$False -MailNickName $GroupName -SecurityEnabled $MgGroupObjectID = $NewMgGroup.Id } Else { Write-Host "Group with Name $GroupName already existed" -ForegroundColor Yellow $MgGroupObjectID = $FoundMgGroup.Id} } Else { # Check if group exist $FoundMgGroup = Get-MgGroup -Filter "DisplayName eq 'GroupCreationAllowedGroup'" if (!$FoundMgGroup) { Write-Host "No Group Name was provided so the script will create the following group:" -NoNewline; Write-host "GroupCreationAllowedGroup" -ForegroundColor Green # Create Group if does not exist $NewMgGroup = New-MgGroup -DisplayName $GroupName -MailEnabled:$False -MailNickName $GroupName -SecurityEnabled $MgGroupObjectID = $NewMgGroup.Id If ($NewMgGroup) { Write-Host "The Following Mg Group has been created: GroupCreationAllowedGroup" } } Else { Write-Host "No Group Name was provided but the group already exist with the following Name:" -NoNewline; Write-host "GroupCreationAllowedGroup" -ForegroundColor Red $MgGroupObjectID = $FoundMgGroup.Id } } # Update Settings $AllowGroupCreation = "False" Write-Host "Updating Group Creation Restriction Settings" -NoNewline; Write-host " - 1/2" -ForegroundColor Red $settingsObjectID = (Get-MgBetaDirectorySetting | Where-object -Property Displayname -Value "Group.Unified" -EQ).id if (!$settingsObjectID) { $DirectorySettingParameters = @{ templateId = "62375ab9-6b52-47ed-826b-58e47e0e304b" values = @( @{ name = "EnableMSStandardBlockedWords" value = "true" } ) } New-MgBetaDirectorySetting -BodyParameter $DirectorySettingParameters $settingsObjectID = (Get-MgBetaDirectorySetting | Where-object -Property Displayname -Value "Group.Unified" -EQ).Id } $NewDirectorySettingParameters = @{ templateId = "62375ab9-6b52-47ed-826b-58e47e0e304b" values = @( @{ name = "EnableGroupCreation" value = $AllowGroupCreation } @{ name = "GroupCreationAllowedGroupId" value = $MgGroupObjectID } ) } Write-Host "Updating Group Creation Restriction Settings" -NoNewline; Write-host " - 2/2" -ForegroundColor Red Update-MgBetaDirectorySetting -DirectorySettingId $settingsObjectID -BodyParameter $NewDirectorySettingParameters Check-MgO365GroupCreationSettings } Function Generate-MgConditionalAccessPoliciesReport { #Source https://github.com/Donovand4/ConditionalAccessPolicyReport/blob/master/Generate-ConditionalAccessReport.ps1 # Find Tenant Name :Microsoft.Graph.Identity.DirectoryManagement #Check if Module ImportExcel is installed If (!(Get-InstalledModule -Name ImportExcel -ErrorAction Silentlycontinue)) { Write-Log Error -Message "ImportExcel module is not installed - Please use the following CMDLet : Install-Module ImportExcel" #Start-Sleep -Seconds 10 Read-Host "Pause before closing Powershell - Please use CTRL+C to cancel" Exit } #Connect using MgGraph Try { Write-Log Warning -Message "Trying to connect to MgGraph" Connect-MgGraph -Scopes 'Policy.Read.All', 'Directory.Read.All' -NoWelcome $MgContext = Get-MgContext $MgScopes = $MgContext.Scopes -join ";" Write-Log Info -Message "Connected to MgGraph with the following scopes: $MgScopes" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to connect to MgGraph" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" #Start-Sleep -Seconds 10 Read-Host "Pause before closing Powershell - Please use CTRL+C to cancel" Exit } # Tenant Name $OnMicrosoft = (Get-MgDomain | where { $_.IsInitial }).Id $TenantName = $OnMicrosoft.Substring(0, $OnMicrosoft.IndexOf(".")) # Variable $Date = Get-Date -Format "ddMMyyyy_HH-mm-ss" $Filename = "Report_ConditionalAccessPolicies_" + $TenantName + "_" + $Date $NamedLocationsFileName = "NamedLocations - " + $TenantName + "_" + $Date $ConditionalAccessPoliciesFileName = "Backup_ConditionalAccessPolicies - " + $TenantName + "_" + $Date #Function function Report-DirectoryApps { param ( [Parameter(Mandatory = $true)] [String[]]$AppID ) ($servicePrincipals | Where-Object { $_.AppID -eq $AppID }).DisplayName } function Report-NamedLocations { param ( [Parameter(Mandatory = $true)] [String[]]$ID ) switch ($ID) { '00000000-0000-0000-0000-000000000000' { 'Unknown Site' } 'All' { 'All' } 'AllTrusted' { 'AllTrusted' } Default { ($namedLocations | Where-Object { $_.ID -eq $ID }).displayName } } } function Get-TypeOfNamedLocations { param ( [Parameter(Mandatory = $true)] [String[]]$TypeString ) switch ($TypeString) { '#microsoft.graph.ipNamedLocation' { 'ipNamedLocation' } '#microsoft.graph.countryNamedLocation' { 'countryNamedLocation' } Default { "UnknownType" } } } function Report-Users { param ( [Parameter(Mandatory = $true)] [String[]]$ID ) switch ($ID) { 'GuestsOrExternalUsers' { 'GuestsOrExternalUsers' } 'All' { 'All' } Default { $user = (Get-MgUser -UserId "$($ID)" -ErrorAction SilentlyContinue).userprincipalname if ($user) { $user } else { "LookingUpError-$($ID)" } } } } function Report-Groups { param ( [Parameter(Mandatory = $true)] [String[]]$ID ) switch ($ID) { 'GuestsOrExternalUsers' { 'GuestsOrExternalUsers' } 'All' { 'All' } Default { $group = (Get-MgGroup -GroupId "$($ID)" -ErrorAction silentlycontinue).displayname if ($group) { $group } else { "LookingUpError-$($ID)" } } } } # Collect Named Locations Try { Write-Log warning -Message "Collecting Named Locations..." $namedLocations = Get-MgIdentityConditionalAccessNamedLocation | select-object displayname, id,` @{ name = "Type"; expression = { ($_.AdditionalProperties.'@odata.type' | ForEach-Object { Get-TypeOfNamedLocations -TypeString $_ }) } },` @{ name = "isTrusted"; expression = { $_.additionalproperties.isTrusted } },` @{ name = "ipRanges"; expression = { $_.additionalproperties.ipRanges.cidrAddress -join "," } },` @{ name = "Country"; express = { $_.additionalproperties.countriesAndRegions -join "," } },` @{ name = "includeUnknownCountriesAndRegions"; expression = { $_.additionalproperties.includeUnknownCountriesAndRegions } },` @{ name = "countryLookupMethod"; expression = { $_.additionalproperties.countryLookupMethod } } Write-Log Info -Message "Named Locations have been collected" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to Collect Named Locations" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } # Collect Service Principals Try { Write-Log warning -Message "Collecting Service Principals..." $servicePrincipals = Get-MgServicePrincipal -All | Select-Object DisplayName, AppId Write-Log Info -Message " Service Principals have been collected" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to collect Service Principals" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } # Collect ConditionalAccess Policies Data Try { Write-Log warning -Message "Collecting Conditional Access Policies..." $MgConditionalAccessPolicies = Get-MgIdentityConditionalAccessPolicy -All Write-Log Info -Message "Conditional Access Policies have been collected" } Catch { $ErrorMessage = $Error[0].Exception.Message $CMDLet = $Error[0].InvocationInfo.Line $FailedItem = $Error[0].Exception.ItemName Write-Log Error -Message "Failed to collect Conditional Access Policies" Write-Log Error -Message "Failed to run the following CMDLet: $CMDLet" Write-Log Error -Message "Failed with Error:$ErrorMessage" } $Report = @() #Collects the conditional access policies using the mgconditionalaccesspolicy command. foreach ($pol in $MgConditionalAccessPolicies) { $Report += New-Object PSobject -Property @{ 'Displayname' = $pol.displayName 'Description' = $pol.Description 'State' = $pol.state 'ID' = $pol.id 'createdDateTime' = if ($pol.createdDateTime) { $pol.createdDateTime } else { 'Null' } 'ModifiedDateTime' = if ($pol.ModifiedDateTime) { $pol.ModifiedDateTime } else { 'Null' } 'UserIncludeUsers' = if ($pol.Conditions.Users.IncludeUsers) { ($pol.Conditions.Users.IncludeUsers | ForEach-Object { (Report-Users -ID $_) }) -join ',' } else { 'Not Configured' } 'UserExcludeUsers' = if ($pol.Conditions.Users.ExcludeUsers) { ($pol.Conditions.Users.ExcludeUsers | ForEach-Object { (Report-Users -ID $_) }) -join ',' } else { 'Not Configured' } 'UserIncludeGroups' = if ($pol.Conditions.Users.IncludeGroups) { ($pol.Conditions.Users.IncludeGroups | ForEach-Object { (Report-Groups -ID $_) }) -join ',' } else { 'Not Configured' } 'UserExcludeGroups' = if ($pol.Conditions.Users.ExcludeGroups) { ($pol.Conditions.Users.ExcludeGroups | ForEach-Object { (Report-Groups -ID $_) }) -join ',' } else { 'Not Configured' } 'ConditionSignInRiskLevels' = if ($pol.Conditions.SignInRiskLevels) { $pol.Conditions.SignInRiskLevels -join ',' } else { 'Not Configured' } 'ConditionClientAppTypes' = if ($pol.Conditions.ClientAppTypes) { $pol.Conditions.ClientAppTypes -join ',' } else { 'Not Configured' } 'PlatformIncludePlatforms' = if ($pol.Conditions.Platforms.IncludePlatforms) { $pol.Conditions.Platforms.IncludePlatforms -join ',' } else { 'Not Configured' } 'PlatformExcludePlatforms' = if ($pol.Conditions.Platforms.ExcludePlatforms) { $pol.Conditions.Platforms.ExcludePlatforms -join ',' } else { 'Not Configured' } 'DevicesFilterStatesMode' = if ($pol.Conditions.Devices.DeviceFilter.Mode) { $pol.Conditions.Devices.DeviceFilter.Mode -join "," } else { "Failed to Report" } 'DevicesFilterStatesRule' = if ($pol.Conditions.Devices.DeviceFilter.Rule) { $pol.Conditions.Devices.DeviceFilter.Rule -join "," } else { "Failed to Report" } 'ApplicationIncludeApplications' = if ($pol.Conditions.Applications.IncludeApplications) { ($pol.Conditions.Applications.IncludeApplications | ForEach-Object { Report-DirectoryApps -AppID $_ }) -join ',' } else { 'Not Configured' } 'ApplicationExcludeApplications' = if ($pol.Conditions.Applications.ExcludeApplications) { ($pol.Conditions.Applications.ExcludeApplications | ForEach-Object { Report-DirectoryApps -AppID $_ }) -join ',' } else { 'Not Configured' } 'ApplicationIncludeUserActions' = if ($pol.Conditions.Applications.IncludeUserActions) { $pol.Conditions.Applications.IncludeUserActions -join ',' } else { 'Not Configured' } 'LocationIncludeLocations' = if ($pol.Conditions.Locations.IncludeLocations) { ($pol.Conditions.Locations.IncludeLocations | ForEach-Object { Report-NamedLocations -ID $_ }) -join ',' } else { 'Not Configured' } 'LocationExcludeLocations' = if ($pol.Conditions.Locations.ExcludeLocations) { ($pol.Conditions.Locations.ExcludeLocations | ForEach-Object { Report-NamedLocations -ID $_ }) -join ',' } else { 'Not Configured' } 'GrantControlBuiltInControls' = if ($pol.GrantControls.BuiltInControls) { $pol.GrantControls.BuiltInControls -join ',' } else { 'Not Configured' } 'GrantControlTermsOfUse' = if ($pol.GrantControls.TermsOfUse) { $pol.GrantControls.TermsOfUse -join ',' } else { 'Not Configured' } 'GrantControlOperator' = if ($pol.GrantControls.Operator) { $pol.GrantControls.Operator } else { 'Not Configured' } 'GrantControlCustomAuthenticationFactors' = if ($pol.GrantControls.CustomAuthenticationFactors) { $pol.GrantControls.CustomAuthenticationFactors -join ',' } else { 'Not Configured' } 'CloudAppSecurityCloudAppSecurityType' = if ($pol.SessionControls.CloudAppSecurity.CloudAppSecurityType) { $pol.SessionControls.CloudAppSecurity.CloudAppSecurityType } else { 'Not Configured' } 'ApplicationEnforcedRestrictions' = if ($pol.SessionControls.ApplicationEnforcedRestrictions.IsEnabled) { $pol.SessionControls.ApplicationEnforcedRestrictions.IsEnabled } else { 'Not Configured' } 'CloudAppSecurityIsEnabled' = if ($pol.SessionControls.CloudAppSecurity.IsEnabled) { $pol.SessionControls.CloudAppSecurity.IsEnabled } else { 'Not Configured' } 'PersistentBrowserIsEnabled' = if ($pol.SessionControls.PersistentBrowser.IsEnabled) { $pol.SessionControls.PersistentBrowser.IsEnabled } else { 'Not Configured' } 'PersistentBrowserMode' = if ($pol.SessionControls.PersistentBrowser.Mode) { $pol.SessionControls.PersistentBrowser.Mode } else { 'Not Configured' } 'SignInFrequencyIsEnabled' = if ($pol.SessionControls.SignInFrequency.IsEnabled) { $pol.SessionControls.SignInFrequency.IsEnabled } else { 'Not Configured' } 'SignInFrequencyType' = if ($pol.SessionControls.SignInFrequency.Type) { $pol.SessionControls.SignInFrequency.Type } else { 'Not Configured' } 'SignInFrequencyValue' = if ($pol.SessionControls.SignInFrequency.Value) { $pol.SessionControls.SignInFrequency.Value } else { 'Not Configured' } } } Write-Log warning -Message 'Generating the Reports & backups ...' $ReportData = $Report | Select-Object -Property Displayname, Description, State, ID, createdDateTime, ModifiedDateTime, UserIncludeUsers, UserExcludeUsers, UserIncludeGroups, UserExcludeGroups, ConditionSignInRiskLevels, ConditionClientAppTypes, PlatformIncludePlatforms, PlatformExcludePlatforms, DevicesFilterStatesMode, DevicesFilterStatesRule, ApplicationIncludeApplications, ApplicationExcludeApplications, ApplicationIncludeUserActions, LocationIncludeLocations, LocationExcludeLocations, GrantControlBuiltInControls, GrantControlTermsOfUse, GrantControlOperator, GrantControlCustomAuthenticationFactors, ApplicationEnforcedRestrictions, CloudAppSecurityCloudAppSecurityType, CloudAppSecurityIsEnabled, PersistentBrowserIsEnabled, PersistentBrowserMode, SignInFrequencyIsEnabled, SignInFrequencyType, SignInFrequencyValue | Sort-Object -Property Displayname Write-Log warning -Message "Generating the Excel Reports. $($Filename.xlsx)" $ReportData | Export-excel -Path "$Filename.xlsx" Write-Log warning -Message "Generating the Excel Reports for Named locations. $($NamedLocationsFileName.xlsx)" $namedLocations | Export-excel -Path "$NamedLocationsFileName.xlsx" Write-Log warning -Message "Generating the Conditional Access policies Backup File. $($ConditionalAccessPoliciesFileName.xml)" $MgConditionalAccessPolicies | Export-Clixml "$ConditionalAccessPoliciesFileName.xml" Write-Log warning -Message 'Disconnecting from Microsoft Graph' Disconnect-MgGraph } #endregion |