Hello,
The script that you can find below creates a CSV file containing all existing AD objects that do not comply with the Property Patterns applied to them. To run the script:
-
Save the script to a file with the .ps1 extension on the computer where your Adaxes service is installed.
-
Launch Windows PowerShell. To do this:
- Press Win+R.
- Type powershell.exe and press Enter.
-
In the PowerShell console, navigate to the folder where you saved the script. For example, if you saved it to C:\Scripts, type:
cd C:\Scripts
-
Run the script using the following command line:
.\MyScript.ps1 <CSV file path> <username> <password>
where
- MyScript.ps1 - the name of the script file that you've created on step 1,
- <CSV file path> - full path to the CSV file that will be created by the script,
- <username>, <password> - credentials that will be used to access Adaxes service. These parameters are optional. If you omit them, credentials of the currently logged on user will be used. The minimum permissions required are the permissions to read all Property Patterns and the permissions to read all objects that you want to check against Property patterns.
The script:
Param([Parameter(Mandatory=$True,Position=1)]$csvFilePath, [Parameter(Mandatory=$False,Position=2)]$username, [Parameter(Mandatory=$False,Position=3)]$password)
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")
function ReportRecord($objectDn, $propertyPatternName, $propertyName, $errorText)
{
Write-Host "Object DN:'$objectDn' Property Pattern:'$propertyPatternName' Property Name:'$propertyName' Error Text:'$errorText'"
$reportRecord = new-object PSObject
$reportRecord | add-member NoteProperty "Object DN" "$objectDn"
$reportRecord | add-member NoteProperty "Property Pattern" "$propertyPatternName"
$reportRecord | add-member NoteProperty "Property Name" "$propertyName"
$reportRecord | add-member NoteProperty "Error Text" "$errorText"
return $reportRecord
}
$admNS = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$admService = $admNS.GetServiceDirectly("localhost")
# Bind to the Property Patterns container
$propertyPatternsPath = $admService.Backend.GetConfigurationContainerPath("PropertyPatterns")
$propertyPatternsContainer = $admService.OpenObject($propertyPatternsPath, $username, $password, 0)
# Configure object searcher to search for all objects
$searcher = $admService.OpenObject("Adaxes://rootDSE", $username, $password, 0)
$searcher.SearchFilter = "(objectClass=*)"
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.PageSize = 500
$searcher.VirtualRoot = $True
$searchResults = $searcher.ExecuteSearch()
# Get backend server name and port number
$backendServer = $admService.Backend.DnsHostName + ":" + $admService.Backend.PortNumber
$report = @()
While ($searchResults.MoveNext())
{
# Bind to the AD object
$object = $admService.OpenObject($searchResults.Current.ADsPath, $username, $password, 0)
# Get Distinguished Name
$objectDN = $object.GetEx("distinguishedName")
# Get effective Property Patterns
$propertyPatterns = $propertyPatternsContainer.GetEffectivePropertyPatterns($object)
foreach ($patternGuidByte in $propertyPatterns)
{
# Bind to the Property Pattern
$patternGuid = New-Object "System.Guid" @(,$patternGuidByte)
$patternPath = "Adaxes://$backendServer/<GUID=$patternGuid>"
$propertyPattern = $admService.OpenObject($patternPath, $username, $password, 0)
# Get Property Pattern name
$patternName = $propertyPattern.PatternName
# Get Property Pattern items
$patternItems = $propertyPattern.Items
for ($patternItem = 0; $patternItem -lt $patternItems.Count; $patternItem++)
{
$item = $patternItems.GetObject($patternItem)
# Get the property name
$propertyName = $item.PropertyName
# Get the current value for the property
$object.GetInfoEx(@($propertyName), $NULL)
$propertyEntry = $NULL
try
{
$propertyEntry = $object.Item($propertyName)
$propertyEntry.ControlCode = "ADS_PROPERTY_UPDATE"
}
catch [Exception]
{
if ($item.IsPropertyRequired)
{
# The object doesn't have a property that's required
$errorMessage = "The '$propertyName' property is required"
$report += ReportRecord $objectDN $patternName $propertyName $errorMessage
}
continue
}
# Get constraints for the property
$constraints = $item.GetConstraints()
foreach ($constraint in $constraints)
{
$errorMessage = ""
# Check the the property value against the constraint
$isValid = $constraint.Check($propertyEntry, $object, [ref]$errorMessage)
if ( -not $isValid)
{
$report += ReportRecord $objectDN $patternName $propertyName $errorMessage
}
}
}
}
}
$searchResults.Dispose()
#Write the report to the csv file
$report | Export-Csv $csvFilePath -NoTypeInformation