SyncAgent.ps1
Add-Type -AssemblyName System.Web # Registers Syncgent to the Azure AD # Apr 2nd 2019 # Sep 7th 2022: Added UpdateTrust function Register-SyncAgent { <# .SYNOPSIS Registers the Sync agent to Azure AD and creates a client certificate or renews existing certificate. .DESCRIPTION Registers the Sync agent to Azure AD with given machine name and creates a client certificate or renews existing certificate. The filename of the certificate is <server FQDN>_<tenant id>_<agent id>_<cert thumbprint>.pfx .Example Get-AADIntAccessTokenForPTA -SaveToCache Register-AADIntPTAAgent -MachineName "server1.company.com" Sync Agent (005b136f-db3e-4b54-9d8b-8994f7717de6) registered as server1.company.com Certificate saved to server1.company.com_513d8d3d-7498-4d8c-85ed-b485ed5c39a9_005b136f-db3e-4b54-9d8b-8994f7717de6_6464A8C05194B416B347D65F01F89FCCE66292FB.pfx .Example $pt=Get-AADIntAccessTokenForPTA PS C:\>Register-AADIntPTAAgent -AccessToken $pt -MachineName "server1.company.com" Sync Agent (005b136f-db3e-4b54-9d8b-8994f7717de6) registered as server1.company.com Certificate saved to server1.company.com_513d8d3d-7498-4d8c-85ed-b485ed5c39a9_005b136f-db3e-4b54-9d8b-8994f7717de6_6464A8C05194B416B347D65F01F89FCCE66292FB.pfx .Example PS C:\>Register-AADIntPTAAgent -MachineName "server1.company.com" -UpdateTrust -PfxFileName .\server1.company.com_513d8d3d-7498-4d8c-85ed-b485ed5c39a9_005b136f-db3e-4b54-9d8b-8994f7717de6_6464A8C05194B416B347D65F01F89FCCE66292FB.pfx Sync Agent (005b136f-db3e-4b54-9d8b-8994f7717de6) certificate renewed for server1.company.com Certificate saved to server1.company.com_513d8d3d-7498-4d8c-85ed-b485ed5c39a9_005b136f-db3e-4b54-9d8b-8994f7717de6_449D42C1BA32B23A621EBE62329AE460FE68924B.pfx #> [cmdletbinding()] Param( [Parameter(Mandatory=$False)] [String]$AccessToken, [Parameter(Mandatory=$True)] [String]$MachineName, [Parameter(Mandatory=$False)] [String]$FileName, [Parameter(ParameterSetName='normal',Mandatory=$False)] [Parameter(ParameterSetName='update',Mandatory=$True)] [switch]$UpdateTrust, [Parameter(ParameterSetName='update',Mandatory=$True)] [String]$PfxFileName, [Parameter(ParameterSetName='update',Mandatory=$False)] [String]$PfxPassword ) Process { return Register-ProxyAgent -AccessToken $AccessToken -MachineName $MachineName -FileName $FileName -AgentType Sync -UpdateTrust $UpdateTrust -PfxFileName $PfxFileName -PfxPassword $PfxPassword } } # Invokes the Sync Agent function Invoke-SyncAgent { <# .SYNOPSIS Invokes a Sync Agent with given name and certificate. .DESCRIPTION Invokes a Sync Agent with given name and certificate, and connects to Azure AD. Emulates Azure AD Sync Agent. .Example Invoke-AADIntSyncAgent -MachineName "server1.company.com" Connector 1 connecting to his-eur1-neur1 Connector 2 connecting to his-eur1-neur1 Connector 3 connecting to his-eur1-weur1 Connector 4 connecting to his-eur1-weur1 Sync Agent started, waiting for logins.. .Example Register-AADIntSyncAgent -MachineName "server1.company.com" Sync agent registered as server1.company.com Certificate saved to Sync_client_certificate.pfx PS C:\>Invoke-AADIntSyncAgent -MachineName "server1.company.com" Connector 1 connecting to his-eur1-neur1 Connector 2 connecting to his-eur1-neur1 Connector 3 connecting to his-eur1-weur1 Connector 4 connecting to his-eur1-weur1 Sync Agent started, waiting for logins.. .Example $pt=Get-AADIntAccessTokenForPTA PS C:\>Register-AADIntSyncAgent -AccessToken $pt -MachineName "server1.company.com" -FileName server1.pfx Sync agent registered as server1.company.com Certificate saved to server1.pfx PS C:\>Invoke-AADIntSyncAgent -MachineName "server1.company.com" -FileName server1.pfx Connector 1 connecting to his-eur1-neur1 Connector 2 connecting to his-eur1-neur1 Connector 3 connecting to his-eur1-weur1 Connector 4 connecting to his-eur1-weur1 Sync Agent started, waiting for logins.. #> [cmdletbinding()] Param( [Parameter(Mandatory=$True)] [String]$MachineName, [Parameter(Mandatory=$False)] [String]$fileName="Sync_client_certificate.pfx" ) Process { # Clean the old jobs Get-Job | Remove-Job -Force # Load the certificate $fullPath = (Get-Item $fileName).FullName $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::CreateFromCertFile($fullPath) # Get the bootStraps $BootStraps = Get-BootstrapConfiguration -MachineName $MachineName -fileName $fileName $max = 10 $connectors = @() foreach($BootStrap in $bootStraps) { if($connectors.Length -gt $max) { break } $id=($connectors.count+1) # The startup script $sb={ param($BootStrap, $cert) . "$PSScriptRoot\MSAppProxy_utils.ps1"; Connect-ToBus -BootStrap $BootStrap -cert $cert } # Create a synchronized hashtable for status etc. $status=[hashtable]::Synchronized(@{}) # Create the runspace etc. $rs=[runspacefactory]::CreateRunspace() $ps=[powershell]::Create() $ps.Runspace = $rs $rs.Open() $rs.SessionStateProxy.SetVariable("status",$status) $ps.AddScript($sb) $ps.AddArgument($BootStrap) $job = $ps.BeginInvoke() $name = "$id-$($BootStrap.Namespace)" # Create a connector object $connector = New-Object PSObject $connector | Add-Member -NotePropertyName "Name" -NotePropertyValue ($name) $connector | Add-Member -NotePropertyName "PowerShell" -NotePropertyValue ($ps) $connector | Add-Member -NotePropertyName "Runspace" -NotePropertyValue ($rs) $connector | Add-Member -NotePropertyName "Job" -NotePropertyValue ($job) $connector | Add-Member -NotePropertyName "Status" -NotePropertyValue ($status) $connectors+=$connector } $colors=@("Yellow","White","Cyan","Red") while($true) { $running = $connectors.count Clear-Host foreach($connector in $connectors) { Write-Host "$($connector.Name) Completed: $($connector.job.IsCompleted) Status: $($connector.status.status)" -ForegroundColor $colors[$((([int]$connector.Name.Substring(0,1))-1)%4)] if($connector.job.IsCompleted) { $connector.PowerShell.EndInvoke($connector.job) $connector.Runspace.Close() $running-- } } if($running -eq 0) { Write-Host "All connectors completed. Exiting.." break } Start-Sleep -Seconds 3 } } } |