Hello,
This is a long and overdue update on a solution I started working on last year to allow my organization to use the modern driver management solution without the need of the custom webservice. I also wanted the solution to use the built-in task sequence steps as much as possible to allow other administrators to customize the solution to their need without the need to go modify a big PowerShell script.
You can read the original blog posts here:
Modern Driver Management with the Administration Service Modern BIOS Management with the Administration Service
Notable improvements
- The solution now works for clients on the internet by querying the AdminService over a cloud management gateway (CMG) Bonus: It works in WinPE! You can do a complete reinstallation of a device over CMG using this solution to dynamically apply bios updates and drivers at the same time during the task sequence.
- The solution now supports 7-Zip and Wim driver packages
- Improvements to handle driver packages using the DisplayVersion property instead of ReleaseId (ex: 20H2 instead of 2009)
Prerequisites to use the solution over CMG
A working CMG
There are multiple blog articles and guides online to help you set up your CMG. Here are some links that helped me:
- Official documentation/guidance from Microsoft
- CMG Guide from System Center Dudes
- CMG Guide from Prajwal Desai
Personally, for my lab, I used the Let’s Encrypt Cloud Management Gateway blog post by Nathan Ziehnert to set up my CMG.
Additional configuration to use the AdminService over CMG
There is some additional configuration that is needed to be able to query the AdminService over the cloud management gateway.
Once again, another one of Nathan’s blog post helped me: Securing Access to the ConfigMgr AdminService Over Cloud Management Gateway
There are 2 things I had to do differently in the Authentication section:
- Add a platform and select “Mobile and desktop applications” and check the box for : https://login.microsoftonline.com/common/oauth2/nativeclient
- Select “Yes” to Allow public client flows
How to query the AdminService over CMG?
I started my research by reading the blog post from Sandy Zeng here: https://msendpointmgr.com/2019/07/16/use-configmgr-administration-service-adminservice-over-internet/
Also, at the same time, when I was looking at my application registration in the Azure Portal I saw this notification:
After inspecting Sandy’s script, I confirmed that it was using Azure Active Directory Authentication Library (ADAL), so I wanted to make my solution work with MSAL instead of ADAL.
After doing some research, I found the perfect PowerShell module to help me: MSAL.PS
With the help of that module, I was easily able to get an access token that is needed to query the AdminService over CMG.
Using the MSAL.PS module
Here is a sample script I used to test retrieving an access token with the MSAL.PS module:
And here is what the result looks like:
Now that I have an access token, I can easily query the AdminService over CMG. I reused the same part of the code used by Sandy to do this:
In the example above, I was successfully able to retrieve information for 36 packages from the AdminService over CMG.
Improvements to Invoke-GetPackageIDFromAdminService
Now that I knew what information I needed to use to query the AdminService over CMG, I was ready to make the necessary modifications to my script.
1) New parameters and ParameterSets
Depending on if the client is on the internet or not, my script would require a different set of parameters. This was the perfect opportunity to use parameter sets.
|
|
2) Verify, Install and Import the MSAL.PS module
I wrote a function to handle installing & importing the MSAL.PS.
The tricky part here is that the MSAL.PS module requires us to accept the license agreement before we can install the module. There is a parameter -AcceptLicense for the Install-Module function but it is only available in the PowerShellGet module version 2 or higher.
This function checks for the availability of the MSAL.PS module and if it’s not there it will check for the prerequisites to install before it can import the module.
|
|
What about WinPE? PowerShell Gallery does not work in WinPE!
You are right, by default PowerShell Gallery does not work in WinPE. To solve this issue, you have 2 options:
- Add PowerShell Gallery support to your boot image:
- See this post by David Segura on how it can be achieved: https://www.osdeploy.com/blog/2021/winpe-powershell-gallery
- The easiest way to add PowerShellGallery support to your boot image is to use a Universal WinPE that can be created with the OSD PowerShell module. Use this as a base for your boot image in Configuration Manager and you will be able to install modules from PSGallery directly in WinPE.
- Manually install the MSAL.PS module during the task sequence before you run the script to query the AdminService:
- Create a package with the saved module and distribute it to your CMG
- Edit the package in the “Manually install MSAL.PS module” step:
- Create a package with the saved module and distribute it to your CMG
Both options will allow you to install and import the MSAL.PS module in WinPE.
If you decide to go with enabling support for PowerShell Gallery in WinPE, you can disable the step to manually install the module in the task sequence.
3) Querying the AdminService
Now, depending on what parameters were used, we will query the AdminService locally or via the CMG:
|
|
The rest of the script to filter and select the most suitable package did not change.
Improvements to the task sequence
Now that the script itself supports querying over CMG, I needed to make some adjustments to the “Query AdminService for PackageID” task sequence to properly call the script with the right parameters.
1) Is the client on Internet?
We need to determine if the device running the task sequence is on Internet or on the corporate network (intranet).
First, we try using the _SMSTSIsClientOnInternet task sequence variable:
Note: In my limited testing, I found that if a task sequence does not reference any package, this variable may not be set.
If the “ClientIsOnInternet” is still not set after this step and device is not in WinPE, we use the following PowerShell command to determine if the device is on Internet:
|
|
2) Additional Parameters for Internet clients
Here you fill out your environment-specific information. The additional parameters needed for CMG support are:
- ExternalUrl: The ExternalUrl to access the AdminService from your CMG. The following query can be used to find the ExternalUrl:
- TenantId: Your Azure AD Tenant ID
- ClientId: The Client ID of the application registration that you created to interact with the AdminService. See additional configuration to use the AdminService over CMG for details.
- ApplicationIdUri: The application ID Uri for your application registration. The default value of “https://ConfigMgrService” will probably be OK for most people.
3) Running the script with the right parameters
Depending on the value of the “ClientIsOnInternet” variable, we run the script with different parameters.
If the client is determined to be intranet, use the intranet parameters:
If the client is on Internet, use the internet parameters:
The end result
You can now use the Modern Driver Management and Modern BIOS Management solution for Internet clients just like you are doing with your intranet clients.
If you are on Current Branch 2010 or later, you can use a boot media to run bare metal deployment on the Internet and still use the Modern Driver/BIOS Management solution.
How do I set this up in my environment?
- Download the task sequences here.
- Import the task sequences in your environment
- Configure the parameters correctly in the “Query AdminService for PackageID” task sequence:
- Add the “Apply Driver Package” and/or “Apply BIOS Package” task sequences in your existing task sequences.
For example on what you can do with these task sequences, see my previous blog posts:
- https://sysmansquad.com/2020/05/15/modern-driver-management-with-the-administration-service/
- https://sysmansquad.com/2020/06/18/modern-bios-management-with-the-administration-service/
What if I have multiple CMGs?
There is nothing stopping you from writing a small script to detect/check which CMG to use and then set the “AS_ExternalUrl” variable to whatever you want.
Now you have support for multiple CMGs 🙂
A note on the task sequence size
Currently, the scripts used in this solution are added directly in the task sequence instead of referencing a package containing the scripts. As you can see below, the task sequence size can be somewhat big:
If you are concerned about the total size of the task sequence, you could store the scripts in a package instead and this would greatly reduce the size of the task sequence.
Reference regarding task sequence size: https://docs.microsoft.com/mem/configmgr/osd/deploy-use/manage-task-sequences-to-automate-tasks#reduce-the-size-of-task-sequence-policy
Links
MDM-AdminService GitHub repository
Charles Tousignant Contributor
Charles, a.k.a. 'No Remote Users' from MMS 2019, is a senior analyst working in the public sector focusing on Windows and systems management.