Skip to main content

Powershell

Access has been blocked by Conditional Access policies when using device code flow

When using device code authentication for PowerShell modules with conditional access you might receive prompts like: “Access has been blocked by Conditional Access policies. The access policy does not allow token issuance” or “AADSTS50097: Device authentication is required”. But what’s the reason for this error and is there a solution available? Examples from the field # Device code flow is quite a convenient way to sign-in for an app within the web browser - at least if it works. If not you have to consider other options and that’s probably the reason why you’re reading this blog article. Az PowerShell Running the Az PowerShell module on PowerShell 7 uses device code flow to authenticate against your Azure tenant and might fail: Connect-AzAccount: AADSTS50097: Device authentication is required. Timestamp: 2020-08-17 13:36:31Z: Response status code does not indicate success: 401 (Unauthorized). The sign-in to Azure is tied to the “Microsoft Azure Management” app that you can select within Conditional Access. Microsoft Graph PowerShell The same applies for the new Microsoft.Graph PowerShell modules - but here we receive a more detailed error message: Connect-Graph: AADSTS53003: Access has been blocked by Conditional Access policies. The access policy does not allow token issuance. Timestamp: 2020-08-17 13:37:12Z The sign-in to the new Microsoft Graph Modules is tied to the “Microsoft Graph PowerShell (Preview)” app and some more apps I couldn’t determine.

Bulk create Intune mobile app deployment groups and assignments

Creating assignments and software deployment groups for Intune mobile apps is quite a repetitive and manual task. Because of that, I want to share a PowerShell script with you which allows you to automatically create software deployment groups in Azure AD and the assignments for various intents. The script allows you to: Create Azure AD groups (install uninstall purpose) Pick existing groups based on displayName Assign Intune mobile apps (tested for Win32 and MSI LOB apps) You can find the script on my techblog GitHub repository. Because of the configurable group prefixes the script helps you to keep your Intune environment clean and implement a standard app assignment configuration. The script uses the Microsoft Graph API and the following resources https://graph.microsoft.com/beta/deviceAppmanagement/mobileApps https://graph.microsoft.com/beta/deviceAppmanagement/mobileApps/{AppID}/Assignments https://graph.microsoft.com/beta/groups It uses the preregistered app “Microsoft Intune PowerShell” which exists by default in all tenants. If you want to run the Script with PowerShell 7 you need to create an adjust the MSAL token section with the -DeviceCode parameter. You can bulk select the apps you want to create the assignment and AAD deployment groups: Hope this saves you some time.

Add PowerShell modules to Azure functions

Azure functions for PowerShell natively ship without additional cmdlets or PowerShell modules. In this post, I will show you how to add both public modules from the PowerShell gallery with automatic dependency management and custom modules. For both options, we use the Kudu tools to adjust the configuration of our function app. You can launch them from the “Advanced Tools” section of your function app: Afterwards, launch the PowerShell debug console and navigate to the wwwroot folder of your app: Option 1: Automatic dependency management # Note: Installing modules which require license acceptance (e.g. the MSAL.PS module) currently cannot be installed with automatic dependency management. You can track the issue status here and here. {: .notice–warning} Azure function apps running PowerShell come with a nice feature called managed dependencies. You can specify the modules you want to import from the PowerShell Gallery and the function app host will automatically process the dependencies. In the requirements.psd1 add the module details: # This file enables modules to be automatically managed by the Functions service. # See https://aka.ms/functionsmanageddependency for additional information. # @{ # For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'. 'Az' = '4.*' 'Microsoft.Graph.Authentication' = '0.*' } You can either specify an exact version available from the PowerShell Gallery or specify the major version with a wildcard. With the wildcard option it will use the latest version available.

Playing around with the Office 365 Service Communications API

