July 14, 2022 / by Adam Murray / In tech
Managing on-premise Active Directory with Azure Function
Recently Tikabu was doing some work with a customer to automate service requests that required modification of Active Directory group memberships. While this is straight forward when on-premise, in this case the requests were being generated in the cloud and therefore required a mechanism to talk to Active Directory on-premise from the Internet.
We considered a couple of options
- Azure Automation account using a hybrid worker
- Azure Function using a Hybrid Connection
- A custom solution
After Googling the options, we didn’t find any information about people successfully using option 2 with an Azure Function so we decided to run a quick proof of concept which allowed us to prove it is possible, though we don’t necessarily recommend it.
There are two main challenges we needed to overcome, and we will drill into how we resolved each of these issues
- The Active Directory PowerShell module is built into Windows as an optional feature and not available on the PowerShell Gallery. We followed this blog to create a portable Active Directory module which we could put inside our Azure Function
- We needed a way to talk to Active Directory on-premise. App Service Hybrid Connection is the piece we needed to make this possible. We followed this blog to get the Hybrid Connection setup. Microsoft also have some good information. For more details on how Hybrid Connections work have a look at this article. We setup the hybrid connection to talk to a domain controller on port 9389 which is Active Directory web services and is used by the Active Directory module.
We needed a Windows app service plan for the solution to work as the Active Directory module requires Windows. The basic plan or above is required as Hybrid Connections only work on Basic, Standard and Premium plans. This means you can’t use consumption or shared plans.
One other thing to note is that you need to set the Azure Function runtime to 64 bit as the PowerShell module is 64 bit.
Below is the test function we used to get a group and add a group member.
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
$pw = "VerySecretPW1!" | ConvertTo-SecureString -AsPlainText -force # You should use keyvault to store your account details
$cred = [pscredential]::new('test',$pw)
Get-ADGroup testgroup -Credential $cred -server test-dc
Get-ADGroupMember testgroup -Credential $cred -server test-dc
Add-ADGroupMember testgroup -members test -Credential $cred -server test-dc
Get-ADGroupMember testgroup -Credential $cred -server test-dc
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $body
})
The only change to a standard PowerShell Azure function is adding the Modules folder and including the ActiveDirectory standalone module we created.
This topic is discussed further here