This guide covers the deployment of the Agent Directory schema extension, event log provider, and PowerShell management module in Active Directory environments.
| Component | Required Membership |
|---|---|
| Schema Extension | Schema Admins |
| Container Creation | Enterprise Admins |
| Tool Registration | Domain Admins |
| Event Log Provider | Local Administrator (on each DC) |
| PowerShell Module | None (user-level) |
- Windows Server 2016 or later Domain Controllers
- Active Directory Forest Functional Level: Windows Server 2016+
- PowerShell 5.1 or later
- .NET Framework 4.7.2 or later
- IANA Private Enterprise Number (PEN) obtained for production OIDs
- Schema extension tested in isolated lab environment
- Change management approval obtained
- Rollback plan documented
- Backup of System State on all DCs completed
- AD replication health verified
- Schema Master DC identified and accessible
-
Deploy Test Forest
- Create an isolated test forest with at least 2 DCs
- Do NOT create trusts with production environment
-
Import Test Data
# Create test OUs and users for delegation testing New-ADOrganizationalUnit -Name "Test-Agents" -Path "DC=test,DC=local" New-ADUser -Name "TestOwner" -Path "OU=Users,DC=test,DC=local"
-
Install Schema Extension
.\schema\install-schema.ps1 -Verbose
-
Verify Schema Objects
# Check attributes exist Get-ADObject -SearchBase "CN=Schema,CN=Configuration,DC=test,DC=local" ` -Filter "name -like 'msDS-Agent*' -or name -like 'msDS-Sandbox*'" | Select-Object Name # Check classes exist Get-ADObject -SearchBase "CN=Schema,CN=Configuration,DC=test,DC=local" ` -Filter "name -eq 'msDS-Agent' -or name -eq 'msDS-AgentTool'" | Select-Object Name
-
Test Agent Creation
Import-Module .\powershell\AgentDirectory # Create agent (user object) New-ADAgent -Name "test-agent-01" ` -Type "assistant" ` -TrustLevel 2 ` -Owner "CN=TestOwner,OU=Users,DC=test,DC=local" # Create sandbox (computer object) and link $sandbox = New-ADAgentSandbox -Name "test-sandbox-01" -SecurityProfile "bwrap" Set-ADAgent -Identity "test-agent-01" -AddSandbox $sandbox.DistinguishedName Get-ADAgent -Identity "test-agent-01"
-
Test Tool Access
Grant-ADAgentToolAccess -Identity "test-agent-01" -Tool "microsoft.powershell" Test-ADAgentToolAccess -Identity "test-agent-01" -Tool "microsoft.powershell"
-
Test Authentication
Install-ADAgentSPN -Identity "test-agent-01" Test-ADAgentAuthentication -Identity "test-agent-01" -AuthType Kerberos
# Run pre-flight checks
.\schema\install-schema.ps1 -PreflightOnly
# Expected output:
# [OK] Running as Schema Admin
# [OK] Schema Master DC reachable: DC01.corp.contoso.com
# [OK] AD replication healthy
# [OK] No conflicting schema objects found
# [OK] OID range available-
Connect to Schema Master DC
# Identify Schema Master $schemaMaster = (Get-ADForest).SchemaMaster Enter-PSSession -ComputerName $schemaMaster
-
Run Schema Installation
# On Schema Master DC cd C:\AgentDirectory .\schema\install-schema.ps1 -Verbose
-
Verify Installation
# Check schema version $schema = Get-ADObject -Identity "CN=Schema,CN=Configuration,DC=corp,DC=contoso,DC=com" -Properties objectVersion Write-Host "Schema Version: $($schema.objectVersion)" # List agent attributes Get-ADObject -SearchBase "CN=Schema,CN=Configuration,DC=corp,DC=contoso,DC=com" ` -Filter "name -eq 'msDS-Agent' -or name -eq 'msDS-AgentTool' -or name -eq 'msDS-AgentSandbox'" | Select-Object Name, ObjectClass
-
Force Schema Cache Refresh
# On all DCs $dcs = (Get-ADDomainController -Filter *).HostName foreach ($dc in $dcs) { Invoke-Command -ComputerName $dc -ScriptBlock { $root = [ADSI]"LDAP://RootDSE" $root.Put("schemaUpdateNow", 1) $root.SetInfo() } }
-
Wait for Replication
# Check replication status repadmin /syncall /APed # Monitor until complete repadmin /showrepl * | Select-String "Last attempt"
# Create Agent container
$systemDN = "CN=System,DC=corp,DC=contoso,DC=com"
New-ADObject -Name "Agents" -Type "container" -Path $systemDN
# Create Agent Tools container
New-ADObject -Name "Agent Tools" -Type "container" -Path $systemDN
# Create Agent Sandboxes container
New-ADObject -Name "Agent Sandboxes" -Type "container" -Path $systemDN
# Set permissions on containers
$agentContainer = "CN=Agents,CN=System,DC=corp,DC=contoso,DC=com"
# Add appropriate ACLs...# Import default tool definitions
.\schema\install-schema.ps1 -ToolsOnly# On each DC
.\events\Install-EventLog.ps1 -Verbose
# Verify installation
Get-WinEvent -ListLog "Microsoft-AgentDirectory/*"-
Create GPO for Event Log Settings
New-GPO -Name "Agent Directory - Event Log Settings"
-
Import ADMX Template
- Copy
events\GPO\AgentAuditPolicy.admxtoC:\Windows\PolicyDefinitions - Copy
events\GPO\en-US\AgentAuditPolicy.admltoC:\Windows\PolicyDefinitions\en-US
- Copy
-
Configure Settings
- Computer Configuration → Administrative Templates → Agent Directory
- Set log size, retention, and audit levels
-
Link GPO
New-GPLink -Name "Agent Directory - Event Log Settings" ` -Target "OU=Domain Controllers,DC=corp,DC=contoso,DC=com"
# On collector server
.\examples\configure-event-forwarding.ps1 -CollectorMode
# On DCs (source)
.\examples\configure-event-forwarding.ps1 -SourceMode -CollectorServer "collector.corp.contoso.com"# Copy module to PowerShell modules path
Copy-Item -Path ".\powershell\AgentDirectory" `
-Destination "$env:ProgramFiles\WindowsPowerShell\Modules" `
-Recurse
# Verify installation
Get-Module -ListAvailable AgentDirectory# Publish to internal gallery
Publish-Module -Path ".\powershell\AgentDirectory" `
-Repository InternalGallery `
-NuGetApiKey $apiKey
# Install from gallery
Install-Module -Name AgentDirectory -Repository InternalGalleryPackage the module for deployment via configuration management:
# Create package
$packagePath = "C:\Packages\AgentDirectory"
Copy-Item -Path ".\powershell\AgentDirectory" -Destination $packagePath -Recurse
# Create install script
@'
$targetPath = "$env:ProgramFiles\WindowsPowerShell\Modules\AgentDirectory"
if (Test-Path $targetPath) { Remove-Item $targetPath -Recurse -Force }
Copy-Item -Path ".\AgentDirectory" -Destination "$env:ProgramFiles\WindowsPowerShell\Modules" -Recurse
'@ | Out-File "$packagePath\Install.ps1"# Agent Administrators - Full control over agents
New-ADGroup -Name "AG-Admins-Agents" `
-GroupScope Global `
-GroupCategory Security `
-Path "OU=Admin Groups,DC=corp,DC=contoso,DC=com"
# Agent Operators - Create and manage agents
New-ADGroup -Name "AG-Operators-Agents" `
-GroupScope Global `
-GroupCategory Security `
-Path "OU=Admin Groups,DC=corp,DC=contoso,DC=com"
# Tool grants groups
New-ADGroup -Name "AG-Tools-Office-Basic" -GroupScope Global -GroupCategory Security
New-ADGroup -Name "AG-Tools-PowerShell" -GroupScope Global -GroupCategory Security
New-ADGroup -Name "AG-Tools-Management" -GroupScope Global -GroupCategory Security$agentContainer = "AD:CN=Agents,CN=System,DC=corp,DC=contoso,DC=com"
# Grant AG-Admins-Agents full control
$acl = Get-Acl $agentContainer
$admins = Get-ADGroup "AG-Admins-Agents"
$rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$admins.SID, "GenericAll", "Allow", "Descendents"
)
$acl.AddAccessRule($rule)
Set-Acl $agentContainer $aclImport-Module AgentDirectory
# Create a test agent (user object)
$agent = New-ADAgent -Name "pilot-agent-01" `
-Type "assistant" `
-Owner "CN=IT Admins,OU=Groups,DC=corp,DC=contoso,DC=com" `
-TrustLevel 1 `
-Model "claude-opus-4-5" `
-Description "Pilot AI assistant for IT operations"
# Create sandbox (computer object) for the agent
$sandbox = New-ADAgentSandbox -Name "pilot-sbx-01" `
-SecurityProfile "bwrap" `
-Description "Sandbox for pilot agent"
Set-ADAgent -Identity "pilot-agent-01" -AddSandbox $sandbox.DistinguishedName
# Grant basic tool access
Grant-ADAgentToolAccess -Identity $agent -Tool "filesystem.read", "microsoft.teams"
# Enable the agent
Enable-ADAccount -Identity $agent.DistinguishedName# Verify agent class
$agentClass = Get-ADObject -SearchBase "CN=Schema,CN=Configuration,DC=corp,DC=contoso,DC=com" `
-Filter "name -eq 'msDS-Agent'" -Properties *
$agentClass | Select-Object Name, subClassOf, systemMustContain, systemMayContain
# Verify tool class
$toolClass = Get-ADObject -SearchBase "CN=Schema,CN=Configuration,DC=corp,DC=contoso,DC=com" `
-Filter "name -eq 'msDS-AgentTool'" -Properties *
$toolClass | Select-Object Name, subClassOf
# Verify sandbox class
$sandboxClass = Get-ADObject -SearchBase "CN=Schema,CN=Configuration,DC=corp,DC=contoso,DC=com" `
-Filter "name -eq 'msDS-AgentSandbox'" -Properties *
$sandboxClass | Select-Object Name, subClassOf# Check all DCs have schema changes
$dcs = (Get-ADDomainController -Filter *).HostName
foreach ($dc in $dcs) {
$result = Get-ADObject -Server $dc `
-SearchBase "CN=Schema,CN=Configuration,DC=corp,DC=contoso,DC=com" `
-Filter "name -eq 'msDS-Agent' -or name -eq 'msDS-AgentSandbox'"
Write-Host "$dc : $(if ($result) {'OK'} else {'MISSING'})"
}# Create a test event
Write-ADAgentEvent -EventId 1000 -Message "Test event" -AgentName "test"
# Verify event logged
Get-WinEvent -LogName "Microsoft-AgentDirectory/Operational" -MaxEvents 1# List all cmdlets
Get-Command -Module AgentDirectory
# Test basic operations
Get-ADAgent | Select-Object Name, Type, TrustLevel
Get-ADAgentTool | Select-Object Identifier, DisplayName, RiskLevel
Get-ADAgentSandbox | Select-Object Name, SecurityProfile, StatusSchema objects cannot be deleted, only deactivated:
# Deactivate agent class (will prevent new agent creation)
$agentClass = Get-ADObject -SearchBase "CN=Schema,CN=Configuration,DC=corp,DC=contoso,DC=com" `
-Filter "name -eq 'msDS-Agent'"
Set-ADObject $agentClass -Replace @{isDefunct=$true}# Remove agents first
Get-ADAgent | Remove-ADAgent -Confirm:$false
# Remove tools
Get-ADAgentTool | Remove-ADAgentTool -Confirm:$false
# Remove sandboxes
Get-ADAgentSandbox | Remove-ADAgentSandbox -Confirm:$false
# Remove containers
Remove-ADObject "CN=Agents,CN=System,DC=corp,DC=contoso,DC=com" -Recursive
Remove-ADObject "CN=Agent Tools,CN=System,DC=corp,DC=contoso,DC=com" -Recursive
# Remove sandbox container
Remove-ADObject "CN=Agent Sandboxes,CN=System,DC=corp,DC=contoso,DC=com" -Recursive.\events\Uninstall-EventLog.ps1Remove-Item "$env:ProgramFiles\WindowsPowerShell\Modules\AgentDirectory" -Recurse -Force| Event ID | Severity | Alert Threshold |
|---|---|---|
| 2001 | Warning | >5 per hour per agent |
| 2020 | Critical | Any occurrence |
| 5020 | Critical | Any occurrence |
| 6002 | Critical | Any occurrence |
| 6020 | Critical | Any occurrence |
# Run daily health check
.\examples\health-check.ps1 | Export-Csv "C:\Logs\agent-health-$(Get-Date -Format 'yyyyMMdd').csv"Monitor these counters on DCs:
- LDAP searches for Agent container
- Authentication events for agent accounts
- Kerberos ticket issuance for AGENT/* SPNs
Error: Insufficient permissions to modify schema
Solution: Verify membership in Schema Admins group. Log off and on to refresh token.
Error: The specified class is not defined in the schema
Solution: Force schema cache refresh on target DC:
$root = [ADSI]"LDAP://RootDSE"
$root.Put("schemaUpdateNow", 1)
$root.SetInfo()
Error: The specified channel was not found
Solution: Re-run Install-EventLog.ps1 with -Force parameter
Error: Agent trust level insufficient
Solution: Check both agent trust level and tool required trust level:
Get-ADAgent -Identity <agent> | Select TrustLevel
Get-ADAgentTool -Identity <tool> | Select RequiredTrustLevel
| Component | Log Location |
|---|---|
| Schema Installation | Event Log: Directory Service |
| Agent Operations | Event Log: Microsoft-AgentDirectory/Operational |
| PowerShell Module | $env:LOCALAPPDATA\AgentDirectory\Logs |
For issues with the Agent Directory extension:
- Check troubleshooting guide above
- Review event logs for specific error messages
- Collect diagnostic information:
.\examples\collect-diagnostics.ps1 -OutputPath "C:\Support\diag-$(Get-Date -Format 'yyyyMMddHHmm')"