The Office 365 Service Communications API provides information about Microsoft 365 service status for your tenant including service messages. I built a little PowerShell module to access the API with PowerShell cmdlets. In this post I want to show you some examples which help you to use the API. PowerShell Module # I built a PowerShell module to access Microsoft 365 service status details natively with PowerShell. The PowerShell module and documentation is available on the PowerShell Gallery and on GitHub. Before using the module an app registration is required. Setup instructions are also provided on GitHub. CI/CD # By leveraging Azure DevOps I created a build and release pipeline which automatically builds the PowerShell module with Plaster. Builds are only created if the commit on GitHub includes a version tag. This version tag gets automatically populated to the module manifest. The build artifact gets then automatically published to the PowerShell Gallery as a new version. Furthermore, a new GitHub release including the module artifact is added to the project. This process fully automates the publishing and build process for the module. For local development and maintenance, the module can also be built with Invoke-Build.

Azure AD guest user review solution

Azure Active Directory guest users really simplify the process to collaborate with external users. Although keeping a good governance on guest accounts can become quite a challenge. The two biggest challenges I often observe are: “Who invited that guest user?” and “Does this guest user still need access to our infrastructure?”. Inspired by a recent post of Thomas Kurth regarding Azure AD Guest Account - Governance and Cleanup I also developed a solution which comes quite close to an “Azure AD Access review” like user experience. Notable features # The ‘Manager’ attribute of your guest users get’s automatically populated with the identity of the inviter All Azure AD app registration information is stored in Azure Key Vault Almost zero touch deployment with ARM templates You can integrate existing guest users into this solution by populating the manager attribute in Azure AD You can configure the approval frequency for guest accounts Approval frequency respects last approval date for each guest account Architecture # The solution leverages function of: Azure Logic App

Remove Azure AD direct License Assignments with PowerShell

Who doesn’t love a clean and tidy environment, do you? This also applies for your license assignments in Office 365 and Azure AD. As time passess it is likely to have users with direct license assignments or users which still have old trial licenses assigned. To get rid of those assignments I created a PowerShell script with removal and reporting functionality. Direct link to the script. Identify direct license assignments # In the Azure Portal we recognize direct license assignments on a user account by viewing the “Assignment Paths”: With the MSOnline PowerShell module we can view the Licenses property of a user and retrieve a nested property called: GroupsAssigningLicense. The GroupsAssigningLicense property contains either: An empty array if the license was not inherited from a group -> direct assignment An array with objectId’s If the array contains the user’s objectId -> direct assignment Example 1: User with objectId 36c9b091-fe88-4dc2-a9e1-2662020b4bab has group based license assignment and direct assignment: AccountSkuId : nicolasuter:SPE_E5 GroupsAssigningLicense : {0a918505-d0d5-4078-9891-0e8bec67cb65, 36c9b091-fe88-4dc2-a9e1-2662020b4bab} Example 2: User has no inherited licenses from a group: AccountSkuId : nicolasuter:SPE_E5 GroupsAssigningLicense : {} PowerShell Script # You find the PowerShell script on my techblog GitHub repository.

10 suggestions to improve your next PowerShell script

Most of the time PowerShell is my favourite choice to automate processes and tasks. In order to improve the maintainability of my scripts I usually try to focus on some standards combined with a clean scripting style. In this post I want to show you 10 suggestions to improve your next PowerShell script. I’ve tried to order the suggestions according to an actual PowerShell starting from the very first line till the last line. 1. Script prerequisites # Your PowerShell script might need specific modules or elevated user rights to run. The #Requires statement ensures that these prerequisites are met before the actual script get’s executed. So you don’t need to implement your own checks to verify prerequisites. Simply use the #Requires statement at the very first line of your script. Find out more about #Requires statement. Modules # Another benefit of specifying the modules within the requires statement is that scripts hosted on the PowerShell Gallery automatically install the modules mentioned in the #Requires list. To make sure a specific module is installed use: #Requires -module "Microsoft.Graph.Intune" To ensure a module with a specific version is available:

