Our module allows you to Domain Join a device that doesn’t have access to the Domain Controller (through the company network or via VPN). It’s an alternative to using Azure Hybrid Join.
While Azure Hybrid Join adds a device to Azure AD (Entra) and local AD, this option allows joining a device to local AD only. Meanwhile, Hybrid Join is limited regarding naming convention and only allows the defining of the prefix.
With this solution, it’s possible to define a prefix and to use a serial number of computers for the computer name.
Who is this for?
You can benefit from using this module whether you’re a XOAP user or not. Here’s how:
a) If you’re a XOAP user, simply set up Windows clients for use of Offline Domain Join via Azure Blob Storage using this module and XOAP console.
b) If you’re not a XOAP user, use this module in your own DSC environment, or use PowerShell scripts inside this module to create their own automation alternative for Offline Domain Join.
🚀 Want to experience everything XOAP has to offer? Create your free account here!
What does this module do?
To explain further, this module will rename the computer using the serial number and defined prefix. Afterwards, it’ll make an Offline Domain Join of the device via Azure Blob storage; if wanted.
The computer creates a request and posts it on a defined location on Azure Blob. Then, the Domain Controller will take that request and post a response on Azure Blob. This response file is then read by a computer – and the computer makes Offline Domain Join. Furthermore, the certificate will be imported from Azure Blob.
What do I need to know before I start?
To understand how to use it, knowledge of PowerShell, Active Directory and Azure Storage is needed along with these 3 components:
- Server-side: modify Domain Controller to allow for Offline Domain Join
- Azure Blob Storage: storage to host files needed for Offline Domain Join
- XOAPOfflineDomainJoinViaBlobDSC: to set up Windows client to create request and fetch the answer for Offline Domain Join
List of prerequisites:
- AzureAZ PowerShell Module (if not installed ‘Az.Accounts’ and ‘Az.Storage’ submodules are going to be installed while running this DSC module);
- ComputerManagementDsc in version 8.5.0;
- Azure Blob storage;
- Local Active Directory;
- PowerShell script that reads the request from Azure Blob Storage and sets response file and machine certificate to Azure Blob storage (example below).
$WarningPreference = "SilentlyContinue"
$Domain = "test.local.com"
$OU = "OU=Notebooks,OU=Koeln,DC=test,DC=local,DC=com"
$Tenant_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$Subscription_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$ResUsername = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$SAccountname = 'xoapdeployments'
$ContainerName = "adjoin"
$FExt = ".blb"
$BlobFolder ="adblob"
$RequestFolder = "request"
$JoinName =""
Set-Location C:\Scripts
#SecPass.exe generetes password for Azure access
$SecPassStr = cmd /c .\SecPass.exe $args 2`>`&1
$cred = New-Object System.Management.Automation.Pscredential($ResUsername, (ConvertTo-SecureString -String $SecPassStr))
$ARMA = Add-AzureRmAccount -ServicePrincipal -Credential $cred -TenantId $Tenant_ID -Subscription $Subscription_ID
$ARMA
$storageContainer = Get-AzureRmStorageAccount | where {$_.StorageAccountName -eq $SAccountname} | Get-AzureStorageContainer
$ComputerFiles = $storageContainer | Get-AzureStorageBlob | where {$_.Name.Contains($RequestFolder) -and !($_.Name.Contains("flag.flg"))} | Select-Object "Name" ,"LastModified"
# $ComputerFiles
if($ComputerFiles) {
foreach($Computerfile in $ComputerFiles) {
$JoinName = $ComputerFile.Name.Replace("/","\")
# $JoinName
$storageContainer | Remove-AzureStorageBlob -Container $ContainerName -Blob ($JoinName) -Force
$JoinName = $JoinName.SubString(8)
$ADblobfile = $Computername + ".blob" -f $computer
$BlobName = ".\" + $JoinName + $FExt
# $BlobName
$run = "djoin.exe /provision /domain {0} /MachineOU {1} /machine {2} /savefile {3} /reuse /rootcacerts" -f $Domain, $OU, $JoinName, $BlobName
# $run
Invoke-Expression $run
$StorageBlob = $BlobFolder + "\" + $JoinName + $FExt
# $Storage
$storageContainer | Set-AzureStorageBlobContent –File $BlobName -Blob $StorageBlob -Properties @{"ContentType" = "text/plain"}
$storageContainer | Remove-AzureStorageBlob -Blob ($RequestFolder + "\" + $JoinName) -Force
Remove-Item -Path $BlobName
}
}
Remove-AzureRmAccount -Username $ResUsername
Available resources and syntax
OfflineDomainJoinViaBlob [String] #ResourceName
{
[DependsOn = [String[]]]
[PsDscRunAsCredential = [PSCredential]]
Tenant_ID = [String]
Subscription_ID = [String]
Username = [String]
Password = [String]
SAccountname = [String]
ContainerName = [String]
RequestFolder = [String]
BlobFolder = [String]
CertFolder = [String]
[TimeoutInMinutes = [Int32]]
[RenameComputerUsingSerial = [Boolean]]
[ComputerNamePrefix = [String]]
[RebootAfterDomainJoin = [Boolean]]
}
Saccountname = Storage Account Name
🖱️ Ready to get started? Download this module below!
Download Offline Domain Join
to Domain Join a device that doesn’t have access to Domain Controller