How would I speed up the processing of my PowerShell script?
At the moment it takes about 1-2 hours to run 1K+ uses records, really need to speed it up.
# Must be run in Powershell 5.1 or else you can't get account creation date
# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
$maximumfunctioncount = 8192
Install-Module Microsoft.Graph -Scope CurrentUser -Force -AllowClobber
Connect-MgGraph -Scopes "Directory.Read.All","User.Read.All","AuditLog.Read.All"
Select-MgProfile -Name "Beta"
# Add a line from the variable name onwards to uncomment the license SKU
$LicenseSku = 'ENTERPRISEPACK'
# Use this to check for the license SKU
# Get-MgSubscribedSku -All -Select SkuPartNumber, SkuId, SkuPartNumber, ConsumedUnits | Format-List
# Get the assigned users details & exports as a CSV file
$licenseDetails = Get-MgSubscribedSku -All | Where SkuPartNumber -eq $LicenseSku
Get-MgUser -Filter "assignedLicenses/any(x:x/skuId eq $($licenseDetails.SkuId) )" -ConsistencyLevel eventual -All | Export-Csv -Path "C:\temp\LiceneUsers.csv"
# Imports the above CSV file
$UserCSVExtract = Import-Csv -Path "C:\temp\LiceneUsers.csv"
# This is the final CSV file that is created with the user UPN + last sign-in date + account creation date
$FinalCSVName = 'c:\temp\License CSV '+$LicenseSku + '.csv'
$Result=@()
foreach($user in $UserCSVExtract)
{
$usersignindate = Get-MgUser -UserId $user.ID -Select SignInActivity | Select -ExpandProperty SignInActivity
$userprops = [ordered]@{
UserPrincipalName = $user.UserPrincipalName
LastSignInDateTime = $usersignindate.LastSignInDateTime
AccountCreationDate = $user.CreatedDateTime
}
$userObj = new-object -Type PSObject -Property $userprops
$Result += $userObj | Export-csv -Path $FinalCSVName -Append
}
$Result
EDIT2:
#Connect to Microsoft Graph
Connect-MgGraph -scope User.Read.All, AuditLog.read.All
#Select the beta profile
Select-MgProfile -name beta
#Gather all users in tenant
$AllUsers = Get-MgUser -All
#Create a new empty array list object
$Report = [System.Collections.Generic.List[Object]]::new()
Foreach ($user in $AllUsers)
{
#Null variables
$SignInActivity = $null
$Licenses = $null
#Display progress output
Write-host "Gathering sign-in information for $($user.DisplayName)" -ForegroundColor Cyan
#Get current user information
$SignInActivitiy = Get-MgUser -UserId $user.id -Property signinactivity | Select-Object -ExpandProperty signinactivity
$licenses = (Get-MgUserLicenseDetail -UserId $User.id).SkuPartNumber -join ", "
#Create informational object to add to report
$obj = [pscustomobject][ordered]@{
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
Licenses = $licenses
LastInteractiveSignIn = $SignInActivitiy.LastSignInDateTime
LastNonInteractiveSignin = $SignInActivitiy.LastNonInteractiveSignInDateTime
}
#Add current user info to report
$report.Add($obj)
}
$report | Export-CSV -path C:\temp\Microsoft365_User_Activity-Report.csv -NoTypeInformation
You don't really need to use the Beta endpoint as signInActivity is in the v1.0 endpoint and also unless you have another need for it export the results of the first Get-MgUser to a CSV isn't required. The slowest part of you script would be the individual Get-MgUser for each user in the CSV that would create one request for every user which isn't need because you can get all the information you after from the first request. (Even if you where going to do this you would want to batch the Get-MgUser).
Eg a condensed version of what you trying to do can be done using a oneliner
[edit]