Skip to main content

Posts

2020

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:

Document Conditional Access Configuration with my Modern Workplace Concierge

Documenting things sucks. If it involves a lot of klick(edi klack klack) in portals and copying information around even more. But there’s hope. And it’s called automation. For the Intune part Thomas Kurt did already an awesome job with his IntuneDocumentation. Now the Modern Workplace Concierge is ready to help you with documenting your Conditional Access configuration. I promise you: we will get through this within under 15 minutes! Afterwards you can make an impression on your fellow Enterprise Mobility teammates. What’s inside? # A Conditional Access policy is returned by the Microsoft Graph API in the following JSON representation: { "id": "714b5737-5f13-415e-bf96-d659f3a5928e", "displayName": "PROD - Admin protection - Azure management: Require MFA", "createdDateTime": null, "modifiedDateTime": null, "state": "enabled", "grantControls": { "operator": "OR", "builtInControls": [ "mfa" ], "customAuthenticationFactors": [], "termsOfUse": [] }, "conditions": { "signInRiskLevels": [], "clientAppTypes": [], "platforms": null, "locations": null, "deviceStates": null, "applications": { "includeApplications": [ "797f4846-ba00-4fd7-ba43-dac1f8f63013" ], "excludeApplications": [], "includeUserActions": [] }, "users": { "includeUsers": [ "All" ], "excludeUsers": [], "includeGroups": [], "excludeGroups": [ "04988d96-ad01-4569-9aee-a199a1cb4f8e" ], "includeRoles": [], "excludeRoles": [] } }, "sessionControls": null } That’s not really human readable. Especially the object id’s (32 character UUIDs) make it difficult to guess to which users or apps a policy is assigned. But an API has definitely other goals than showing pretty formatted reports.

I said Connect-AzureAD and not sign-out and re-sign-in!

If you are using the “AzureAD” PowerShell module (also applies to the AzureADPreview) you have probably noticed that the Connect-AzureAD Cmdlet ignores existing access tokens and initiates a new sign in to Azure AD even if you are already signed in. Prompt you get when calling the "Connect-AzureAD" cmdlet Long story short, I got annoyed every time when I accidentally recalled Connect-AzureAD (mostly when working with Scripts) until I found this amazing hint on technet and now I want to (re-)share it with you. In your PowerShell scripts simply use the following snippet to connect with Azure AD / check your connection and you wont get any sign-in prompts if you are already connected! Reusing the access token for the MsOnline module # The Azure AD PowerShell access token which gets stored can also be used to connect to the MsOnline resources (because certain attributes like strong authentication details are not available with the AzureAD modules): $token = [Microsoft.Open.Azure.AD.CommonLibrary.AzureSession]::AccessTokens Connect-MsolService -AccessToken $token.AccessToken.AccessToken

Generate a report about assigned Azure Active Directory roles

The Azure AD portal does not really provide an overview about all directory role assignments in your tenant. If you want to review existing Azure AD Directory roles a csv report will probably better server your needs. Therefore I created a PowerShell script to export the role assignments. The Azure AD Portal only displays limited information about the assignments ### PowerShell Script Find the PowerShell script in my techblog GitHub Repository. Make sure that you have the AzureAD PowerShell module installed before running the script. You can install it by running “Install-Module AzureAD”. PowerShell script output Report # The report contains three columns: Role (name of the directory role) Note that the Global Administrator Role is represented as Company Administrator Member If the role is assigned to a user its the UserPrincipalName If the role is assigned to a service principal its the display name with the Azure AD application ID in the brackets ObjectType Indicates whether the role is assigned to user account or a service principal CSV file containing all assigned directory roles Comparing reports # You can compare two reports with the following PowerShell code:

Detect Deleted User Accounts in Azure Active Directory

An account in your Azure Active Directory got deleted and you want to examine who initiated the delete action? Sounds very simple but if you do not want to search your logs manually things become a little bit trickier. The challenge # When a user gets deleted and you only remember it’s userPrincipalName you wont be able to to search for a match. And I doubt that you memorized the Azure AD object id of that user. Here’s what the Azure AD Audit log shows us: The userPrincipalName attribute will get the Azure AD object ID as prefix: userPrincipalName before deletion: [email protected] userPrincipalName after deletion: [email protected] By having a closer look to the Azure Active Directory Audit logs you will notice that the filtering or search capabilities are limited in terms of searching for a specific target: Search is case-sensitive and only supports ‘starts with’ operator Which means we cannot search for the userPrincipalName. The only option in the Azure AD Audit Logs would be to download the logs and perform a search within a text editor which is not really feasible nor efficient.

