Upload files to "/"

This commit is contained in:
2024-06-14 07:00:08 +00:00
commit 2f51b658a9

421
Intune-Set-PrimaryUser.ps1 Normal file
View File

@@ -0,0 +1,421 @@
<#PSScriptInfo
.SYNOPSIS
Script for Intune to set Primary User on Device
.DESCRIPTION
This script will get the Entra Sign in logs for Windows Sign ins
The script then determine who has logged on to the device the most times in the last 30 days and set the Primary user to that user
The script uses Ms Graph with MGGraph modules
.EXAMPLE
.\Intune-Set-PrimaryUser.ps1
Will set the primary user for devices in Intune
.NOTES
Written by Mr-Tbone (Tbone Granheden) Coligo AB
torbjorn.granheden@coligo.se
.VERSION
2.0
.RELEASENOTES
1.0 2023-02-14 Initial Build
2.0 2021-03-01 Large update to use Graph batching and reduce runtime
.AUTHOR
Tbone Granheden
@MrTbone_se
.COMPANYNAME
Coligo AB
.GUID
00000000-0000-0000-0000-000000000000
.COPYRIGHT
Feel free to use this, But would be grateful if My name is mentioned in Notes
.CHANGELOG
1.0.2202.1 - Initial Version
2.0.2312.1 - Large update to use Graph batching and reduce runtime
#>
#region ---------------------------------------------------[Set script requirements]-----------------------------------------------
#
#Requires -Modules Microsoft.Graph.Authentication
#Requires -Modules Microsoft.Graph.DeviceManagement
#Requires -Modules Microsoft.Graph.Reports
#
#endregion
#region ---------------------------------------------------[Script Parameters]-----------------------------------------------
#endregion
#region ---------------------------------------------------[Modifiable Parameters and defaults]------------------------------------
# Customizations
[System.Object]$Enrollmentaccounts = @("install@tbone.se", "wds@tbone.se") # @() = No Enrollment accounts. @("wds@tbone.se","wds2@tbone.se") = will filter them out and not assign them as primary users.
[int]$SigninsTimeSpan = 30 # Number of days back in time to look back for Sign-In logs (Default 30 days)
[int]$DeviceTimeSpan = 30 # Number of days back in time to look back for active devices (Default 30 days)
[Bool]$TestMode = $False # $True = No changes will be made on Primary owner, $False = Primary Owner will be changed
[Bool]$Verboselogging = $False # $Ture = Enable verbose logging for t-shoot. $False = Disable Verbose Logging
[Bool]$ReturnReport = $True # $True = Will return a report with all devices and primary users. $False = No report will be returned
#Batch Runtime settings
[Bool]$RunBatchMode = $true #Run the script in batch mode, faster but uses more memory, recommended for large environments
[int]$Batchsize = 20 #How many objects to process in each batch
[int]$waittime = 0 #How many seconds to wait between Batches to avoid throttling
[int]$MaxRetry = 50 #How many retries of trottled requests before error
[string[]]$DeviceGroups = @("Group1", "Group2") # Add your desired groups here
#endregion
#region ---------------------------------------------------[Set global script settings]--------------------------------------------
Set-StrictMode -Version Latest
#endregion
#region ---------------------------------------------------[Import Modules and Extensions]-----------------------------------------
import-Module Microsoft.Graph.Authentication
import-Module Microsoft.Graph.DeviceManagement
import-Module Microsoft.Graph.Reports
#endregion
#region ---------------------------------------------------[Static Variables]------------------------------------------------------
[Int64]$MemoryUsage = 0
[System.Object]$report = @()
[System.Object]$IntuneDevices = @()
[System.Object]$SignInLogs = @()
[System.Object]$AllPrimaryUsersHash = @()
[System.Object]$RequiredScopes = ("DeviceManagementManagedDevices.ReadWrite.All", "AuditLog.Read.All", "User.Read.All")
[datetime]$scriptStartTime = Get-Date
[datetime]$SignInsStartTime = (Get-Date).AddDays(-$SigninsTimeSpan )
[datetime]$DeviceStartTime = (Get-Date).AddDays(-$DeviceTimeSpan )
if ($Verboselogging) { $VerbosePreference = "Continue" }
else { $VerbosePreference = "SilentlyContinue" }
#endregion
#region ---------------------------------------------------[Functions]------------------------------------------------------------
function ConnectTo-MgGraph {
param (
[System.Object]$RequiredScopes
)
Begin {
$ErrorActionPreference = 'stop'
[String]$resourceURL = "https://graph.microsoft.com/"
$GraphAccessToken = $null
if ($env:AUTOMATION_ASSET_ACCOUNTID) { [Bool]$ManagedIdentity = $true } # Check if running in Azure Automation
else { [Bool]$ManagedIdentity = $false } # Otherwise running in Local PowerShell
}
Process {
if ($ManagedIdentity) {
#Connect to the Microsoft Graph using the ManagedIdentity and get the AccessToken
Try {
$response = [System.Text.Encoding]::Default.GetString((Invoke-WebRequest -UseBasicParsing -Uri "$($env:IDENTITY_ENDPOINT)?resource=$resourceURL" -Method 'GET' -Headers @{'X-IDENTITY-HEADER' = "$env:IDENTITY_HEADER"; 'Metadata' = 'True' }).RawContentStream.ToArray()) | ConvertFrom-Json
$GraphAccessToken = $response.access_token
Write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to get an Access Token to Graph for managed identity"
}
Catch { Write-Error "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Failed to get an Access Token to Graph for managed identity, with error: $_" }
$GraphVersion = ($GraphVersion = (Get-Module -Name 'Microsoft.Graph.Authentication' -ErrorAction SilentlyContinue).Version | Sort-Object -Desc | Select-Object -First 1)
if ('2.0.0' -le $GraphVersion) {
Try {
Connect-MgGraph -ManagedIdentity -Nowelcome
$GraphAccessToken = convertto-securestring($response.access_token) -AsPlainText -Force
Write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to connect to Graph with module 2.x and Managedidentity"
}
Catch { Write-Error "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Failed to connect to Graph with module 2.x and Managedidentity, with error: $_" }
}
else {
#Connect to the Microsoft Graph using the AccessToken
Try {
Connect-mgGraph -AccessToken $GraphAccessToken
Write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to connect to Graph with module 1.x and Managedidentity"
}
Catch { Write-Error "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Failed to connect to Graph with module 1.x and Managedidentity, with error: $_" }
}
}
else {
Try {
Connect-MgGraph -Scope $RequiredScopes -NoWelcome
Write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to connect to Graph manually"
}
Catch { Write-Error "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Failed to connect to Graph manually, with error: $_" }
}
#Check and cleanup memory after connecting to Graph
return $GraphAccessToken
}
End {
$MemoryUsage = [System.GC]::GetTotalMemory($true)
Write-Verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to cleanup Memory usage after connect to Graph to: $(($MemoryUsage/1024/1024).ToString('N2')) MB"
}
}
function get-mggraphrequestbatch {
Param(
[string]$RunProfile,
[string]$Object,
[String]$Method,
[system.object]$Objects,
[string]$Uri,
[int]$BatchSize,
[int]$WaitTime,
[int]$MaxRetry
)
Begin {
$Retrycount = 0
$CollectedObjects = [System.Collections.ArrayList]@()
$LookupHash = @{}
if ($env:AUTOMATION_ASSET_ACCOUNTID) { $ManagedIdentity = $true } # Check if running in Azure Automation
else { $ManagedIdentity = $false } # Otherwise running in Local PowerShell
}
Process {
do {
$TotalObjects = $objects.count
[int]$i = 0
$currentObject = 0
$RetryObjects = [System.Collections.ArrayList]@()
#Start looping all objects and run batches
for ($i = 0; $i -lt $TotalObjects; $i += $BatchSize) {
# Create Requests of id, method and url
[System.Object]$req = @()
if ($i + ($BatchSize - 1) -lt $TotalObjects) {
$req += ($objects[$i..($i + ($BatchSize - 1))] | Select-Object @{n = 'id'; e = { $_.id } }, @{n = 'method'; e = { 'GET' } }, @{n = 'url'; e = { "/$($Object)/$($_.id)$($uri)" } })
}
elseif ($TotalObjects -eq 1) {
$req += ($objects[$i] | Select-Object @{n = 'id'; e = { $_.id } }, @{n = 'method'; e = { 'GET' } }, @{n = 'url'; e = { "/$($Object)/$($_.id)$($uri)" } })
}
else {
$req += ($objects[$i..($TotalObjects - 1)] | Select-Object @{n = 'id'; e = { $_.id } }, @{n = 'method'; e = { 'GET' } }, @{n = 'url'; e = { "/$($Object)/$($_.id)$($uri)" } })
}
#Send the requests in a batch
$responses = invoke-mggraphrequest -Method POST `
-URI "https://graph.microsoft.com/$($RunProfile)/`$batch" `
-body (@{'requests' = $req } | convertto-json)
#Process the responses and verify status
foreach ($respons in $responses.responses) {
$CurrentObject++
switch ($respons.status) {
200 {
[void] $CollectedObjects.Add($respons)
Write-Verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to get object $($respons.id) from Graph batches"
}
403 { write-error "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Error Access denied during Graph batches - Status: $($respons.status)" }
404 { write-error "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Error Result not found during Graph batches- Status: $($respons.status)" }
429 {
[void] $RetryObjects.Add($respons)
write-warning "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Warning, Throttling occured during Graph batches- Status: $($respons.status)"
}
default {
[void] $RetryObjects.Add($respons)
write-error "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Error Other error occured during Graph batches - Status: $($respons.status)"
}
}
}
#progressbar
$Elapsedtime = (get-date) - $starttime
$timeLeft = [TimeSpan]::FromMilliseconds((($ElapsedTime.TotalMilliseconds / $CurrentObject) * ($TotalObjects - $CurrentObject)))
if (!$ManagedIdentity) {
Write-Progress -Activity "Get $($uri) $($CurrentObject) of $($TotalObjects)" `
-Status "Est Time Left: $($timeLeft.Hours) Hour, $($timeLeft.Minutes) Min, $($timeLeft.Seconds) Sek - Throttled $($retryObjects.count) - Retry $($Retrycount) of $($MaxRetry)" `
-PercentComplete $([math]::ceiling($($CurrentObject / $TotalObjects) * 100))
}
$throttledResponses = $responses.responses | Select-Object -last 20 | Where-Object { $_.status -eq "429" }
$throttledResponse = $throttledResponses | Select-Object -last 1
# | Select-Object -Property *,@{Name='HasDelay';Expression={$null -ne $_.headers."retry-after"}} | Where-Object HasDelay -eq $true
if ($throttledResponse) {
[int]$recommendedWait = ($throttledResponses.headers.'retry-after' | Measure-object -Maximum).maximum
write-warning "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Warning Throttling occured during Graph batches, Will wait the recommended $($recommendedWait+1) seconds"
Start-Sleep -Seconds ($recommendedWait + 1)
}
else { Start-Sleep -Milliseconds $WaitTime } #to avoid throttling
}
if ($RetryObjects.Count -gt 0 -and $MaxRetry -gt 0) {
$Retrycount++
$MaxRetry--
write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to start rerun batches with $($RetryObjects.Count) collected a total of $($CollectedObjects.count))"
$objects = @()
$objects = $RetryObjects
}
}While ($RetryObjects.Count -gt 0 -and $MaxRetry -gt 0)
write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success returning $($CollectedObjects.count) objects from Graph batching"
foreach ($CollectedObject in $CollectedObjects) { $LookupHash[$CollectedObject.id] = $CollectedObject }
return $LookupHash
}
End {
$MemoryUsage = [System.GC]::GetTotalMemory($true)
Write-Verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to cleanup Memory usage after Graph batching to: $(($MemoryUsage/1024/1024).ToString('N2')) MB"
}
}
function Set-IntunePrimaryUsers {
param (
[System.Object]$IntuneDevices,
[System.Object]$SignInLogs,
[System.Object]$AllPrimaryUsersHash,
[System.Object]$Enrollmentaccounts,
[Bool]$Testmode,
[Bool]$ReturnReport
)
Begin {
$ErrorActionPreference = 'stop'
[int]$i = 0
[String]$EnrollmentaccountsFilter = ($Enrollmentaccounts | ForEach-Object { [regex]::escape($_) }) -join '|'
}
Process {
[System.Object]$report = @()
Foreach ($IntuneDevice in $IntuneDevices) {
[System.Object]$SignInLogsOnDevice = $null
[System.Object]$MostFrequentUser = $null
[hashtable]$primaryuserHash = @{}
[String]$MostFrequentUserPrincipalname = $null
[String]$MostFrequentUserID = $null
[String]$primaryUser = $null
$i++
#Get current Primary User
if ($AllPrimaryUsersHash.count -gt 0) {
$PrimaryuserHash = $AllPrimaryUsersHash[$IntuneDevice.id]
$primaryUserJson = ($primaryuserHash.body.value | ConvertTo-Json -Depth 9 | ConvertFrom-Json -Depth 9)
if ($primaryUserJson -and $primaryUserJson.PSObject.Properties.Name -contains 'userprincipalname') {
$primaryuser = $primaryUserJson.userprincipalname
}
write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to get Primary User $($Primaryuser) for $($IntuneDevice.DeviceName) from batch lookup"
}
else {
try {
$primaryUser = (Get-MgDeviceManagementManagedDeviceUser -ManagedDeviceId $IntuneDevice.ID -property "UserPrincipalName").UserPrincipalName
write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to get Primary User $($Primaryuser) for device $($IntuneDevice.DeviceName) from Graph"
}
catch {
write-Warning "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Failed to get Primary User $($Primaryuser) for device $($IntuneDevice.DeviceName) from Graph with error: $_"
}
}
if (!$primaryUser) { $primaryUser = ""; write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success getting Primary user for device $($IntuneDevice.DeviceName) but device has no Primary User" }
# Get sign in logs for the device
if ($enrollmentaccounts.count -ge 1) { $SignInLogsOnDevice = $SignInLogs | Where-Object { $_.deviceid -eq $IntuneDevice.AzureAdDeviceId -and $_.userprincipalname -notmatch $EnrollmentaccountsFilter } }
else { $SignInLogsOnDevice = $SignInLogs | Where-Object { $_.deviceid -eq $IntuneDevice.AzureAdDeviceId } }
if ($SignInLogsOnDevice) { $SignInUsers = $SignInLogsOnDevice | Select-Object userprincipalname, UserId | Group-Object userprincipalname }
else {
write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Warning Device $($IntuneDevice.DeviceName) is skipped due to failing to find Sign-In logs"
if ($ReturnReport) { $report += "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Warning Device $($IntuneDevice.DeviceName) is skipped due to failing to find Sign-In logs" }
continue
}
$MostFrequentUser = $SignInUsers | Sort-Object count | Select-Object -Last 1
$MostFrequentUserPrincipalname = $MostFrequentUser.group[0].UserPrincipalName
$MostFrequentUserID = $MostFrequentUser.group[0].UserID
$IntuneDeviceID = $IntuneDevice.id
#Set primary User if needed
if (($MostFrequentUserPrincipalname) -and ($MostFrequentUserid) -and ($MostFrequentUserPrincipalname -ne $PrimaryUser)) {
write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to determine change needed on Device $($IntuneDevice.DeviceName) primaryuser from $($PrimaryUser) to $($MostFrequentUserPrincipalname)"
$uri = "https://graph.microsoft.com/beta/deviceManagement/managedDevices('$IntuneDeviceID')/users/`$ref"
$Body = @{ "@odata.id" = "https://graph.microsoft.com/beta/users/$MostFrequentUserid" } | ConvertTo-Json
$Method = "POST"
if (!$TestMode) {
try {
Invoke-MgGraphRequest -Method $Method -uri $uri -body $Body
write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to set Primary User $($MostFrequentUserPrincipalname) for device $($IntuneDevice.DeviceName)"
if ($ReturnReport) { $report += "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to set Primary User $($MostFrequentUserPrincipalname) for device $($IntuneDevice.DeviceName)" }
}
catch {
write-Warning "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Failed to set Primary User $($MostFrequentUserPrincipalname) for device $($IntuneDevice.DeviceName) with error: $_"
if ($ReturnReport) { $report += "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Failed to set Primary User $($MostFrequentUserPrincipalname) for device $($IntuneDevice.DeviceName) with error: $_" }
}
}
else {
write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Testmode - Will not set Primary User $($MostFrequentUserPrincipalname) for device $($IntuneDevice.DeviceName)"
if ($ReturnReport) { $report += "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Testmode - Will not set Primary User $($MostFrequentUserPrincipalname) for device $($IntuneDevice.DeviceName)" }
}
}
else {
if (!$MostFrequentUserPrincipalname) {
write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to determine that Device $($IntuneDevice.DeviceName) has no logins in collected logs"
if ($ReturnReport) { $report += "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to determine that Device $($IntuneDevice.DeviceName) has no logins in collected logs" }
}
else {
write-Verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to determine that Device $($IntuneDevice.DeviceName) have correct Primary User $($PrimaryUser)"
if ($ReturnReport) { $report += "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to determine that Device $($IntuneDevice.DeviceName) have correct Primary User $($PrimaryUser)" }
}
}
}
return $report
}
End {
$MemoryUsage = [System.GC]::GetTotalMemory($true)
Write-Verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to cleanup Memory usage after set Primary Users to: $(($MemoryUsage/1024/1024).ToString('N2')) MB"
}
}
#endregion
#region ---------------------------------------------------[[Script Execution]------------------------------------------------------
$StartTime = Get-Date
$MgGraphAccessToken = ConnectTo-MgGraph -RequiredScopes $RequiredScopes
# Get Intune Devices
try {
$IntuneDevices = Get-MgDeviceManagementManagedDevice -Filter "operatingSystem eq 'Windows' and LastSyncDateTime gt $($DeviceStartTime.ToString('yyyy-MM-ddTHH:mm:ssZ'))" -All -Property "AzureAdDeviceId,DeviceName,Id"
if ($DeviceGroups.Count -gt 0) {
$GroupIds = @()
foreach ($group in $DeviceGroups) {
$groupObj = Get-MgGroup -Filter "displayName eq '$group'" -Property id
if ($groupObj) {
$GroupIds += $groupObj.id
}
else {
Write-Warning "Group $group not found."
}
}
$DeviceIdsInGroups = @()
foreach ($groupId in $GroupIds) {
$devicesInGroup = Get-MgGroupMember -GroupId $groupId -All -Property id | Where-Object { $_.'@odata.type' -eq '#microsoft.graph.device' }
$DeviceIdsInGroups += $devicesInGroup.id
}
$IntuneDevices = $IntuneDevices | Where-Object { $DeviceIdsInGroups -contains $_.Id }
}
Write-Verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to get $($IntuneDevices.Count) Devices with selected properties for devices synced last $($DeviceTimeSpan) days"
}
catch {
Write-Error "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Failed to get Devices with error: $_"
}
#Memory Garbage collection
$MemoryUsage = [System.GC]::GetTotalMemory($true)
Write-Verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to cleanup Memory usage after get devices to: $(($MemoryUsage/1024/1024).ToString('N2')) MB"
#Get Sign-In logs
try {
$SignInLogs = Get-MgAuditLogSignIn -Filter "appDisplayName eq 'Windows Sign In' and CreatedDateTime gt $($SignInsStartTime.ToString("yyyy-MM-ddTHH:mm:ssZ"))" -All | Select-Object devicedetail.deviceid, userprincipalname, UserId -ExpandProperty devicedetail
write-verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to get $($SignInLogs.count) Sign-In logs with selected properties for last $($SigninsTimeSpan) days"
}
catch { write-Error "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Failed to get Sign-In logs with error: $_" }
#Memory Garbage collection
$MemoryUsage = [System.GC]::GetTotalMemory($true)
Write-Verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to cleanup Memory usage after get Sign-In logs to: $(($MemoryUsage/1024/1024).ToString('N2')) MB"
if (($IntuneDevices) -and ($SignInLogs)) {
If ($RunBatchMode) {
#Getting Primary Users in batch mode
try {
$AllPrimaryUsersHash = get-mggraphrequestbatch -RunProfile "beta" -method GET -Object "deviceManagement/managedDevices" -objects $IntuneDevices -uri "/users" -BatchSize $Batchsize -WaitTime $waittime -MaxRetry $MaxRetry
Write-Verbose "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Success to get Primary Users for $($AllPrimaryUsersHash.count) Devices"
}
catch { Write-Error "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),Failed to get Primary Users for Devices with error: $_" }
$report = Set-IntunePrimaryUsers -IntuneDevices $IntuneDevices -SignInLogs $SignInLogs -AllPrimaryUsersHash $AllPrimaryUsersHash -Enrollmentaccounts $Enrollmentaccounts -TestMode $TestMode -ReturnReport $ReturnReport
}
else {
#Getting Primary Users in foreach mode
$report = Set-IntunePrimaryUsers -IntuneDevices $IntuneDevices -SignInLogs $SignInLogs -AllPrimaryUsersHash $AllPrimaryUsersHash -Enrollmentaccounts $Enrollmentaccounts -TestMode $TestMode -ReturnReport $ReturnReport
}
}
else { write-Warning "$(Get-Date -Format 'yyyy-MM-dd'),$(Get-Date -format 'HH:mm:ss'),No Devices or Sign-In logs found, exiting script" }
if ($ReturnReport) { write-Output -InputObject $report }
disconnect-mggraph | out-null
[datetime]$scriptEndTime = Get-Date
$MemoryUsage = [System.GC]::GetTotalMemory($false)
write-Output "Script execution time: $(($scriptEndTime-$scriptStartTime).ToString('hh\:mm\:ss'))"
Write-Output "Memory Usage at the end of script execution: $(($MemoryUsage/1024/1024).ToString('N2')) MB"
$VerbosePreference = "SilentlyContinue"