microsoftgraph / msgraph-sdk-powershell

Powershell SDK for Microsoft Graph
https://www.powershellgallery.com/packages/Microsoft.Graph
Other
704 stars 168 forks source link

Get-MgDeviceManagementReportDeviceInstallStatusReport has no -All parameter #2081

Closed andreiv3103 closed 1 year ago

andreiv3103 commented 1 year ago

I just started using the new Get-MgDeviceManagementReportDeviceInstallStatusReport cmdlet to retrieve the status of a specific app deployment. It works, but it returns only 50 devices in a call. Ho do I get all of them? I have almost 400000 devices in my deployment. I hope there is a sane solution to this and I don't have to use "skip" and "top" in a loop to get all the data. That is 8000 runs to get it all... And that wouldn't be that bad (all the others cmdlets I use to retrieve data usually run for around 1 hour to get it all) but I have to write 8000 files and read them! And this report runs daily...

DydyDelFuego commented 1 year ago

Hi,

I have exactly the same problem. If anyone has the solution please?

Regards,

timayabi2020 commented 1 year ago

@andreiv3103 @DydyDelFuego kindly share the sdk version you are using.

andreiv3103 commented 1 year ago

@andreiv3103 @DydyDelFuego kindly share the sdk version you are using.

image

andreiv3103 commented 1 year ago

For those looking for a workaround here, I ended up using the report export feature, still though the Graph API. And it works very nicely.

DydyDelFuego commented 1 year ago

Do you have an example of the request used please?

andreiv3103 commented 1 year ago

This is the PowerShell code I use to retrieve the data from the report:

$AppName = '<APPLICATION_NAME>'
$ArchiveFile = "$env:Temp\$AppName.zip"
$CsvDestination = "$env:Temp\$AppName"
$ReportsExportJobsUrl = 'https://graph.microsoft.com/beta/deviceManagement/reports/exportJobs'
$ReportsExportJobsRequestBody = ConvertTo-Json @{
    reportName = 'DeviceInstallStatusByApp'
    filter     = "(ApplicationId eq '<APPLICATION_ID>')"
    select     = @(
        'DeviceName'
        'UserPrincipalName'
        'Platform'
        'AppVersion'
        'DeviceId'
        'AssignmentFilterIdsExist'
        'LastModifiedDateTime'
        'AppInstallState'
        'AppInstallStateDetails'
        'HexErrorCode'
    )
    format     = 'csv'
    snapshotId = ''
}
# Connect to MS Graph.
Connect-MgGraph
# Trigger the report creation.
$RequestReply = Invoke-MgGraphRequest -Method 'POST' -Uri $ReportsExportJobsUrl -Body $ReportsExportJobsRequestBody
# Wait for the report to be created.
while ($ExportJobData.status -ne 'completed') {
    $ExportJobUri = "$ReportsExportJobsUrl('$($RequestReply.id)')"
    $ExportJobData = Invoke-MgGraphRequest -Method 'GET' -Uri $ExportJobUri
    Start-Sleep -Seconds 1
}
# Download the report.
Invoke-WebRequest -Uri $ExportJobData.url -OutFile $ArchiveFile
# Remove the archive destination folder, if it exists.
Remove-Item -Path $CsvDestination -Recurse -Confirm:$false -ErrorAction Ignore
# Re-crete the archive destination folder.
New-Item -Path $CsvDestination -ItemType 'Directory'
# Expand the archive.
Expand-Archive -Path $ArchiveFile -DestinationPath $CsvDestination
# Import the CSV data.
$ReturnedData = Import-Csv -Path "$CsvDestination\*.csv" -Encoding 'UTF8'
# Downloaded archive file no longer needed, so remove it.
Remove-Item -Path $ArchiveFile -Force -EA Ignore
# Also remove the archive parent folder.
Remove-Item -Path $CsvDestination -Recurse -Confirm:$false -ErrorAction Ignore

Just replace:

DydyDelFuego commented 1 year ago

Thank's i'll try it next week, thank you very much ;)

andreiv3103 commented 1 year ago

Thank's i'll try it next week, thank you very much ;)

You're welcome. If you face any issues, let me know.

DydyDelFuego commented 1 year ago

Hi @andreiv3103

Thanks. I've an error when i executed the script ->