Exploring the new Microsoft Graph PowerShell Module(s)

Microsoft is working on a new set of PowerShell modules grouped under the umbrella of Microsoft.Graph that will (hopefully) cover all the Microsoft Graph resources available. I’ve already used some of them for my Conditional Access Documentation Script and thought they have some notable features worth sharing. Advantages and changes # The Microsoft Graph modules use the new Microsoft Authentication Library (MSAL) instead of the old Azure AD Authentication Library (ADAL). The MSAL library in the modules implements a token cache which persists the access and refresh tokens. MSAL caches a token after it has been acquired. Application code should try to get a token silently (from the cache), first, before acquiring a token by other means. - Microsoft docs The token cache persists system reboots and re-opening PowerShell sessions. The module allows you to obtain tokens either for authentication via client credentials (certificate only) or device code flow. Furthermore, the new modules support a really broad spectrum of available entities on the Graph API. From an EM+S perspective this means for example: groups, users, identity protection, conditional access, and some of the Intune app management commands are also starting to appear. Just be aware that the modules are currently published as pre-release. If you encounter any issues share them with the development team on GitHub and submit issues or even better contribute directly to the project.

Validating a GUID with PowerShell

For some recent Microsoft Graph scripts I wanted to translate some Azure AD Object ID / GUID entries to their respective display name. The array with the GUID’s contained already some readable text. Of course I only wanted to translate the GUID entries with according Graph API requests. Otherwise the Graph requests would fail. Google offered only some fancy regex functions and helpers but I had that .NET function in my mind which looks much nicer compared to whatever regex pattern that I don’t understand. "applications": { "includeApplications": [ "797f4846-ba00-4fd7-ba43-dac1f8f63013", "Office365" ] } So I needed a way to test a string for a valid GUID and only invoking the Graph calls for GUID values. Matching a GUID with a regex # I found the following regex on this site: "d815c3bc-9c49-4633-9d16-29808242d063" -match '(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$' Matching a GUID with the .NET method # Instead of the complex regex we can invoke this nice .NET member method which returns true or false based on the input: [guid]::TryParse("d815c3bc-9c49-4633-9d16-29808242d063", $([ref][guid]::Empty)) I guess that’s much more convenient. Helper Function # Here’s a helper function which can be used in PowerShell scripts:

Creating desktop shortcuts with Intune

Why want you to create desktop shortcuts with Intune? Business specific apps may require special shortcuts in order to launch the application with the right parameters. Or you need to create a shortcut for an application which is stored on your on premises fileserver. For this purpose I created a little solution which closes the gap between the modern cloud and on premises world. In comparison with other solutions this one works if you have redirected the users desktop with OneDrive Known Folder Move and automatically remediates missing shortcuts if they got deleted. Direct link to the GitHub repository. Browser links: Instead of placing shortcuts to websites on the desktop I would recommend you to use managed bookmarks which can be directly provisioned within the web browser. I documented this for the new Microsoft Edge based on chromium here. {: .notice} Features # This solution works when the desktop is redirected with OneDrive Known Folder Move Everything is user based (local userprofile) If the shortcut is missing or deleted it gets automatically (re)created Possibility to remove shortcut via Intune Win32 app uninstall Shortcut can point to: URL, File (UNC) or Folder (UNC) Ability to pass shortcut arguments Ability to specify shortcut icon (UNC/URL) Ability to deploy shortcut together with an app using Intune Win32 app dependencies Architecture # A simple PowerShell script which does all the shortcut stuff is wrapped as Intune Win32 App. This adds possibility to detect the presence of the shortcut and if required to uninstall it with Intune. In order to work with the redirected desktop to OneDrive with Known Folder Move we can take advantage of the [Environment]::GetFolderPath("Desktop") method to resolve the desktop location. Based on the Win32 app configuration the shortut get’s either created on the users personal desktop or on the allusers desktop.