Open Active Directory Users and Computers and turn on View → Advanced Features.
Right-click an object, then choose Properties → Security → Advanced → Effective Access.
Click Select a user, then Object Types…, and tick Service Accounts. It’s unticked by default, so the gMSA won’t be found otherwise.
Enter
ploy-connectorand click View effective access.Check that List contents, Read all properties and Read permissions are all ticked.
Set up the Active Directory connector
The Active Directory connector is a small Windows service that runs on your network, reads identity data from AD on Ploy's behalf, and optionally writes group membership changes back. AD credentials never leave your network; all connections are initiated outbound from the connector to https://api.joinploy.com.
What you need before you start
A domain-joined Windows Server 2019 or later to host the connector service.
PowerShell 5.1+ running as Administrator on the connector host.
The RSAT AD PowerShell module on the host where you will create the gMSA (typically a domain controller):
Install-WindowsFeature RSAT-AD-PowerShellOutbound HTTPS (port 443) from the connector host to
api.joinploy.com.A bearer key from the Ploy admin UI. It must start with
ploy_ct_.
Download the connector
Download
ploy-connector-<version>-windows-amd64.zipfrom the Ploy console.Extract it to
C:\Program Files\Ploy\Connector\. The folder contains:ploy-connector.execonfig.example.yamlINSTALL.txt
Provision a Group Managed Service Account
A gMSA is an AD-managed identity whose password rotates automatically and never needs to be stored. The connector authenticates to AD as this identity, so no password sits on the host.
Create a KDS root key
Run this once per AD forest from a domain controller if you do not already have a KDS root key:
Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10))Create the gMSA
On a DC, as a Domain Admin. Replace CONNECTORHOST with your connector host's computer name:
New-ADServiceAccount -Name ploy-connector -DNSHostName ploy-connector.corp.example.com -PrincipalsAllowedToRetrieveManagedPassword "CONNECTORHOST$"The trailing $ in CONNECTORHOST$ is required because it identifies the computer object, not a user.
On the connector host, as Administrator:
Install-ADServiceAccount ploy-connector
Test-ADServiceAccount ploy-connectorTest-ADServiceAccount must return True. If it returns False, the most common cause is that the host is not in PrincipalsAllowedToRetrieveManagedPassword. Re-run the gMSA creation step with the correct computer name.
Grant AD permissions
In standard AD configurations, authenticated users have read access to user, group, and OU objects, so the gMSA inherits read access automatically. If your environment hardens the directory, make sure the connector can Read on user, group, organizationalUnit, and container objects under your base_dn.
How to check the gMSA can read users, groups, OUs and containers
Write access is only needed if you enable write features. Scope rights to the OU subtree that holds the users and groups Ploy manages, and let inheritance carry them to objects inside it. Run this on a DC as someone who can edit that OU's ACL. Set $gmsa and $ouPath for your environment. Grant only the blocks you need:
PowerShell ACL script for write access
Import-Module ActiveDirectory
$gmsa = "ploy-connector"
$ouPath = "AD:\OU=Ploy-Managed,DC=corp,DC=example,DC=com"
$sid = (Get-ADServiceAccount $gmsa).SID
$userObj = [GUID]'bf967aba-0de6-11d0-a285-00aa003049e2'
$groupObj = [GUID]'bf967a9c-0de6-11d0-a285-00aa003049e2'
$memberProp = [GUID]'bf9679c0-0de6-11d0-a285-00aa003049e2'
$allGuid = [GUID]'00000000-0000-0000-0000-000000000000'
$Allow = [System.Security.AccessControl.AccessControlType]::Allow
$Desc = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::Descendents
$ScopeAll = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All
$acl = Get-Acl -Path $ouPath
# group_management: write the 'member' attribute on groups in the subtree
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$sid,
[System.DirectoryServices.ActiveDirectoryRights]::WriteProperty,
$Allow, $memberProp, $Desc, $groupObj)))
# identity_management: create and delete user objects in the subtree
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$sid,
[System.DirectoryServices.ActiveDirectoryRights]'CreateChild,DeleteChild',
$Allow, $userObj, $ScopeAll)))
# identity_management: full control over the user objects themselves
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$sid,
[System.DirectoryServices.ActiveDirectoryRights]::GenericAll,
$Allow, $allGuid, $Desc, $userObj)))
Set-Acl -Path $ouPath -AclObject $aclThe member rule alone is enough for group_management. The two user-object rules are only needed where the connector provisions accounts. If managed users and groups live under different OUs, run the relevant block against each $ouPath.
To confirm the gMSA can create users in the target OU and write the attributes Ploy sets on users there, run .\ploy-connector.exe doctor. It reports this read-only, without creating anything. It cannot check the Reset Password right this way, and it says so in its output.
Configure the connector
The service reads its config from C:\ProgramData\Ploy\Connector\config.yaml.
Create the directory:
New-Item -ItemType Directory -Force -Path "C:\ProgramData\Ploy\Connector"Copy the example and edit:
Copy-Item "C:\Program Files\Ploy\Connector\config.example.yaml" "C:\ProgramData\Ploy\Connector\config.yaml" notepad "C:\ProgramData\Ploy\Connector\config.yaml"Fill in at minimum:
backend.key— your bearer key, or reference it withenv://PLOY_CONNECTOR_KEY.integrations.<slug>.credentials.url— your DC's LDAPS URL.integrations.<slug>.credentials.base_dn— your domain root DN.
Find your DC's LDAPS URL and base_dn
nltest /dsgetdc:The DC: line shows a domain controller, and Dom Name: shows your domain:
DC: \\DC01.corp.example.com
Dom Name: corp.example.comDrop the leading \ and use that name in the URL:
url: ldaps://DC01.corp.example.com:636
Use the full name, not an IP address. The connector checks the domain controller’s certificate, and the name in the URL has to match it.
To list every domain controller:
Get-ADDomainController -Filter * | Select-Object HostName, SitePick one in the same site as the connector host.
For base_dn:
Get-ADDomain).DistinguishedNameExample config using gMSA authentication:
backend:
key: env://PLOY_CONNECTOR_KEY
integrations:
corp-ad:
type: active_directory
enabled_features: [scan, group_management]
credentials:
url: ldaps://dc01.corp.example.com:636
auth: windows_integrated
base_dn: "DC=corp,DC=example,DC=com"If you source the bearer key from an environment variable, set it at machine scope so the service sees it:
[Environment]::SetEnvironmentVariable('PLOY_CONNECTOR_KEY', 'ploy_ct_...', 'Machine')Machine-scope environment variables only apply to new processes. Restart the service after changing one.
Install and start the service
From an elevated PowerShell:
cd "C:\Program Files\Ploy\Connector"
.\ploy-connector.exe install-service -service-account "CORP\ploy-connector$"
Start-Service PloyConnector
Get-Service PloyConnectorReplace CORP with your domain's NetBIOS name. The trailing $ is required for gMSAs. The service is registered with auto-start, so it survives reboots.
Find your domain’s NetBIOS name
To find your NetBIOS name, run:
(Get-ADDomain).NetBIOSNameVerify the setup
Wait approximately 30 seconds, then open the Ploy admin UI and go to Integrations > Connectors. The connector should report as online with a recent heartbeat.
Tail the local log:
Get-Content -Wait -Tail 50 "C:\ProgramData\Ploy\Connector\logs\connector.log"On a healthy startup you will see
connector starting, thenmanifest registered, then periodicscan completedlines.Check Windows Event Viewer under Applications and Services Logs > Ploy Connector. Errors are written here even if the log file path is unreachable.
Run
.\ploy-connector.exe doctorfor an explicit pass/fail result across the whole setup: config, backend connectivity, AD access, and state.
Check the setup with doctor
ploy-connector.exe doctor checks the whole connector setup and prints a PASS, WARN, or FAIL result for each check, with a suggested fix under anything that is not a PASS. It is read-only: it never changes Active Directory or the connector's state, and its output is safe to send to Ploy support.
From an elevated PowerShell on the connector host:
cd "C:\Program Files\Ploy\Connector"
.\ploy-connector.exe doctorRun it elevated: doctor registers a temporary service under the connector service's account, normally the gMSA, so the checks describe the account the connector actually runs as. The first line of the report names that account. Add -report doctor.txt to write the report to a file you can send to Ploy support.
For the full list of checks, the other options, and fixes for common findings, see Troubleshoot the connector.
Update or uninstall
To update, stop the service, replace the binary, and restart:
Stop-Service PloyConnector
Copy-Item .\ploy-connector.exe "C:\Program Files\Ploy\Connector\" -Force
Start-Service PloyConnectorConfig and state persist across upgrades. After restarting the service, run .\ploy-connector.exe doctor to confirm the updated connector still passes its checks.
To uninstall:
.\ploy-connector.exe uninstall-service
Remove-Item -Recurse "C:\ProgramData\Ploy\Connector"
Remove-ADServiceAccount ploy-connector # run on a DCUse password-based authentication instead of gMSA
Use this only if your environment cannot use a gMSA. In config.yaml, set auth: simple and supply bind_user plus bind_password. The service can then run as LocalSystem; omit -service-account from the install command.
integrations:
corp-ad:
type: active_directory
enabled_features: [scan]
credentials:
url: ldaps://dc01.corp.example.com:636
auth: simple
bind_user: "CN=ploy-connector,OU=Service Accounts,DC=corp,DC=example,DC=com"
bind_password: env://AD_BIND_PASSWORD
base_dn: "DC=corp,DC=example,DC=com"We strongly recommend reading the password from an environment variable rather than embedding it in the file.
Corporate proxy and internal CAs
The connector honours HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables set at machine scope. User-info form http://user:pass@proxy:8080 is supported.
For internal CAs, set tls.ca_bundle in config.yaml to a PEM file path. Use tls.ca_bundle_append: true to add to the system root store rather than replace it.