Managing the new Microsoft Edge Browser with Intune

With the availability of the new Edge browser based on chromium I gained the first experiences about configuring the browser in an enterprise environment. Of course I want to share those with you. This post hopefully helps you to roll-out and configure the new Edge Browser with Microsoft Intune. Install the new Edge Chromium with Intune # The installation of Edge is not the main topic of this post. The Edge browser is available in Intune as built-in app type like the Office 365 suite. More information about the installation process is available here. Set Edge Chromium as default browser # Default applications are configured on the Windows 10 operating system level via app associations. The current app associations of a device can be exported with dism and the command: Dism /Online /Export-DefaultAppAssociations:"appassociations.xml" Which will produce a file containing all associations. For setting Edge as the default browser this one is sufficient: To deploy an app associations file with Intune it needs to be base64 encoded. I used the base64encode online tool. Intune configuration # To distribute the default app association configure the following OMA-URI in a custom device configuration profile:

Prevent Intune devices from getting the Microsoft search (Bing) plugin

Microsoft recently announced to install a Bing extension on new and existing Office 365 ProPlus installations which will set Bing as the default search engine starting with the first Office 365 ProPlus release in 2020 - not appreciated Microsoft and definitely not what customers want! The extension will be shipped for new Office installations and existing clients with Office 365 ProPlus installed when they update. Update 11.02.2020: “ The Microsoft Search in Bing browser extension will not be automatically deployed with Office 365 ProPlus.” - I will keep this post for the archives. Starting with Version 2002 of Office 365 ProPlus, an extension for Microsoft Search in Bing will be installed that makes Bing the default search engine for the Google Chrome web browser only on devices in certain locations. This extension will be installed with new installations of Office 365 ProPlus or when existing installations of Office 365 ProPlus are updated. (Reference) As expected date the 2002 release will be rolling out in March for the monthly update channel. More details are available under: Microsoft Search in Bing and Office 365 ProPlus Affected locations New Office installations # To avoid the plugin being installed with new office installations edit your Office 365 Configuration with the Office Customization Tool . Make sure to toggle the switch for “Set default search engine to Microsoft Search in Bing” to off:

Deploy fonts to Intune managed Windows 10 devices

Recently a customer using Microsoft Intune requested to deploy a TrueType font required by one of their line of business apps. Because Intune does not offer a native solution to deploy fonts it was quite clear that a PowerShell script or Intune Win32 app should do the trick. Note that the mentioned PowerShell scripts can also be used for app deployments with Configuration Manager (MEMCM). How to install a font programmatically? # There seem to be multiple options depending on the operating system version. I’ve tested this with Windows 10 1909. And broke it down to the following steps: Copy the font to the “C:\Windows\Fonts” folder Create a registry key which points to the filename of the *.ttf or *.otf font copied to the Windows font path How to install a font with Intune? # To get the font to Windows 10 devices I created a PowerShell script which copies the font files to the windows-fonts folder and creates the required registry key. Deploying the PowerShell script as Intune Win32 app has the advantage that we can link the font as a dependency if any app requires a specific font. Additionally we can detect and uninstall the font if needed.

Connecting to foreign Intune tenants with Microsoft Graph and PowerShell

If you manage multiple Intune tenants with your Azure AD account (invited as guest in the foreign tenant) we need a way to specify the tenant id we want to connect. Otherwise you will land in your home-tenant every time. This posts shows you how to accomplish that with the Intune PowerShell SDK. If we have a look at the default Graph settings in a PowerShell session with the Intune PowerShell SDK you will notice that all authentication requests will land on the /common endpoint. Get-MSGraphEnvironment AuthUrl : https://login.microsoftonline.com/common ResourceId : https://graph.microsoft.com/ GraphBaseAddress : https://graph.microsoft.com AppId : d1ddf0e4-d672-4dae-b554-9d5bdfd93547 RedirectLink : urn:ietf:wg:oauth:2.0:oob SchemaVersion : v1.0 To connect to a specific tenant we need to update the AuthUrl to contain the tenant id or any registered domain name of the target tenant before connecting: Update-MSGraphEnvironment -AuthUrl "https://login.microsoftonline.com/nicolonsky.ch" Afterewards you can connect to Microsoft Graph as usual: Connect-MSGraph ``` Happy Microsoft Graph-ing with multiple tenants.