Too lazy to sign your PowerShell scripts? Yes of course it provides security benefits but performing the steps manually can be easily forgotten and re-signing needs to happen after every script change. Because I like CI/CD topics and have not found a solution on the internet I decided to build a solution based on Azure capabilities. Furthermore, I wanted a solution which does not require to hand out the code signing certificate to the respective script author which can be useful if you have a bunch of people writing PowerShell scripts.
From a personal perspective, I would also recommend signing scripts you hand over to customers to ensure the integrity of the scripts because as soon as the script gets changed the signature is invalid.
You can find more general recommendations about script signing in the PowerShell docs.
Solution overview # The key vault will store the code signing certificate with an access policy that allows access from the Azure DevOps pipeline.
The pipeline consists of the following steps:
Import code signing certificate The certificate is supplied as secret in a variable group which is linked to the key vault Access to the key vault is granted with a service connection (service principal) Sign PowerShell scripts which contain a “magic token” All *.ps1 within the attached repository will be enumerated To control which scripts will be signed only those with the “magic token” get processed The “magic token” gets removed before signing the script Publish signed PowerShell scripts as pipeline artifacts To make them available for download
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.
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.
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 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
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.
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:
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.
With Microsoft Graph we have powerful automation and configuration management capabilities. To further simplify this process I built the “Modern Workplace Concierge”. It is an ASP.NET application which uses an Azure AD multi tenant app to access the Microsoft Graph API on behalf to perform export and import tasks. The project uses the Microsoft Graph Beta API to access your tenant’s data.
Modern Workplace Concierge # The Modern Workplace Concierge allows you to:
Import and export Intune configuration and settings Import and export Conditional Access policies Download OSD ready offline Autopilot profiles Download stored PowerShell scripts in Intune (as PowerShell) This allows you to import your existing Intune and Conditional Access configuration in new tenants or demo tenants. The files in JSON format can be used for further processing or documentation.
And this all via web browser no client side prerequisites or PowerShell code is required!
The Modern Workplace Concierge The project and more information is available on GitHub feel free to provide feedback there.
That's how I backup my Intune configuration with the #ModernWorkplaceConcierge. Curious? Give it a try. Of course also supporting imports .https://t.co/30H8b0olLn pic.twitter.com/g5X58l1e1i
— Nicola Suter (@nicolonsky) December 3, 2019 More Information:
I’m thrilled to introduce the intune-drive-mapping-generator which creates PowerShell scripts to map network drives with Intune. The tool is open source and built on ASP.NET Core MVC.
The intune-drive-mapping-generator is your tool of choice to:
Generate an Intune PowerShell script to map network drives on Azure AD joined devices Seamlessly migrate existing network drive mapping group policies Generate a network drive mapping configuration from scratch Use an existing Active Directory group as a filter to deploy all your drive mapping configurations within one script This all happens without scripting effort. You receive a fully functional PowerShell script for the deployment with Intune.
Architecture # This tool is designed to work best with the following components although it can be useful for other purposes(?) :
Azure AD Joined and Intune enrolled Windows 10 devices Synced user account from Active Directory to Azure Active Directory (Azure AD Connect) On-premises file servers Howto # Export existing group policy # To convert your existing drive mapping group policy configuration, save the GPO as XML report with the group policy management console.