Graph API
372 TopicsUse PowerShell to retrieve all assigned Intune policies and applications per Azure AD group!
==>>A special thanks to Timmy Andersson for the PowerShell script!!<<== Dear Microsoft Intune Friends, In Microsoft Intune, it is possible to work with configuration profiles, among other things. OK, this is nothing new. But which Azure Active Directory groups have been assigned to the configuration profiles? I am confronted with this question again and again. This is where PowerShell comes into play. Let's explore this together. I used the PowerShell ISE for this configuration. But you are also very welcome to use Visual Studio Code, just as you wish. Please start with the following steps to begin the deployment (the Hashtags are comments): The first two lines have nothing to do with the configuration, but make some space below in the blue part of the ISE. Set-Location C:\Temp Clear-Host #Install the module Install-Module -Name Microsoft.Graph.Intune -AllowClobber -Verbose -Force #Connect and change the scheme Connect-MSGraph -ForceInteractive Update-MSGraphEnvironment -SchemaVersion beta Connect-MSGraph #Which group do you want to check? $groupName = "AutoPilot Geräte" $Group = Get-AADGroup -Filter "displayname eq '$GroupName'" ####Config Start#### Write-host "Azure Active Directory Group: $($Group.displayName)" -ForegroundColor Green #Apps $AllAssignedApps = Get-IntuneMobileApp -Filter "isAssigned eq true" -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id} Write-host "Number of Apps found: $($AllAssignedApps.DisplayName.Count)" -ForegroundColor cyan Foreach ($Config in $AllAssignedApps) { Write-host $Config.displayName -ForegroundColor Yellow } #Device Compliance $AllDeviceCompliance = Get-IntuneDeviceCompliancePolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id} Write-host "Number of Device Compliance policies found: $($AllDeviceCompliance.DisplayName.Count)" -ForegroundColor cyan Foreach ($Config in $AllDeviceCompliance) { Write-host $Config.displayName -ForegroundColor Yellow } #Device Configuration $AllDeviceConfig = Get-IntuneDeviceConfigurationPolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id} Write-host "Number of Device Configurations found: $($AllDeviceConfig.DisplayName.Count)" -ForegroundColor cyan Foreach ($Config in $AllDeviceConfig) { Write-host $Config.displayName -ForegroundColor Yellow } #Device Configuration Powershell Scripts $Resource = "deviceManagement/deviceManagementScripts" $graphApiVersion = "Beta" $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=groupAssignments" $DMS = Invoke-MSGraphRequest -HttpMethod GET -Url $uri $AllDeviceConfigScripts = $DMS.value | Where-Object {$_.assignments -match $Group.id} Write-host "Number of Device Configurations Powershell Scripts found: $($AllDeviceConfigScripts.DisplayName.Count)" -ForegroundColor cyan Foreach ($Config in $AllDeviceConfigScripts) { Write-host $Config.displayName -ForegroundColor Yellow } #Administrative templates $Resource = "deviceManagement/groupPolicyConfigurations" $graphApiVersion = "Beta" $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments" $ADMT = Invoke-MSGraphRequest -HttpMethod GET -Url $uri $AllADMT = $ADMT.value | Where-Object {$_.assignments -match $Group.id} Write-host "Number of Device Administrative Templates found: $($AllADMT.DisplayName.Count)" -ForegroundColor cyan Foreach ($Config in $AllADMT) { Write-host $Config.displayName -ForegroundColor Yellow } ####Config End#### Now let's check all the groups from Azure Active Directory. $Groups = Get-AADGroup | Get-MSGraphAllPages ####Config Start #### Foreach ($Group in $Groups) { Write-host "Azure Active Directory Group Name: $($Group.displayName)" -ForegroundColor Green #Apps $AllAssignedApps = Get-IntuneMobileApp -Filter "isAssigned eq true" -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id} Write-host "Number of Apps found: $($AllAssignedApps.DisplayName.Count)" -ForegroundColor cyan Foreach ($Config in $AllAssignedApps) { Write-host $Config.displayName -ForegroundColor Yellow } #Device Compliance $AllDeviceCompliance = Get-IntuneDeviceCompliancePolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id} Write-host "Number of Device Compliance policies found: $($AllDeviceCompliance.DisplayName.Count)" -ForegroundColor cyan Foreach ($Config in $AllDeviceCompliance) { Write-host $Config.displayName -ForegroundColor Yellow } #Device Configuration $AllDeviceConfig = Get-IntuneDeviceConfigurationPolicy -Select id, displayName, lastModifiedDateTime, assignments -Expand assignments | Where-Object {$_.assignments -match $Group.id} Write-host "Number of Device Configurations found: $($AllDeviceConfig.DisplayName.Count)" -ForegroundColor cyan Foreach ($Config in $AllDeviceConfig) { Write-host $Config.displayName -ForegroundColor Yellow } #Device Configuration Powershell Scripts $Resource = "deviceManagement/deviceManagementScripts" $graphApiVersion = "Beta" $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=groupAssignments" $DMS = Invoke-MSGraphRequest -HttpMethod GET -Url $uri $AllDeviceConfigScripts = $DMS.value | Where-Object {$_.assignments -match $Group.id} Write-host "Number of Device Configurations Powershell Scripts found: $($AllDeviceConfigScripts.DisplayName.Count)" -ForegroundColor cyan Foreach ($Config in $AllDeviceConfigScripts) { Write-host $Config.displayName -ForegroundColor Yellow } #Administrative templates $Resource = "deviceManagement/groupPolicyConfigurations" $graphApiVersion = "Beta" $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)?`$expand=Assignments" $ADMT = Invoke-MSGraphRequest -HttpMethod GET -Url $uri $AllADMT = $ADMT.value | Where-Object {$_.assignments -match $Group.id} Write-host "Number of Device Administrative Templates found: $($AllADMT.DisplayName.Count)" -ForegroundColor cyan Foreach ($Config in $AllADMT) { Write-host $Config.displayName -ForegroundColor Yellow } } ####Config End#### I hope this article was useful. Thank you for taking the time to read the article. Best regards, Tom Wechsler P.S. All scripts (#PowerShell, Azure CLI, #Terraform, #ARM) that I use can be found on github! https://github.com/tomwechsler96KViews9likes17CommentsCreating a folder containing multiple files and sending to devices via intune
Hi all, I desperately need some help! And just thought Id post on here to see if someone can help! I need to create a folder on client machines in the c drive (Folder name: Spanish Games) which I then deploy a bunch of files to this folder I create I have had a look and seems like I need to create a win32 app container with all in, script and files. What would I need to include in the script to get this to work? I have had a look at docs online but cant find one that deploys a folder and files too. I have found this: https://pariswells.com/blog/intune/copy-file-to-workstations-with-windows-intune but dont really understand some of it. Any help would be great!! Thanks in advanceSolved58KViews0likes22CommentsDuplicating Device Configuration Profiles
Duplicating Device Configuration Profiles 7/24/2019 - 13 Minutes to read One of the highest voted feature requests in Intune UserVoice is the ability to duplicate Device Configuration profiles and for good reason. I work in the Education sector, so I'm deploying carts of laptops to multiple classrooms in multiple schools. Generally, the whole school would have the same profiles assigned to all devices but teachers can be pretty fickle about what restrictions should and shouldn't be on their classroom's devices. So if a couple classrooms want to have one or two things changed for their carts, I'd be stuck in the portal, clicking away and comparing until I have four or five profiles that are exactly the same, aside from those tiny changes. It's a huge time suck having to do that and some setting always gets missed. Lucky us, (almost*) the entire Intune UI front end is built using Graph so anything we can do in the UI, we can also do in Graph. Let's say that the entire school has a profile applied to all devices but one classroom wants to block the camera. To do this through the UI, we'd have to start from scratch and dual monitor or split screen two windows to have the default profile open while we configure the one-off profile. But let's see how we can do this through Graph to speed up the process and help eliminate missed settings between the two profiles. I use two methods to view the profile through Graph. Between the two, the one that I use just depends on if I have Graph open already. If I don't have Graph open, I'll start in the portal. We'll start with that method first. Method 1 – Using Developer Tools from your Browser The first method, you'll be using your browser's built-in Developer Tools. For me, that's usually Chrome but I've been using the new Edge more and more lately. The good thing is since they are both built on Chromium, it's pretty much the same between the two. For this guide, I'll be using Chrome. Navigate to Intune > Device configuration – Profiles Since everything in the UI is just a frontend for Graph API, every time you do something in the UI, you'll be able to see all of the REST requests made by observing Network requests from the Network tab of your DevTools. This can look a little intimidating at first but if you start recording Network requests right before you view or change something in the UI, then stop recording when you're done viewing or changing things, you'll limit the number of recorded requests to only what happened while you making the changes or viewing the profiles. Open your browser's Developer Tools. In Chrome (called DevTools), this is done by pushing F12. Open the Network tab and make sure it's recording. You'll see the Red record button lit up. Click on the profile you want to copy. Once the page loads, stop the Network recording. You should now see a handful of requests listed there. These are what was happening behind the scenes as you opened the profile that you wanted to copy. We can break this down a little bit but we won't get too deep as that could be a completely separate guide by itself and I'm not an expert in RESTful APIs. You can see a little bit of what you need just by the name of the requests, but when you click on the requests, you'll get a lot more information. Click on the first one listed and open the Headers tab. In that tab, you'll see Request URL under General. Let's take a look at that URL and break it down. In this case, it can be broken down like this: https://graph.microsoft.com/{version}/{collection}/{collection}/{entity}?[query_parameters] So that means, "deviceManagment" is a collection that contains other collections, like "managedDeviceOverview", "detectedApps", and what we want, "deviceConfigurations". "deviceConfigurations" is the collection of, you guessed it, all your device configuration profiles. And the final part of the request URL is the ID of the device configuration profile entity that we are copying. Now technically, that is the full URL. The question mark is the query initiator and everything after is part of the query. In our URL, the query is requesting that the returned data also includes the assignments of the profile. We don't really need that and it's usually faster to just do the assignments through the UI unless you already have the entity ID of the groups you will be assigning them to. So now that we know all that, we can move on to the next Network request in the list which should be the actual "GET" request. What we are interested in with this one, is in the Response tab. These are all the settings that are in that device configuration profile and all their properties. Now, in this view it's pretty hard to read, but we can use Graph Explorer to get the same data in a prettier format since we have the request URL. Copy everything in the Request URL from the beginning up to the "?". Remember that the question mark and everything behind it is part of a query and is not something that we need right now. Open https://developer.microsoft.com/en-us/graph/graph-explorer# in a browser, sign in, and read and allow access if needed (if this is your first time using Graph and no one has accepted on behalf of the organization then you'll be prompted for this). In the Graph URL request input field, paste the Request URL that you just copied. Make sure that the HTTP verb select button is on GET and click on Run Query. Upon success you'll get a little notification with the Status Code of 200 and a Response Preview of all the settings and their properties in JSON format. We now have all the data we need to make another profile with the exact same settings. Method 2 – Using Graph to find the device configuration profile The second method is actually the one I use most since I typically have a Graph Explorer window open as one of my five opening tabs and since I'm becoming more comfortable using Graph. Open https://developer.microsoft.com/en-us/graph/graph-explorer# in a browser and enter https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations into the Graph URL request input field, make sure that the HTTP verb select button is on GET and click on Run Query. How do I know this if I didn't use DevTools? The "Working with Intune in Microsoft Graph" (https://docs.microsoft.com/en-us/graph/api/resources/intune-graph-overview?view=graph-rest-1.0) doc is a pretty great reference on how to navigate your way through Graph. I have come across a few discrepancies here and there but for the most part, it's pretty solid. Using that doc, you can find out how to "list" all your device configurations. Again, you should see "Success – Status Code 200" after the query is returned. This time, in the Response Preview body, you'll see a list of all your device configuration profiles. For me, it's a very short list; just one profile, but in a production environment, there can be a lot more. Easiest thing to do is ctrl-F to find the name of the profile you want to copy but you can save yourself a little time and get a little practice in by adding some query parameters to the end of your request URL. We initiate the query parameter with "?" Followed by the name of the parameter. These query options are in OData V4 query language. We'll be using the "$filter" to filter out everything we don't need and only return what we do need. As you can see in the screen shot, the "displayName" of my policy is "Default Restrictions". Since we already know the name of the policy we are going to be copying, we can use that to filter everything else out by adding ?$filter=displayName eq 'Default Restrictions' to the end of our request URL and run the query. Now, only profiles matching that filter will be returned. Then copy the "id", and add it to the end of the request URL and run your query again. We now have the data we need to create a new profile with the same settings. Creating the new profile We should now be looking at a JSON formatted policy that we can copy and edit to create a new policy with. To do this, we'll need to prune out a few lines. While you can do this directly in Graph Explorer, I recommend using a smart text editor like Notepad ++ or Sublime Text. Copy everything from the opening bracket ( { ) just above the "@odata.context" line to the closing bracket ( } ) just after your last setting. Careful here. You have to make sure you're copying everything you need. In my profile, the last setting uses brackets within the setting. It's easy to misread it and copy the bracket that closes that setting and miss the bracket the closes the entire config. Just be mindful of that. Paste the copied text into a text editor and find the lines that you'll need to delete. You'll want to remove anything that is generated automatically like "@odata.context", "id", "lastModifiedDateTime", "supportsScopeTags", "createdDateTime", and "version". Once those are removed, you'll want to edit the "displayName" and "description" at least, but you can also make your configuration changes here if you know what you are doing. In my case, I'll change the "displayName", "description", and "cameraBlocked" settings, The first two setting properties are strings, while the "cameraBlocked" setting property is boolean. I'll replace displayName: "Default Restrictions" with "Custom Restrictions – City High School Room 104", description: "Standard policy for Company Windows 10 Devices" with "Modified from Default Restrictions – Block Camera", and cameraBlocked: false to true. Pay special attention to where the quotes are. There are none needed for boolean properties. Now I have my new profile in JSON format and we are ready to create the new profile using Graph. Open https://developer.microsoft.com/en-us/graph/graph-explorer and enter https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations in the URL request field. Copy and paste our newly created JSON text into the Request Body field, change the HTTP verb select button to POST, run our query and be done. Obviously, you always want to be very careful when you are running POST requests, and generally any other request that isn't a read action. You should now get a notification with "Success – Status Code 201" along with a Response Preview of the complete JSON data of the new profile, including the automatically created settings that were removed previously. If you refresh your Intune > Device configuration – Profiles blade, you'll see your new profile. It's always best to compare the number of Settings Configured just to be sure nothing was missed. Here you can see that the new profile has the correct name, description, and has one more setting then the Default Restrictions profile. That additional setting is the Block Camera setting. So you can see how we can leverage Graph to programmatically make changes to Intune. It doesn't stop with duplicating profiles either. I've used it to create hundreds of Dynamic Device Groups, assign Apps to mass groups, and much more. Graph is adding to its capabilities to manage Intune as fast as Intune is adding features. And best of all, you get to deal with Intune UI a lot less. Follow Graph's What's new page at https://docs.microsoft.com/en-us/graph/whats-new-overview. Follow me on Twitter: @portaldotjay * -Thanks jenstf for pointing out that Intune also uses the API, "main.iam.ad.ext.azure.com". Be warned - using that API is unsupported so don't dink around in there if you don't know what you're doing.53KViews3likes9CommentsHow to create a backup of your Microsoft Endpoint Manager (Intune) infrastructure!
Dear Microsoft Intune Friends, Imagine the following situation. You have invested several hours to build your Microsoft Endpoint Manager (Intune) infrastructure. After the final tests, everything is now working exactly as you imagined. Now the question arises how can I backup all these settings and configurations? I will answer this question in this article. Note: I will describe how to compare and restore the backup in a next article. https://techcommunity.microsoft.com/t5/microsoft-intune/compare-and-restore-a-microsoft-endpoint-manager-intune-backup/m-p/2993736 What we can do in the Microsoft Endpoint Manager portal is export configuration settings to a CSV file. However, this is not exactly what I wanted. To create a complete backup of our tenant we need the power of PowerShell (power of PowerShell - funny ) I used the PowerShell ISE for this configuration. But you are also very welcome to use Visual Studio Code, just as you wish. Please start with the following steps to begin the deployment (the Hashtags are comments): #The first two lines have nothing to do with the configuration, but make some space below in the blue part of the ISE Set-Location Clear-Host #Customize the ExecutionPolicy (absolutely OK for this demo) Set-ExecutionPolicy -ExecutionPolicy Unrestricted #Install the Module Install-Module -Name Microsoft.Graph.Intune -Verbose -Force -AllowClobber #Install the Module Install-Module -Name MSGraphFunctions -Verbose -Force -AllowClobber #Import the Module Import-Module -Name MSGraphFunctions #Install the Module Install-Module -Name AzureAD -Verbose -Force -AllowClobber #Install IntuneBackupAndRestore from the PowerShell Gallery Install-Module -Name IntuneBackupAndRestore -Verbose -Force -AllowClobber #Update the Module Update-Module -Name IntuneBackupAndRestore -Verbose #Import the Module Import-Module IntuneBackupAndRestore #Connect to Microsoft Graph Connect-MSGraph Here you must agree to the extended permissions. #Create a folder New-Item -ItemType Directory -Path C:\Backup\IntuneBackup #Switch to the folder Set-Location C:\Backup\IntuneBackup #Create the Full-Backup Start-IntuneBackup -Path 'C:\Backup\IntuneBackup' It starts with the creation of the backup. #Let's look at the content Get-ChildItem -Path 'C:\Backup\IntuneBackup' Let's start Windows Explorer and navigate to our backup folder, Bingo....we have a complete backup! I know that was nothing spectacular, but I still wanted to share my experience with you. Thank you for taking the time to read this article. Kind regards, Tom Wechsler P.S. All scripts (#PowerShell, Azure CLI, #Terraform, #ARM) that I use can be found on github! https://github.com/tomwechsler46KViews10likes14CommentsManaging Intune Device Categories via Powershell
Hi all, Looking for a bit of help with the Intune Powershell/graph interface. I'm trying to manipulate Intune Device Categories via Powershell, so that I can firstly correct devices that were placed into the wrong category during enrollment, and secondly, I'm in the middle of moving from Hybrid SCCM/Intune to Azure Intune and where we're not using Device Categories for devices already enrolled into SCCM Hybrid Intune, I want to use powershell to loop through a CSV file full of device serial numbers / IMEI numbers and place corporate devices into the right device category. So, investigating the powershell/graph interface for Intune, I can do something like Get-IntuneManagedDevice -Filter "IMEI eq '01 012345 678910 1'" (Or -Filter "serialNumber eq 'DEADBEEF'" or whatever) and get my all my device's details output. This includes a field for "deviceCategoryDisplayName", which is the value I want to change. I can even do Get-IntuneManagedDevice -Filter "serialNumber eq 'DEADBEEF'"| select manageddeviceid to get the managedDeviceID value as an output. As far as I can tell, this should work with Update-IntuneManagedDevice? (see below) get-help Update-IntuneManagedDevice -detailed NAME Update-IntuneManagedDevice SYNOPSIS Updates a "microsoft.graph.managedDevice". SYNTAX Update-IntuneManagedDevice -managedDeviceId <string> So I should be able to update a device by using its managed Device ID? What I can't do is: Get-IntuneManagedDevice -Filter "serialNumber eq 'deadbeef'"| select manageddeviceid | Update-IntuneManagedDevice -deviceCategoryDisplayName 'BYOD' I get the error below. Clearly I'm doing something wrong but can anyone point me in the right direction? I don't think that what I'm trying to do is fundamentally unreasonable... is it? (just to be clear, doing Get-IntuneManagedDevice -managedDeviceID deadbeef-aaaa-bbbb-cccc-0123456789ab returns my target device details ok, and running Update-IntuneManagedDevice -managedDeviceID deadbeef-aaaa-bbbb-cccc-0123456789ab -deviceCategoryDisplayName 'BYOD' gives me the same error) Update-IntuneManagedDevice : 400 Bad Request { "error": { "code": "InternalError", "message": "{\r\n \"_version\": 3,\r\n \"Message\": \"An error has occurred - Operation ID (for customer support): 00000000-0000-0000-0000-000000000000 - Activity ID: 6f743002-b0e0-48ed-a25d-0cdd33870efd - Url: https://fef.msub02.manage.microsoft.com/DeviceFE/StatelessDeviceFEService/deviceManagement/managedDevices%28%27cef75e9c-9747-4520-8e18-2498ac18a1da%27%29?api-version=2018-05-24\",\r\n \"CustomApiErrorPhrase\": \"\",\r\n \"RetryAfter\": null,\r\n \"ErrorSourceService\": \"\",\r\n \"HttpHeaders\": \"{}\"\r\n}", "innerError": { "request-id": "6f743002-b0e0-48ed-a25d-0cdd33870efd", "date": "2019-03-06T14:08:02" } } } At line:1 char:92 + ... ddeviceid | Update-IntuneManagedDevice -deviceCategoryDisplayName 'BY ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ConnectionError: (@{Request=; Response=}:PSObject) [Update-IntuneManagedDevice], HttpRequestException + FullyQualifiedErrorId : PowerShellGraphSDK_HttpRequestError,Microsoft.Intune.PowerShellGraphSDK.PowerShellCmdlets.Update_IntuneManagedDevice35KViews1like9Comments"You'll need a new app to open this about link"
I have a custom app running inside of Microsoft Teams. Everything works as expected when running it inside the Teams web application. Running it inside the Teams desktop application breaks part of my custom app. The issue arises when making a request to any web API. That could be the Microsoft Graph API or a custom one I've build for the custom, client application. Instead of getting data back when making the request, I get a popup stating "You'll need a new app to open this about link". Look for an app in the Microsoft Store. Yes/No. I've tried all kinds of different things. Different providers, SSO vs Azure Auth. Any help would be highly appreciated. Regards, Tolga35KViews0likes5Comments