I'm working on a PowerShell script to gather information about users and the devices they use for Outlook. Given the size of our environment, querying one user at a time would take around 48 hours. To speed things up, I thought about using the -Parallel option available in PowerShell 7. The bottleneck seems to be querying the devices from Exchange, rather than the number of users. However, when I try to use the -Parallel flag in my script, I encounter an error stating that the 'Get-MobileDeviceStatistics' command is not recognized. The script runs fine without the -Parallel flag, so I could use some advice on how to resolve this issue while keeping the performance improvements. Here's the relevant code I've shared:
```powershell
$DomainUsers | ForEach-Object {
Write-Host "Querying ExchangeOnline for Device info for $($_.UserPrincipalName)"
$user = $($_)
$Manager = Get-ADUser -filter "EmployeeID -eq '$($_.extensionAttribute2)'" -properties UserPrincipalName
$MobileDeviceFD = Get-MobileDeviceStatistics -mailbox $($user.UserPrincipalName)
$MobileDeviceFD | ForEach-Object {
$MobileDeviceLD += [PSCustomObject]@{
UserEmail = $User.UserPrincipalName
EmployeeTitle = $User.extensionAttribute1
EmployeeID = $User.EmployeeID
MDM = $($_.DeviceAccessStateReason)
FriendlyName = $($_.DeviceFriendlyName)
DeviceOS = $($_.DeviceOS)
FirstSyncTime = $($_.FirstSyncTime)
ExchangeObjectID = $($_.Guid)
DeviceID = $($_.DeviceID)
LastSuccessSync = $($_.LastSuccessSync)
Manager = $Manager.UserPrincipalName
}
}
}
```
4 Answers
For using -Parallel, you'll need to ensure that the module containing `Get-MobileDeviceStatistics` is imported within the script block itself. Each iteration that's run in parallel doesn't automatically have access to modules loaded in the main session. You might also need to authenticate for each invocation, depending on how your module handles connections. It could slow things down if this query is frequent, but it’s necessary to ensure each parallel run has the proper context.
A good solution is to import the Exchange Online module directly within the script block using `Import-Module ExchangeOnlineManagement` and call `Connect-ExchangeOnline`. This ensures that each parallel function has access to the necessary commands, which should solve the error you're seeing.
Consider creating a hashtable with unique values from `extensionAttribute2` so you can pull manager data outside of the loop. This may help with performance a bit, but I agree that it might still be relatively slow compared to querying directly since Active Directory lookups can add more time.
You might want to check what module `Get-MobileDeviceStatistics` is in by running `get-command Get-MobileDeviceStatistics`. Make sure you've imported the module in your parallel sessions. If you try to run the whole querying portion in parallel without properly importing the module, you'll run into issues. Also, the way you're adding to `$MobileDeviceFD` may create unwanted behaviors; be careful about how you're accumulating data.
Related Questions
Online Hash Generator - String to Hash Converter
Convert CSV To HTML Table
Convert Json To Xml
Bitrate Converter
JavaScript Multi-line String Builder
GUID Generator