Invoke-MgGraphRequest : POST https://graph.microsoft.com/beta/deviceManagement/reports/exportJobs HTTP/1.1 403 Forbidden Transfer-Encoding: chunked Vary: Accept-Encoding Strict-Transport-Security: max-age=31536000 request-id: 1dcef832-f75f-44b8-9c1a-804db6193cfd client-request-id: 1dcef832-f75f-44b8-9c1a-804db6193cfd x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"France Central","Slice":"E","Ring":"5","ScaleUnit":"002","RoleInstance":"PA3PEPF00005D46"}} Date: Thu, 22 Jun 2023 08:18:46 GMT Content-Encoding: gzip Content-Type: application/json {"error":{"code":"Forbidden","message":"{\r\n \"_version\": 3,\r\n \"Message\": \"Application is not authorized to perform this operation. Application must have one of the following scopes: DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All, DeviceManagementConfiguration.Read.All, DeviceManagementConfiguration.ReadWrite.All, DeviceManagementManagedDevices.Read.All, DeviceManagementManagedDevices.ReadWrite.All - Operation ID (for customer support): 00000000-0000-0000-0000-000000000000 - Activity ID: 1dcef832-f75f-44b8-9c1a-804db6193cfd - Url: https://fef.amsub0502.manage.microsoft.com/ReportingService/StatelessReportingFEService/deviceManagement/reports/exportJobs?api-version=5021-09-01\",\r\n
\"CustomApiErrorPhrase\": \"\",\r\n \"RetryAfter\": null,\r\n \"ErrorSourceService\": \"\",\r\n \"HttpHeaders\": \"{}\"\r\n}","innerError":{"date":"2023-06-22T08:18:47","request-id":"1dcef832-f75f-44b8-9c1a-804db6193cfd","client-request-id":"1dcef832-f75f-44b8-9c1a-804db6193cfd"}}} Au caractère Ligne:26 : 17

My AAD application has the following rights:

DeviceManagementApps.Read.All DeviceManagementConfiguration.Read.All DeviceManagementManagedDevices.Read.All

andreiv3103 commented 1 year ago

You don't have all the required permission to run the API query. Here is what you need: image

Read is not enough. You need Read/Write. Why, I don't know. But it doesn't work otherwise. You might try to give Read/Write permissions one by one. Maybe that not all need to be Read/Write.

DydyDelFuego commented 1 year ago

I forced the rights in the scope

Connect-MgGraph -Scopes 'DeviceManagementApps.ReadWrite.All','DeviceManagementConfiguration.ReadWrite.All','DeviceManagementManagedDevices.ReadWrite.All'

and it's work but my report is empty.. image

yet I'm supposed to have at least 1000 results :(

image

Any ideas?

andreiv3103 commented 1 year ago

Don't run the code like that. Put it in a file and run it as a script. Running code in the console like that could create issues. Copy paste my code in a notepad, fill in the app name and id, save the file with any name you want and with the .ps1 extension, open a PowerShell console and run it like this: ."FULL_PATH_TO_FILE" once it finished, call the $RetunedData variable to see if it contains any data.

DydyDelFuego commented 1 year ago

It works, thank you very much! :)

andreiv3103 commented 1 year ago

You're welcome! Glad to help.

Sembemann commented 1 year ago

This is the PowerShell code I use to retrieve the data from the report:

$AppName = '<APPLICATION_NAME>'
$ArchiveFile = "$env:Temp\$AppName.zip"
$CsvDestination = "$env:Temp\$AppName"
$ReportsExportJobsUrl = 'https://graph.microsoft.com/beta/deviceManagement/reports/exportJobs'
$ReportsExportJobsRequestBody = ConvertTo-Json @{
    reportName = 'DeviceInstallStatusByApp'
    filter     = "(ApplicationId eq '<APPLICATION_ID>')"
    select     = @(
        'DeviceName'
        'UserPrincipalName'
        'Platform'
        'AppVersion'
        'DeviceId'
        'AssignmentFilterIdsExist'
        'LastModifiedDateTime'
        'AppInstallState'
        'AppInstallStateDetails'
        'HexErrorCode'
    )
    format     = 'csv'
    snapshotId = ''
}
# Connect to MS Graph.
Connect-MgGraph
# Trigger the report creation.
$RequestReply = Invoke-MgGraphRequest -Method 'POST' -Uri $ReportsExportJobsUrl -Body $ReportsExportJobsRequestBody
# Wait for the report to be created.
while ($ExportJobData.status -ne 'completed') {
    $ExportJobUri = "$ReportsExportJobsUrl('$($RequestReply.id)')"
    $ExportJobData = Invoke-MgGraphRequest -Method 'GET' -Uri $ExportJobUri
    Start-Sleep -Seconds 1
}
# Download the report.
Invoke-WebRequest -Uri $ExportJobData.url -OutFile $ArchiveFile
# Remove the archive destination folder, if it exists.
Remove-Item -Path $CsvDestination -Recurse -Confirm:$false -ErrorAction Ignore
# Re-crete the archive destination folder.
New-Item -Path $CsvDestination -ItemType 'Directory'
# Expand the archive.
Expand-Archive -Path $ArchiveFile -DestinationPath $CsvDestination
# Import the CSV data.
$ReturnedData = Import-Csv -Path "$CsvDestination\*.csv" -Encoding 'UTF8'
# Downloaded archive file no longer needed, so remove it.
Remove-Item -Path $ArchiveFile -Force -EA Ignore
# Also remove the archive parent folder.
Remove-Item -Path $CsvDestination -Recurse -Confirm:$false -ErrorAction Ignore

Just replace:

  • <APPLICATION_NAME> with the actual application name
  • <APPLICATION_ID> with the actual application ID (without the curly brackets)
  • The data will be in the $ReturnedData variable.

Thank you for the script. It works for the first time but when I change the ApplicationID and run it again, I always receive the previous report. As if it is not created again. Did you experience the same?

Or do you have a better idea on how to efficiently iterate through all apps in intune to get their install status?

ghost commented 1 year ago

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment.