By Robert Dyjas 4 months ago • Edit this post
If you're going to restrict syncing OneDrive for Business libraries to specific domains only, you might want to first check, which domains are currently being used to synchronize data.
This is most useful if your environment consist of many different domains and/or forests. To get such data we'll be using audit log functionality in Microsoft 365 Compliance Center.
If you're not sure if it's already turned on, go to Audit page in M365 Compliance Center and check if you have the option to start recording activity:
If the button is available and the search is greyed out, you need to turn the audit log on first.
See the article about Exchange Online module for more details about installation and connecting to your environment.
View-Only Audit Logs or Audit Logs role in Exchange Online is required (source).
If your account has Global Admin (in Microsoft 365) or Organization Management (in Exchange Online), that should be enough. In the environment, where access is limited, check if the role assigned to your account has the correct permission level.
Or in the new one:
If you want to get the data once, you can go to audit log and search for Allowed computer to sync files event:
From this level you you find machine's domain data by choosing More information:
And finding MachineDomainInfo there:
You can also export the results to .csv
file. Unfortunately, it only exports basic details, without any option to include what we saw under More information.
Using Exchange Online PowerShell module you can get data on scheduled basis. You can also format your data in whatever way you prefer, so it seems pretty neat to explore that option.
Before we start, let's define some basic variables:
# Paths
$userDataFilePath = Join-Path $logFolder 'SyncEvents.xlsx'
# Cloud service account
$cloudServiceAccount = 'ServiceAccount@tenant.onmicrosoft.com'
$cloudSvcAccCredsPath = Join-Path 'C:\Scripts\Src\' "$cloudServiceAccount-creds.xml"
$cloudSvcAccCreds = Import-Clixml $cloudSvcAccCredsPath
# Set logging level
$VerbosePreference = 'Continue'
# Set how long to check in the past
$checkUntil = (Get-Date).AddDays(-1)
# Initialize
$allToBeBlocked = @()
$end = (Get-Date)
# Domains to be excluded from the report
$domainGUIDArray = @(
'11111111-aaaa-2222-3333-444444444444',
'bbbbbbbb-bc25-4436-dddd-eeeeeeeeeeee'
)
Then let's connect to Exchange Online and get some data:
Connect-ExchangeOnline -Credential $cloudSvcAccCreds
while ($end -gt $checkUntil) {
try {
# Generate session ID
$sessID = "OneDriveSyncCheck-$(Get-Random)"
$start = $end.AddHours(-1)
Write-Verbose "Checking entries to $end"
$res = $null
$params = @{
Operations = 'ManagedSyncClientAllowed'
StartDate = $start
EndDate = $end
ResultSize = 5000
SessionCommand = 'ReturnNextPreviewPage'
SessionID = $sessID
ErrorAction = 'Stop'
}
$res = Search-UnifiedAuditLog @params
Write-Verbose "Found $($res.count) entries"
$wouldBeBlocked = $res | Where-Object {
($_.AuditData | ConvertFrom-Json).MachineDomainInfo -notin $domainGUIDArray
}
$allToBeBlocked += $wouldBeBlocked | Sort-Object userids -unique | Select-Object -Property UserIds, @{n="UserAgent";e={($_.AuditData | ConvertFrom-Json).UserAgent}}, CreationDate
$mostRecentEntry = $res.CreationDate | Sort-Object | Select-Object -First 1
Write-Verbose "End date set to $mostRecentEntry"
$end = $mostRecentEntry
} catch {
# In case any errors, always worth reconnecting
Connect-ExchangeOnline -Credential $cloudSvcAccCreds
Write-Error $_
}
} # end of loop
# Paths
$userDataFilePath = Join-Path $logFolder 'SyncEvents.xlsx'
# Cloud service account
$cloudServiceAccount = 'ServiceAccount@tenant.onmicrosoft.com'
$cloudSvcAccCredsPath = Join-Path 'C:\Scripts\Src\' "$cloudServiceAccount-creds.xml"
$cloudSvcAccCreds = Import-Clixml $cloudSvcAccCredsPath
# Set logging level
$VerbosePreference = 'Continue'
We only define basic variables here, nothing special. Next, let's define time range to be checked for events. Make sure to check how long it takes to get all the data, it might depend on your tenant size:
# Set how long to check in the past
$checkUntil = (Get-Date).AddDays(-1)
# Initialize
$allToBeBlocked = @()
$end = (Get-Date)
Next, we can define an array of domains we'd like to exclude from the report. If you don't exclude anything, your list might be pretty big soon:
# Domains to be excluded from the report
$domainGUIDArray = @(
'11111111-aaaa-2222-3333-444444444444',
'bbbbbbbb-bc25-4436-dddd-eeeeeeeeeeee'
)
Then we need to connect to Exchange Online. Make sure that the sign-in method you use is suitable for unattended run. You can have a look at App-only authentication:
Connect-ExchangeOnline -Credential $cloudSvcAccCreds
And now we start our processing. We want our loop to end once it reaches certain timestamp and we wrap all the processing in try catch block for error handling:
while ($end -gt $checkUntil) {
try {
Then we generate session ID to be used while sending all the requests. See Parameters of Search-UnifiedAuditLog
for details.
For SessionCommand
we set ReturnNextPreviewPage
value, to get sorted data.
ResultSize
is set to 5000, which is maximum value.
We also need to specify ErrorAction = 'Stop'
so that we can use try/catch
block.
# Generate session ID
$sessID = "OneDriveSyncCheck-$(Get-Random)"
$start = $end.AddHours(-1)
Write-Verbose "Checking entries to $end"
$res = $null
$params = @{
Operations = 'ManagedSyncClientAllowed'
StartDate = $start
EndDate = $end
ResultSize = 5000
SessionCommand = 'ReturnNextPreviewPage'
SessionID = $sessID
ErrorAction = 'Stop'
}
Then we use splatting to run our command.
If it runs successfully, we process the data to get desired format.
Once we get data processed, we check for most recent entry and then set it as new end date for next search.
$res = Search-UnifiedAuditLog @params
Write-Verbose "Found $($res.count) entries"
$wouldBeBlocked = $res | Where-Object {
($_.AuditData | ConvertFrom-Json).MachineDomainInfo -notin $domainGUIDArray
}
$allToBeBlocked += $wouldBeBlocked | Sort-Object userids -unique | Select-Object -Property UserIds, @{n="UserAgent";e={($_.AuditData | ConvertFrom-Json).UserAgent}}, CreationDate
$mostRecentEntry = $res.CreationDate | Sort-Object | Select-Object -First 1
Write-Verbose "End date set to $mostRecentEntry"
$end = $mostRecentEntry
} catch {
As most of the errors I saw were caused by disconnected session, let's try to reconnect. Worth noting - in case any error, new value for $end
won't be set so the previous query will be executed:
# In case any errors, always worth reconnecting
Connect-ExchangeOnline -Credential $cloudSvcAccCreds
Write-Error $_
}
} # end of loop