Hello,
Find the updated script below. To run the script you need to use a Schedule Task configured for Domain-DNS object type. No conditions need to be added to the task.
$networkPrefixProperty = "description" # TODO: modify me
$hostIdentifierToSkip = @("50", "51") # TODO: modify me
# Email message settings
$to = "recipient@domain.com" # TODO: modify me
$subject = "Move computer based on IP address report" # TODO: modify me
$reportHeader = "<b>Move computer based on IP address report</b><br/><br/>" # TODO: modify me
$reportFooter = "<hr /><p><i>Please do not reply to this e-mail, it has been sent to you for notification purposes only.</i></p>" # TODO: modify me
function SearchObjects($filter, $properties, $domainName, $searchInAllDomains)
{
if ($searchInAllDomains)
{
$searcher = $Context.BindToObject("Adaxes://rootDSE")
$searcher.VirtualRoot = $searchInAllDomains
}
else
{
$searcher = $Context.BindToObject("Adaxes://$domainName/rootDSE")
}
$searcher.SearchFilter = $filter
$searcher.SearchScope = "ADS_SCOPE_SUBTREE"
$searcher.PageSize = 500
$searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
$searcher.SetPropertiesToLoad($properties)
try
{
$searchResultIterator = $searcher.ExecuteSearch()
$searchResults = $searchResultIterator.FetchAll()
return ,$searchResults
}
finally
{
# Release resources
if ($searchResultIterator){ $searchResultIterator.Dispose() }
}
}
function AddReportRecord($records, $computerName, $parentName, $newParentName)
{
[void]$records.Append("<tr><td>$computerName</td><td>$parentName</td><td>$newParentName</td></tr>")
}
# Search all computers
$computersSearchResults = SearchObjects "(&(objectCategory=computer)(dNSHostName=*)(!(userAccountControl:1.2.840.113556.1.4.803:=8192)))" @("dNSHostName", "name", "distinguishedName") $NULL $True
$records = New-Object "System.Text.StringBuilder"
$ouInfos = @{}
for ($i = 0; $i -lt $computersSearchResults.Length; $i++)
{
# Get computer info
$computerSearchResult = $computersSearchResults[$i]
$computerName = $computerSearchResult.Properties["name"].Value
$computerDN = New-Object "Softerra.Adaxes.Ldap.DN" $computerSearchResult.Properties["distinguishedName"].Value
$parentName = $Context.GetDisplayNameFromAdsPath("Adaxes://" + $computerDN.Parent)
# Get IP address
try
{
$addresses = [System.Net.Dns]::GetHostAddresses($computerSearchResult.Properties["dNSHostName"].Value)
}
catch
{
$message = "An error occurred when searching for the computer IP address. Error: " + $_.Exception.Message
$Context.LogMessage("$computerName`: $message", "Warning")
AddReportRecord $records $computerName $parentName $message
continue
}
$ipAddress = $addresses | Where-Object {$_.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork}
if ($ipAddress -is [System.Array])
{
$message = "Found more than one IP address for the computer. Addresses: " + [System.String]::Join(";", $ipAddress)
$Context.LogMessage("$computerName`: $message", "Warning")
AddReportRecord $records $computerName $parentName $message
continue
}
if ($ipAddress -eq $NULL)
{
$message = "No IPv4 addresses found."
$Context.LogMessage("$computerName`: $message", "Warning")
AddReportRecord $records $computerName $parentName $message
continue
}
# Find target OU
$hostIdentifier = ($ipAddress | Select-String -Pattern "[0-9]{1,3}$").Matches[0].ToString()
if ($hostIdentifierToSkip -contains $hostIdentifier)
{
continue
}
$networkPrefix = ($ipAddress | Select-String -Pattern "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}").Matches[0].ToString()
if (-not($ouInfos.ContainsKey($networkPrefix)))
{
$domainName = $Context.GetObjectDomain($computerDN)
$ouSearchResults = SearchObjects "(&(objectCategory=organizationalUnit)($networkPrefixProperty=$networkPrefix))" @("distinguishedName") $domainName $False
if ($ouSearchResults.Length -eq 0)
{
$message = "Organizational Unit for IP prefix '$networkPrefix' not found."
$Context.LogMessage("$computerName`: $message", "Warning")
AddReportRecord $records $computerName $parentName $message
continue
}
elseif ($ouSearchResults.Length -gt 1)
{
$message = "Found more than one Organizational Unit for IP prefix '$networkPrefix'."
$Context.LogMessage("$computerName`: $message", "Warning")
AddReportRecord $records $computerName $parentName $message
continue
}
$ouInfos.Add($networkPrefix, $ouSearchResults[0])
}
$ouSearchResult = $ouInfos[$networkPrefix]
$newParentDN = New-Object "Softerra.Adaxes.Ldap.DN" $ouSearchResult.Properties["distinguishedName"].Value
if ($computerDN.Parent -eq $newParentDN)
{
continue
}
# Move computer to the OU
$newParentPath = $ouSearchResult.AdsPath
$ou = $Context.BindToObjectEx($newParentPath, $True)
$ou.MoveHere($computerSearchResult.AdsPath, $NULL)
$newParentName = $Context.GetDisplayNameFromAdsPath($newParentPath)
AddReportRecord $records $computerName $parentName $newParentName
}
# Build report
$html = New-Object "System.Text.StringBuilder"
[void]$html.Append($reportHeader)
if ($records.Length -eq 0)
{
[void]$html.Append("<b>No computers found</b>")
}
else
{
[void]$html.Append("<table border='1' width='100%%'>")
[void]$html.Append("<tr>")
[void]$html.Append("<th>Computer name</th>")
[void]$html.Append("<th>Old parent name</th>")
[void]$html.Append("<th>New parent name</th>")
[void]$html.Append("</tr>")
[void]$html.Append($records.ToString())
[void]$html.Append("</table>")
}
[void]$html.Append($reportFooter)
# Send report
$Context.SendMail($to, $subject, $NULL, $html.ToString())