Employee onboarding often starts in an HR system, while the actual account creation still happens separately in Active Directory and Microsoft Entra ID. With EasyEntraPS, this process can be connected to an external system through a lightweight PowerShell HTTPS listener. The HR system only needs to send the employee’s display name and the EasyEntra template to use. The listener validates the request and then triggers the virtual user template to create the hybrid user. The resulting flow is simple:
HR system → HTTPS POST request → PowerShell listener → EasyEntraPS → Hybrid user creation.
This guide walks through a tested proof of concept and also covers the additional security and infrastructure considerations needed when running the listener unattended.
Prerequisites to Onboard Microsoft 365 Using EasyEntra and a PowerShell HTTPS Listener
Before starting, make sure the following requirements are in place.
Configuring the HTTPS Listener
- The server has a DNS name that callers can resolve.
- You have administrator rights for the initial HTTPS certificate and HTTP.sys configuration.
- PowerShell 7 is installed on the server.
EasyEntra Requirements
- EasyEntra is installed and configured under the Windows account that will run the listener.
- EasyEntraPS is available in PowerShell 7.
- The required Active Directory and Microsoft Entra ID connections are configured in EasyEntra.
- One or more EasyEntra Virtual User Templates are available for the user roles you want to provision.
Important: Configure the required EasyEntra connection profile while signed in with the same Windows account that will run the listener. The account does not need additional administrative privileges to use the configured EasyEntra connections, as EasyEntra securely retrieves the required access tokens from the configuration associated with that user.
1. Identify the Listener Server Name
The HTTPS certificate should match the DNS name that callers use to access the endpoint.
Check the server hostname.
hostname Then retrieve its fully qualified domain name.
[System.Net.Dns]::GetHostEntry($env:COMPUTERNAME).HostName Replace the hostname with the FQDN used in your environment.
2. Create the Onboarding Folder
Create a dedicated folder for the onboarding listener.
New-Item -ItemType Directory -Path "C:\EasyEntra\Onboarding" The listener script will be stored at:
C:\EasyEntra\Onboarding\Run-EasyEntraOnboardingListener.ps1 3. Create the HTTPS Certificate
The listener accepts onboarding information over HTTPS, so Windows needs a certificate for the endpoint.
For this PoC, create a self-signed certificate. Open PowerShell as Administrator and run the below.
$cert = New-SelfSignedCertificate `
-DnsName "demoDC1.demo365.local" `
-CertStoreLocation "Cert:\LocalMachine\My" The certificate subject should match the listener hostname.
This guide uses a self-signed certificate to demonstrate the process. For a production environment, preferably use a certificate issued by your organization's local PKI/Certificate Authority so certificate trust is already available to callers in the domain.
4. Bind the Certificate to Port 8443
Creating the certificate does not automatically associate it with the HTTPS listener.
Generate an application ID.
$AppId = "{$([guid]::NewGuid())}" Then bind the certificate to port 8443.
netsh http add sslcert `
ipport=0.0.0.0:8443 `
certhash=$($cert.Thumbprint) `
appid="$AppId" Once the certificate is successfully added, you can verify the binding by running the following command.
netsh http show sslcert ipport=0.0.0.0:8443 The output will reveal the certificate hash associated with: 0.0.0.0:8443.
Example output:
IP:port : 0.0.0.0:8443
Certificate Hash : <certificate-thumbprint>
Application ID : <application-id>
Certificate Store Name : MY 5. Reserve the Listener URL
Windows HTTP Server API also controls which account can listen on a particular URL. First, identify the account that will run the listener.
whoami From an elevated PowerShell session, run the below to reserve the listener URL.
netsh http add urlacl `
url=https://+:8443/onboard/ `
user="CONTOSO\AutomationUser" Administrator rights are required to configure the SSL binding and URL ACL. The listener account does not need to remain a local administrator simply because elevated rights were required for these initial configuration steps.
6. Trust the Self-Signed Certificate
If you use the self-signed certificate from this PoC, the calling system must trust it.
To export the public certificate, execute the following command.
Export-Certificate `
-Cert $cert `
-FilePath "C:\EasyEntra\Onboarding\OnboardingListener.cer" For a local test, import it into the trusted root certificate store.
Import-Certificate `
-FilePath "C:\EasyEntra\Onboarding\OnboardingListener.cer" `
-CertStoreLocation "Cert:\LocalMachine\Root" If another server will call the listener, that computer must also trust the certificate. This step is normally unnecessary when using a properly issued certificate from an internal PKI that callers already trust.
7. Generate a Shared Secret
The listener should not allow any system that can reach port 8443 to create users. For this PoC, use a GUID as a shared secret.
To generate one:
[guid]::NewGuid().ToString() Use your own generated value. The same GUID must be configured in the listener and in the HR system or other application that calls the endpoint.
8. Create the PowerShell HTTPS Listener
Next, create the HTTPS listener script. This script listens for incoming onboarding requests, validates the shared secret and required values, and then triggers the EasyEntra hybrid user creation cmdlet.
Save the script as:
C:\EasyEntra\Onboarding\Run-EasyEntraOnboardingListener.ps1 Add the following code to the script.
# EasyEntra Hybrid User Onboarding Listener
# Configuration
$Port = 8443
$SharedSecret = "<Your GUID>"
$Prefix = "https://+:$Port/onboard/"
# Load EasyEntraPS
Import-Module "C:\Program Files\PowerShell\7\Modules\EasyEntraPS\EasyEntraPS.psd1" `
-Force `
-ErrorAction Stop
# Create HTTPS listener
$Listener = [System.Net.HttpListener]::new()
$Listener.Prefixes.Add($Prefix)
$Listener.Start()
Write-Host ""
Write-Host "EasyEntra onboarding listener started." -ForegroundColor Green
Write-Host "Listening on: $Prefix"
Write-Host "Press Ctrl+C to stop the listener."
Write-Host ""
try {
while ($Listener.IsListening) {
# Wait for a request
$Context = $Listener.GetContext()
$Request = $Context.Request
$Response = $Context.Response
$StatusCode = 200
$ResponseBody = "OK"
try {
# Only accept POST requests
if ($Request.HttpMethod -ne "POST") {
$StatusCode = 405
$ResponseBody = "Method not allowed"
}
else {
# Read request body
$Reader = [System.IO.StreamReader]::new(
$Request.InputStream,
$Request.ContentEncoding
)
$RawBody = $Reader.ReadToEnd()
$Reader.Dispose()
# Convert JSON payload
try {
$Payload = $RawBody | ConvertFrom-Json -ErrorAction Stop
}
catch {
$StatusCode = 400
$ResponseBody = "Invalid JSON payload"
$Payload = $null
}
# Process request
if ($null -ne $Payload) {
# Validate shared secret
if ($Payload.Secret -ne $SharedSecret) {
$StatusCode = 401
$ResponseBody = "Unauthorized"
}
# Validate required values
elseif (
[string]::IsNullOrWhiteSpace($Payload.DisplayName) -or
[string]::IsNullOrWhiteSpace($Payload.TemplateName)
) {
$StatusCode = 400
$ResponseBody = "DisplayName and TemplateName are required"
}
else {
Write-Host ""
Write-Host "Onboarding request received" -ForegroundColor Cyan
Write-Host "Display name : $($Payload.DisplayName)"
Write-Host "Template : $($Payload.TemplateName)"
Write-Host ""
# Trigger EasyEntra hybrid user creation
$Result = Invoke-EECreateHybridUserFromTemplate `
-DisplayName $Payload.DisplayName `
-TemplateName $Payload.TemplateName
# Prepare JSON response
$ResponseBody = $Result | ConvertTo-Json -Depth 6
$Response.ContentType = "application/json"
Write-Host ""
Write-Host "Onboarding processing finished." -ForegroundColor Green
Write-Host "Status: $($Result.Status)"
Write-Host ""
}
}
}
}
catch {
$StatusCode = 500
$ResponseBody = "Error: $($_.Exception.Message)"
Write-Warning $ResponseBody
}
# Return response to caller
try {
$Buffer = [System.Text.Encoding]::UTF8.GetBytes(
[string]$ResponseBody
)
$Response.StatusCode = $StatusCode
$Response.ContentLength64 = $Buffer.Length
$Response.OutputStream.Write(
$Buffer,
0,
$Buffer.Length
)
$Response.OutputStream.Flush()
}
catch {
Write-Warning "The caller disconnected before the response could be returned."
}
finally {
try {
$Response.OutputStream.Close()
}
catch {
# Connection may already be closed
}
try {
$Response.Close()
}
catch {
# Connection may already be closed
}
}
}
}
catch [System.Management.Automation.PipelineStoppedException] {
Write-Host ""
Write-Host "Stopping listener..." -ForegroundColor Yellow
}
finally {
if ($null -ne $Listener) {
try {
if ($Listener.IsListening) {
$Listener.Stop()
}
$Listener.Close()
}
catch {
# Listener may already be stopped
}
}
Write-Host "EasyEntra onboarding listener stopped." -ForegroundColor Yellow
} Don’t forget to replace the GUID with the one you created earlier.
When an onboarding request reaches the endpoint, the script first validates the request and confirms that the required information is present. It then passes the employee’s display name and selected template to EasyEntra for hybrid user creation. After the operation completes, the result is sent back to the calling system while the listener remains available for the next request.
9. Prepare the EasyEntra Profile
This is an important requirement for unattended execution. EasyEntra stores its connection configuration in the Windows user’s profile. Therefore, the account running the listener must already have the appropriate EasyEntra connections configured.
Using the same Windows account that will run the listener:
- Open EasyEntra interactively.
- Open Connection Manager.
- Configure the required Active Directory connection.
- Associate the AD connection with the correct Entra tenant.
- Authenticate the Microsoft Entra tenant.
- Verify that the EasyEntra license is available.
10. Test the PowerShell Listener
Start the listener manually for the first test.
& "C:\EasyEntra\Onboarding\Run-EasyEntraOnboardingListener.ps1" You should see:
EasyEntra onboarding listener started.
Listening on: https://+:8443/onboard/
Press Ctrl+C to stop the listener. 11. Run the Listener Automatically with Task Scheduler
The listener needs to stay available even when no administrator is logged on. Instead of manually keeping a PowerShell window open, configure Windows Task Scheduler to start it automatically.
Open Task Scheduler and select Action → Create Task. Now, configure the task with the following settings:
- On the General tab, enter EasyEntra Onboarding Listener as the task name. Select the same Windows account that has the required EasyEntra connections configured, choose Run whether user is logged on or not, and enable Run with highest privileges if required.
- On the Triggers tab, create a new trigger and select At startup. This ensures the listener starts automatically when Windows starts.
- On the Actions tab, select Start a program and configure:
- Program/script: C:\Program Files\PowerShell\7\pwsh.exe
- Add arguments: –NoProfile –ExecutionPolicy Bypass -File “C:\EasyEntra\Onboarding\Run-EasyEntraOnboardingListener.ps1″
- Start in: C:\EasyEntra\Onboarding
- On the Settings tab, enable Allow task to be run on demand and set If the task is already running to Do not start a new instance. You can also configure the task to restart if it fails.
- Save the task and provide the account credentials if prompted.
Important: The scheduled task must run under the Windows account that has the required EasyEntra AD and Entra connections configured. Otherwise, the listener may start successfully but EasyEntra will not have the connection information required to create the hybrid user.
12. Verify the Listener
Right-click EasyEntra Onboarding Listener and select Run. Once the task shows Running, verify that the listener is available in PowerShell.
Get-NetTCPConnection -LocalPort 8443 -State Listen -ErrorAction SilentlyContinue Example Output:
LocalAddress LocalPort RemoteAddress RemotePort State
------------ --------- ----------- ---------- -----
0.0.0.0 8443 0.0.0.0 0 Listen If the setup is working, port 8443 should appear in the Listen state. You can then proceed with sending the onboarding request.
13. Test the Onboarding Request
We can now use PowerShell to simulate the request that would eventually come from an HR or onboarding system. Open PowerShell 7 and create the JSON payload.
$json = @{
DisplayName = "Mia Collins"
TemplateName = "SalesUser"
Secret = "YOUR-GENERATED-GUID"
} | ConvertTo-Json And then, send it to the listener.
Invoke-RestMethod `
-Uri "https://demoDC1.demo365.local:8443/onboard/" `
-Method Post ` -Body $json `
-ContentType "application/json" Example output:
Template : EasyEntra-Template-b7417f59@demo365.skrubbeltrang.com (EasyEntra Template SalesUser)
DisplayName : Olivia Turner
Identity : oliviaturner@demo365.skrubbeltrang.com
Domain : demo365.local
Tenant : easy365manager
Type : Hybrid
Status : Completed
Timestamp : 8/17/2026 5:27:15 PM
TaskLog : ... A successful request returns the created user’s details with the status shown as Completed, confirming that the onboarding request was processed successfully.
Security Considerations for Production
This setup is designed as a simple PoC. For production use, replace the self-signed certificate with one issued by your organization’s local PKI and store the shared secret securely.
Restrict access to the listener port to approved systems, such as the HR server, and run the listener with only the permissions required for onboarding. Also consider basic logging and automatic task recovery to keep the endpoint reliable.