Skip to main content

Hi, I'm Nicola 👋

Security insights. Fresh perspectives. Shared with the community through blog posts, open-source projects, and conference talks.

MVP Logo

Recent

How I migrated my Ghost blog to Jekyll

Another migration of my blog? After running it for almost three years I thought it’s time for another change. The Ghost platform introduced a lot of changes and updates (with features that I don’t need) and caused me quite some expenses on my Azure subscription (around 50$ each month). Furthermore I wanted someting looking more clean with more focus on the writing part without a lot of fancy add-ons and functionalities. But it still had to cover features like tag summaries, yearly archive and a site search (Ghost doesn’t ship with those features out of the box). Because static sites seem to be a thing now I thought let’s hop onto the static site generator train. I did some subjective research and decided that it will be Jekyll. I’ve chosen Jekyll because it’s quite easy to understand compared to hugo. Although hugo offers GraphQL which allows you to generate blog posts basically from any source including a REST API and Ghost has such an API in place which provides access to all posts. To sum up the evolution of my blog: 2017 - 2018: Wordpress (hosted on a free hoster) 2018 - 2020: Ghost (hosted on Azure) 2020 - 20xx: Jekyll (hosted on GitHub Pages) Since the beginning of my blog I had my DNS zones running on Cloudflare including CDN features. When I migrated from Wordpress to Ghost I also migrated the comments to Disqus -> so for this migration I didn’t need to change anything regarding comments.

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