Automatically adding devices to an Azure AD group when Autopilot completes with Azure Automation
In this post we will see how to use PowerShell and Azure Automation to automatically add a device when Windows Autopilot is successfully completed.
Context
See below what we want:
- Install devices with Autopilot
- Install things only once Autopilot completes
Autopilot and end time
In Monitor > Autopilot deployments you will get information about Deployment end time. Then you just need to filter on success deployment and you can get devices with Autopilot that completes successfully.
The solution
After giving a look to the monitor report, I started playing with MS Graph and PowerShell to find the appropriate resource.
To know when a new autopilot devices is completely installed the resource to use is: deviceManagement/autopilotEvent
See below through the monitor portal part:
See below through now result using Graph and PowerShell:
The idea is now to automatically add devices from there into a specific Azure AD group.
To do this automatically we will use Azure Automation.
In the script you can choose to add devices in the group as below:
- All devices from the Monitor part
- Only devices installed during last x hours
- Only devices installed during last x days
What does the script ?
The automation script will proceed as below:
1. Get all devices from autopilot devices
OR
1. Get all devices from autopilot devices installed last x hours/days
2. Get the approriate serial number
3. Get the appropriate ID using the serial number
4. Add the device to an Azure AD group using its ID
Get the script
Click on the below GitHub picture to get the script
How to use the script ?
Adding group ID
The idea is to add the device to an Azure AD group when Autopilot is finished.
For this add the group ID into the variable: $Deployment_Completed_Group_ID
Managed identity
The Azure Automation script works with a managed identity.
To make it simple a Managed identity is an Azure AD account that will be used to
Choose how to add devices
As mentioned previously, you can choose to add devices as below:
- All devices from the Monitor part
- Only devices installed during last x hours
- Only devices installed during last x days
In the script you will have to comment/uncomment only the part you want.
See them below:
Azure Automation account
Create the account
1. Go to Azure
2. In the search bar type: Automation accounts
3. Go to Automation accounts
4. Click on Create
5. Type a name
7. Choose a Subscription
8. Choose the Resource group
10. Choose your region
12. In Create Azure Run As Account, select No
13. Click on Create
15. Click on Go to resource
Add modules
1. Go to your automaton account
2. Click on Modules gallery
3. Search: az.Accounts
4. Click on az.Accounts
5. Click on Import
6. Click on OK
7. Wait for importing
Set Managed Identity
1. Go to your automation account
2. Go to Identity (Preview)
3. Go to System assigned
4. Select On
5. Click on Save
6. Click on Yes
Add a group owner
1. Go to your group
2. Go to Owners
3. Add the automation account
Add permissions
Once the Managed Identity has been configured a new Enterprise application will be created.
Then you need to add permissions to do some actions, there permission to get info from the Autopilot events part.
The required permission is the following: DeviceManagementManagedDevices.Read.All
You can get more info there.
To add this permission you will need to use PowerShell, it can't be done through the portal.
For that use the script Assign_permission on my GitHub repo.
You just need to fill below variables:
$TenantID: your tenant ID
$DisplayNameOfMSI: name of your automation account
Azure Automation Runbook
Create a Runbook
1. Go to Azure
2. In the search bar type: Automation accounts
3. Go to your Automation accounts
4. Go to Runbooks
5. Click on + Create a runbook
6. Type a name
7. In Runbook type, select PowerShell
8. Click on Create
Add script in Runbook
The runbook script is located downloaded sources
Add the group ID in the variable $Deployment_Completed_Group_ID.
Test the Runbook
1. Click on Test pane
2. Click on Start
3. Once finished, you should see Completed
Publish the Runbook
1. Go to your Runbook
2. Click on Edit
3. Click on Publish
4. Click on Yes
Schedule the Runbook
1. Go to your Runbook
2. Click on Schedules
3. Click on + Add a schedule
4. Click on Link a schedule to your runbook
5. Click on + Add a schedule
6. Type a schedule name
7. In Recurrence, select Recuring
8. Click on Create
Other solutions
See below some posts from the awesome Niall Brady who uses another solution to do this:
Displaying a welcome page after Windows Autopilot completes
Adding devices to an AAD group after windows autopilot completes part1
Adding devices to an AAD group after windows autopilot completes part2
9 commentaires
Hi,
I'm getting error:
Invoke-WebRequest : The remote server returned an error: (401) Unauthorized. At line:37 char:25
Completed
Environments
------------
{[AzureChinaCloud, AzureChinaCloud], [AzureCloud, AzureCloud], [AzureGermanCloud, AzureGermanCloud], [AzureUSGovernme...
The remote server returned an error: (401) Unauthorized.
Cannot bind argument to parameter 'InputObject' because it is null.
The remote server returned an error: (401) Unauthorized.
Cannot bind argument to parameter 'InputObject' because it is null.
The remote server returned an error: (403) Forbidden.
Cannot bind argument to parameter 'InputObject' because it is null.
I have the same issue. Unfortunately I couldn`t get around it.
Have you assigned permissions ?
I also got the above errors following the green 'completed' entry:
Environments
------------
{[AzureChinaCloud, AzureChinaCloud], [AzureCloud, AzureCloud], [AzureGermanCloud, AzureGermanCloud], [AzureUSGovernme...
The remote server returned an error: (403) Forbidden.
Cannot bind argument to parameter 'InputObject' because it is null.
7/1/2022 2:34:31 PM
System.Management.Automation.ParameterBindingValidationException: Cannot bind argument to parameter 'MemberObjectId' because it is null.
at System.Management.Automation.ParameterBinderBase.ValidateNullOrEmptyArgument(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, Type argumentType, Object parameterValue, Boolean recurseIntoCollections)
at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
at System.Management.Automation.CmdletParameterBinderController.BindParameter(CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
at System.Management.Automation.CmdletParameterBinderController.BindParameter(UInt32 parameterSets, CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
at System.Management.Automation.CmdletParameterBinderController.BindParameters(UInt32 parameterSets, Collection`1 arguments)
at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParametersNoValidation(Collection`1 arguments)
at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
at System.Management.Automation.CommandProcessor.BindCommandLineParameters()
at System.Management.Automation.CommandProcessorBase.DoPrepare(IDictionary psDefaultParameterValues)
at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
device added:
I have waited and tried again but no difference.
Looks like it's failing (404 forbidden) at line 45. Autopilot and Intune parts go through fine:
# Get information from Azure AD part
$Get_DevicesFromAz_info = Invoke-WebRequest -Uri $AzureAD_Devices_URL -Method GET -Headers $headers -UseBasicParsing
Did you manage to get round the 404 forbidden error? I'm seeing the same along with 'Insufficient privileges to complete the operation' even though the permissions have been added. I can't seem to find an Enterprise App for this however, does the Enterprise App show up immediately?
To everyone having issues with the script (403 forbidden), the Automation Account is missing the "Device.Read.All" permissions, you need to edit the Assign_Permissions.ps1 script and replace "DeviceManagementManagedDevices.Read.All" with "Device.Read.All" and run it again to grant the right permissions.
I am getting this error
| Cannot bind argument to parameter 'MemberObjectId' because it is null.
Enregistrer un commentaire