{"id":1484,"date":"2015-01-02T14:06:35","date_gmt":"2015-01-02T06:06:35","guid":{"rendered":"http:\/\/www.jhouseconsulting.com\/?p=1484"},"modified":"2016-03-22T16:55:10","modified_gmt":"2016-03-22T08:55:10","slug":"script-to-create-a-summary-overview-and-full-report-of-all-contact-objects-in-a-domain","status":"publish","type":"post","link":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/2015\/01\/02\/script-to-create-a-summary-overview-and-full-report-of-all-contact-objects-in-a-domain-1484","title":{"rendered":"Script to Create a Summary Overview and Full Report of all Contact Objects in a Domain"},"content":{"rendered":"<p>This PowerShell script is one of the most comprehensive you will find that provides a thorough overview and full report of all contact\u00a0objects in a domain. It is the culmination of many Active Directory audit and reviews and therefore contains valuable input from many customers.<\/p>\n<p>A lot of thought has been put into the logic within this script to help an organisation understand:<\/p>\n<ul>\n<li>Contacts\u00a0that are mail-disabled<\/li>\n<li>Contacts that are ADFS Farm objects, which are Contact objects located\u00a0under the certificate sharing container.<\/li>\n<li>Contacts that are UM Integration objects<\/li>\n<li>Contacts that are conflicting\/duplicate objects (name contains CNF:)<\/li>\n<li>Contacts that have expired<\/li>\n<li>Contacts that have no manager set<\/li>\n<li>Contacts\u00a0that have been left in the default Users container (CN=Users)<\/li>\n<\/ul>\n<p>FYI:<\/p>\n<ul>\n<li>Mail-enabled contacts are derived from the\u00a0targetAddress, proxyAddresses, legacyExchangeDN,\u00a0and mailNickName attributes.<\/li>\n<\/ul>\n<p><!--more--><\/p>\n<p>Open the full CSV report in Excel and add a column filter and freeze the top row. This will help you to filter the data and move through the spreadsheet with ease.<\/p>\n<p>Contacts are typically used to represent external users for the purpose of e-mail. But before making this statement you need to ensure that either a 3rd party or in house application are not making use of them in other ways.<\/p>\n<p>Contacts can be &#8216;disabled&#8217; by mail-disabling them.\u00a0Always clearly document situations where contacts have been disabled. i.e. Are they being kept for a reason, such as for their phone details, etc, or should they be deleted. Delete them if they are no longer valid.<\/p>\n<p>Contacts should not be left in the default Users container (ie. CN=Users). Move them to a more appropriate and meaningful location.<\/p>\n<p>Contacts\u00a0whose name contains CNF: means that it\u2019s a duplicate object\u00a0caused by conflicting\/duplicate objects. This typically occurs when objects are created on different Read Write Domain Controllers at nearly the same time. After replication kicks in and those conflicting\/duplicate objects replicate to other Read Write Domain Controllers, Active Directory replication applies a conflict resolution mechanism to ensure every object is and remains unique. Verify that there is a matching normal object, merge attributes and then the\u00a0conflicting\/duplicate object can be deleted.<\/p>\n<p>ADFS Farm objects under the certificate sharing container need to be managed by the ADFS team and not by this process. They are not a traditional contact object. I always found it bizarre that Microsoft chose to create these as Contact objects. I don&#8217;t have an issue with it, but just find it dangerous to think that some IT Pros may just blindly run a script to delete all old contact objects before understanding what they really are!<\/p>\n<p>From here you\u00a0can start to implement some good policies and processes around the management of contacts.<\/p>\n<p>At the end of the day a nice way to manage contacts is to set their expirationTime attribute. This will give us the ability to implement a nice life cycle management process. You can go one step further and add a user or mail-enabled security group to the manager attribute. This will give us the ability to implement some workflow when the contact is x days before expiring.<\/p>\n<p>The following screen shot is from a recent health check and audit I completed.<\/p>\n<p>There are 4 things here that stick out here like a sore thumb:<\/p>\n<ul>\n<li>9.35% of Contacts are mail-disabled. Are they serving any purpose?<\/li>\n<li>None of the Contacts have an expiration time set<\/li>\n<li>More or less none of the Contacts have a manager set<\/li>\n<li>Contacts left in the default Users container<\/li>\n<\/ul>\n<p><a href=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectOverview.png\"><img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter wp-image-1485\" title=\"Contact Object Overview\" src=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectOverview.png\" alt=\"Contact Object Overview\" width=\"700\" height=\"389\" srcset=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectOverview.png 881w, https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectOverview-300x167.png 300w, https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectOverview-768x426.png 768w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>It&#8217;s very clear to me just by looking at this that they have no life cycle management process in place for their Contact objects.<\/p>\n<p>The following screen shot is the full report from the same health check. Whilst I\u2019ve had to blur our some of the data you can get an idea from the column headings that it\u2019s fairly extensive. There are a further 8\u00a0columns that I was unable to capture in the screen shot due to screen resolution.<\/p>\n<p><a href=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectFullReport.png\"><img decoding=\"async\" class=\"aligncenter wp-image-1486\" title=\"Contact Object Full Report\" src=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectFullReport.png\" alt=\"Contact Object Full Report\" width=\"700\" height=\"366\" srcset=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectFullReport.png 1887w, https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectFullReport-300x157.png 300w, https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectFullReport-768x402.png 768w, https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2015\/01\/ContactObjectFullReport-1024x536.png 1024w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>Here is the <a  data-e-Disable-Page-Transition=\"true\" class=\"download-link\" title=\"\" href=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/download\/1490\/?tmstv=1776914799\" rel=\"nofollow\" id=\"download-link-1490\" data-redirect=\"false\" >\n\tGet-ContactReport.ps1\t(1316 downloads\t)\n<\/a>\n\u00a0script:<\/p>\n<pre class=\"brush: powershell; auto-links: false; title: ; toolbar: false; notranslate\" title=\"\">\r\n&lt;# This script will enumerate all contact objects in a Domain, providing both a summary overview and a full report based on the values of the following attributes: - name - distinguishedname - givenName - sn - initials - mail - telephoneNumber - mobile - displayName - description - title - company - physicalDeliveryOfficeName - manager - employeeID - employeeNumber - employeeType - msexchextensioncustomattribute1 - msexchextensioncustomattribute2 - msexchextensioncustomattribute3 - msexchextensioncustomattribute4 - msexchextensioncustomattribute5 - isCriticalSystemObject - expirationtime - info - whencreated - whenchanged - memberOf - targetAddress - proxyAddresses - legacyExchangeDN - mailNickName - msRTCSIP-Line - otherIpPhone We further derive: - The Parent OU from the distinguishedname attribute. - MailEnabled from targetAddress, proxyAddresses, legacyExchangeDN, and mailNickName. - http:\/\/pmoreland.blogspot.com.au\/2013\/03\/creating-mail-contacts-and-distribution.html - UMIntegrationObject from msRTCSIP-Line and otherIpPhone We check to see if the Surname (sn) contains a non-alpha character. This is to ensure that a consistent standard\/pattern has been used for hyphenated namnes, some Asian names, and tussenvoegsels. Syntax examples: - To execute the script in the current Domain: Get-ContactReport.ps1 - To execute the script against a trusted Domain: Get-ContactReport.ps1 -TrustedDomain mydemosthatrock.com Script Name: Get-ContactReport.ps1 Release 2.3 Written by Jeremy@jhouseconsulting.com 27\/12\/2013 Modified by Jeremy@jhouseconsulting.com 14\/12\/2015 #&gt;\r\n#-------------------------------------------------------------\r\nparam(&#x5B;String]$TrustedDomain,&#x5B;switch]$verbose)\r\n\r\nif ($verbose.IsPresent) { \r\n  $VerbosePreference = 'Continue' \r\n  Write-Verbose &quot;Verbose Mode Enabled&quot; \r\n} \r\nElse { \r\n  $VerbosePreference = 'SilentlyContinue' \r\n}\r\n\r\n#-------------------------------------------------------------\r\n\r\n# Set this to the OU structure where the you want to search to\r\n# start from. Do not add the Domain DN. If you leave it blank,\r\n# the script will start from the root of the domain.\r\n$OUStructureToProcess = &quot;&quot;\r\n\r\n# Set this to true to include the employeeID, employeeNumber and\r\n# employeeType attributes.\r\n$IncludeEmployeeAttributes = $True\r\n\r\n# Set this to true to include the first 3 msexchextensioncustomattribute\r\n# attributes. Really handy for Office365 license management with DirSync.\r\n$IncludeExchExtensionCustomAttributes = $False\r\n\r\n# Set this to true to include extra contact attributes such as\r\n# displayName, description, telephoneNumber, mobile, title,\r\n# company, physicalDeliveryOfficeName\r\n$IncludeExtendedDetails = $True\r\n\r\n# Set this to true to include the user's direct group membership\r\n$IncludeMemberOf = $True\r\n\r\n# Set the name of the attribute you want to populate for objects\r\n# to be evaluated as a stale or non-stale object.\r\n$ExcludeAttribute = &quot;comment&quot;\r\n\r\n# Set the text within the $ExcludeAttribute that you want to use\r\n# to evaluate if the object should be excluded from the stale\r\n# object collection.\r\n$ExcludeText = &quot;Decommission=False&quot;\r\n\r\n# Set this to the delimiter for the CSV output\r\n$Delimiter = &quot;,&quot;\r\n\r\n# Set this to remove the double quotes from each value within the\r\n# CSV.\r\n$RemoveQuotesFromCSV = $False\r\n\r\n# Set this value to true if you want to see the progress bar.\r\n$ProgressBar = $True\r\n\r\n#-------------------------------------------------------------\r\n\r\n$invalidChars = &#x5B;io.path]::GetInvalidFileNamechars() \r\n$datestampforfilename = ((Get-Date -format s).ToString() -replace &quot;&#x5B;$invalidChars]&quot;,&quot;-&quot;)\r\n\r\n# Get the script path\r\n$ScriptPath = {Split-Path $MyInvocation.ScriptName}\r\n$ReferenceFileFull = $(&amp;$ScriptPath) + &quot;\\ContactReport-$($datestampforfilename).csv&quot;\r\n$ReferenceFileSummaryTotals = $(&amp;$ScriptPath) + &quot;\\ContactReport-Summary-Totals-$($datestampforfilename).csv&quot;\r\n\r\nif (Test-Path -path $ReferenceFileFull) {\r\n  remove-item $ReferenceFileFull -force -confirm:$false\r\n}\r\nif (Test-Path -path $ReferenceFileSummaryTotals) {\r\n  remove-item $ReferenceFileSummaryTotals -force -confirm:$false\r\n}\r\n\r\nif (&#x5B;String]::IsNullOrEmpty($TrustedDomain)) {\r\n  # Get the Current Domain Information\r\n  $domain = &#x5B;System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()\r\n} else {\r\n  $context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext(&quot;domain&quot;,$TrustedDomain)\r\n  Try {\r\n    $domain = &#x5B;System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($context)\r\n  }\r\n  Catch &#x5B;exception] {\r\n    write-host -ForegroundColor red $_.Exception.Message\r\n    Exit\r\n  }\r\n}\r\n\r\n# Get AD Distinguished Name\r\n$DomainDistinguishedName = $Domain.GetDirectoryEntry() | select -ExpandProperty DistinguishedName  \r\n\r\nIf ($OUStructureToProcess -eq &quot;&quot;) {\r\n  $ADSearchBase = $DomainDistinguishedName\r\n} else {\r\n  $ADSearchBase = $OUStructureToProcess + &quot;,&quot; + $DomainDistinguishedName\r\n}\r\n\r\n$TotalcontactsProcessed = 0\r\n$contactCount = 0\r\n$TotalMailEnabledObjects = 0\r\n$TotalMailDisabledObjects = 0\r\n$TotalDefaultUsersContainer = 0\r\n$TotalUMIntegrationObjects = 0\r\n$TotalADFSFarmObjects = 0\r\n$TotalConflictingObjects = 0\r\n$TotalManagerNotSet = 0\r\n$TotalExpirationTimeNotSet = 0\r\n$TotalExcludedObjects = 0\r\n\r\n# Create an LDAP search for all contacts\r\n$ADFilter = &quot;(&amp;(objectClass=contact)(objectcategory=person))&quot;\r\n\r\n# There is a known bug in PowerShell requiring the DirectorySearcher\r\n# properties to be in lower case for reliability.\r\n$ADPropertyList = @(&quot;name&quot;,&quot;distinguishedname&quot;,&quot;givenname&quot;,&quot;sn&quot;,&quot;initials&quot;,&quot;mail&quot;, `\r\n                    &quot;telephonenumber&quot;,&quot;mobile&quot;,&quot;displayname&quot;,&quot;description&quot;,&quot;title&quot;, `\r\n                    &quot;company&quot;,&quot;physicaldeliveryofficename&quot;,&quot;manager&quot;,&quot;employeeid&quot;, `\r\n                    &quot;employeenumber&quot;,&quot;employeetype&quot;,&quot;info&quot;,&quot;iscriticalsystemobject&quot;, `\r\n                    &quot;whencreated&quot;,&quot;whenchanged&quot;,&quot;expirationtime&quot;,&quot;memberof&quot;, `\r\n                    $ExcludeAttribute,&quot;msexchextensioncustomattribute1&quot;, `\r\n                    &quot;msexchextensioncustomattribute2&quot;,&quot;msexchextensioncustomattribute3&quot;, `\r\n                    &quot;msexchextensioncustomattribute4&quot;,&quot;msexchextensioncustomattribute5&quot;, `\r\n                    &quot;targetaddress&quot;,&quot;proxyaddresses&quot;,&quot;legacyexchangedn&quot;,&quot;mailnickname&quot;, `\r\n                    &quot;msrtcsip-line&quot;,&quot;otheripphone&quot;)\r\n\r\n$ADScope = &quot;SUBTREE&quot;\r\n$ADPageSize = 1000\r\n$ADSearchRoot = New-Object System.DirectoryServices.DirectoryEntry(&quot;LDAP:\/\/$($ADSearchBase)&quot;) \r\n$ADSearcher = New-Object System.DirectoryServices.DirectorySearcher\r\n$ADSearcher.SearchRoot = $ADSearchRoot\r\n$ADSearcher.PageSize = $ADPageSize \r\n$ADSearcher.Filter = $ADFilter \r\n$ADSearcher.SearchScope = $ADScope\r\nif ($ADPropertyList) {\r\n  foreach ($ADProperty in $ADPropertyList) {\r\n    &#x5B;Void]$ADSearcher.PropertiesToLoad.Add($ADProperty)\r\n  }\r\n}\r\nTry {\r\n  write-host -ForegroundColor Green &quot;`nPlease be patient whilst the script retrieves all contact objects and specified attributes...&quot;\r\n  $colResults = $ADSearcher.Findall()\r\n  # Dispose of the search and results properly to avoid a memory leak\r\n  $ADSearcher.Dispose()\r\n  $contactCount = $colResults.Count\r\n}\r\nCatch {\r\n  $contactCount = 0\r\n  Write-Host -ForegroundColor red &quot;The $ADSearchBase structure cannot be found!&quot;\r\n}\r\n\r\nif ($contactCount -ne 0) {\r\n  write-host -ForegroundColor Green &quot;`nProcessing $contactCount contact objects in the $domain Domain...&quot;\r\n  $colResults | ForEach-Object {\r\n    $contactDN = $_.Properties.distinguishedname&#x5B;0]\r\n    $ParentOU = $contactDN -split '(?&lt;!&#x5B;\\\\]),'\r\n    $ParentOU = $ParentOU&#x5B;1..$($ParentOU.Count-1)] -join ','\r\n    $Name = $_.Properties.name&#x5B;0]\r\n    If (($_.Properties.givenname | Measure-Object).Count -gt 0) {\r\n      $Firstname = $_.Properties.givenname&#x5B;0]\r\n    } else {\r\n      $Firstname = &quot;&quot;\r\n    }\r\n    If (($_.Properties.sn | Measure-Object).Count -gt 0) {\r\n      $Surname = $_.Properties.sn&#x5B;0]\r\n      $nonalphacharsinsurname = $Surname -match '&#x5B;^a-zA-Z]'\r\n    } else {\r\n      $Surname = &quot;&quot;\r\n      $nonalphacharsinsurname = $False\r\n    }\r\n    If (($_.Properties.initials | Measure-Object).Count -gt 0) {\r\n      $Initials = $_.Properties.initials&#x5B;0]\r\n    } else {\r\n      $Initials = &quot;&quot;\r\n    }\r\n    If (($_.Properties.employeeid | Measure-Object).Count -gt 0) {\r\n      $EmployeeID = $_.Properties.employeeid&#x5B;0]\r\n    } else {\r\n      $EmployeeID = &quot;&quot;\r\n    }\r\n    If (($_.Properties.employeenumber | Measure-Object).Count -gt 0) {\r\n      $EmployeeNumber = $_.Properties.employeenumber&#x5B;0]\r\n    } else {\r\n      $EmployeeNumber = &quot;&quot;\r\n    }\r\n    If (($_.Properties.employeetype | Measure-Object).Count -gt 0) {\r\n      $EmployeeType = $_.Properties.employeetype&#x5B;0]\r\n    } else {\r\n      $EmployeeType = &quot;&quot;\r\n    }\r\n    If (($_.Properties.mail | Measure-Object).Count -gt 0) {\r\n      $EMail = $_.Properties.mail&#x5B;0]\r\n    } else {\r\n      $EMail = &quot;&quot;\r\n    }\r\n\r\n    $MailEnabled = $False\r\n    If (($_.Properties.targetaddress | Measure-Object).Count -gt 0 -AND\r\n        ($_.Properties.proxyaddresses | Measure-Object).Count -gt 0 -AND\r\n        ($_.Properties.legacyexchangedn | Measure-Object).Count -gt 0 -AND\r\n        ($_.Properties.mailnickname | Measure-Object).Count -gt 0 ) {\r\n      $MailEnabled = $True\r\n      $TotalMailEnabledObjects = $TotalMailEnabledObjects + 1\r\n    } Else {\r\n      $TotalMailDisabledObjects = $TotalMailDisabledObjects + 1\r\n    }\r\n\r\n    If ($IncludeExtendedDetails) {\r\n      If (($_.Properties.displayname | Measure-Object).Count -gt 0) {\r\n        $DisplayName = $_.Properties.displayname&#x5B;0]\r\n      } else {\r\n        $DisplayName = &quot;&quot;\r\n      }\r\n      If (($_.Properties.description | Measure-Object).Count -gt 0) {\r\n        $Description = $_.Properties.description&#x5B;0]\r\n      } else {\r\n        $Description = &quot;&quot;\r\n      }\r\n      If (($_.Properties.telephonenumber | Measure-Object).Count -gt 0) {\r\n        $TelephoneNumber = $_.Properties.telephonenumber&#x5B;0].Replace(&quot;;&quot;,&quot;|&quot;)\r\n      } else {\r\n        $TelephoneNumber = &quot;&quot;\r\n      }\r\n      If (($_.Properties.mobile | Measure-Object).Count -gt 0) {\r\n        $Mobile = $_.Properties.mobile&#x5B;0].Replace(&quot;;&quot;,&quot;|&quot;)\r\n      } else {\r\n        $Mobile = &quot;&quot;\r\n      }\r\n      If (($_.Properties.title | Measure-Object).Count -gt 0) {\r\n        $Title = $_.Properties.title&#x5B;0]\r\n      } else {\r\n        $Title = &quot;&quot;\r\n      }\r\n      If (($_.Properties.company | Measure-Object).Count -gt 0) {\r\n        $Company = $_.Properties.company&#x5B;0]\r\n      } else {\r\n        $Company = &quot;&quot;\r\n      }\r\n      If (($_.Properties.physicaldeliveryofficename | Measure-Object).Count -gt 0) {\r\n        $Office = $_.Properties.physicaldeliveryofficename&#x5B;0]\r\n      } else {\r\n        $Office = &quot;&quot;\r\n      }\r\n    }\r\n\r\n    If (($_.Properties.manager | Measure-Object).Count -gt 0) {\r\n      $Manager = $_.Properties.manager&#x5B;0]\r\n    } else {\r\n      $Manager = &quot;&quot;\r\n      $TotalManagerNotSet = $TotalManagerNotSet + 1\r\n    }\r\n\r\n    If (($_.Properties.msexchextensioncustomattribute1 | Measure-Object).Count -gt 0) {\r\n      $msExchExtensionCustomAttribute1 = $_.Properties.msexchextensioncustomattribute1&#x5B;0]\r\n    } else {\r\n      $msExchExtensionCustomAttribute1 = &quot;&quot;\r\n    }\r\n    If (($_.Properties.msexchextensioncustomattribute2 | Measure-Object).Count -gt 0) {\r\n      $msExchExtensionCustomAttribute2 = $_.Properties.msexchextensioncustomattribute2&#x5B;0]\r\n    } else {\r\n      $msExchExtensionCustomAttribute2 = &quot;&quot;\r\n    }\r\n    If (($_.Properties.msexchextensioncustomattribute3 | Measure-Object).Count -gt 0) {\r\n      $msExchExtensionCustomAttribute3 = $_.Properties.msexchextensioncustomattribute3&#x5B;0]\r\n    } else {\r\n      $msExchExtensionCustomAttribute3 = &quot;&quot;\r\n    }\r\n    If (($_.Properties.msexchextensioncustomattribute4 | Measure-Object).Count -gt 0) {\r\n      $msExchExtensionCustomAttribute4 = $_.Properties.msexchextensioncustomattribute4&#x5B;0]\r\n    } else {\r\n      $msExchExtensionCustomAttribute4 = &quot;&quot;\r\n    }\r\n    If (($_.Properties.msexchextensioncustomattribute5 | Measure-Object).Count -gt 0) {\r\n      $msExchExtensionCustomAttribute5 = $_.Properties.msexchextensioncustomattribute5&#x5B;0]\r\n    } else {\r\n      $msExchExtensionCustomAttribute5 = &quot;&quot;\r\n    }\r\n\r\n    $whencreated = $_.Properties.whencreated&#x5B;0]\r\n \r\n    # If it was created less than 30 days ago mark it as a new account.\r\n    If ($whencreated -gt (Get-Date).AddDays(-30)) {\r\n      $IsNew = $True\r\n    } else {\r\n      $IsNew = $False\r\n    }\r\n\r\n    $whenchanged = $_.Properties.whenchanged&#x5B;0]\r\n\r\n    If (($_.Properties.expirationtime | Measure-Object).Count -gt 0) {\r\n      $ExpirationTime = $_.Properties.expirationtime\r\n    } Else {\r\n      $ExpirationTime = $NULL\r\n      $TotalExpirationTimeNotSet = $TotalExpirationTimeNotSet + 1\r\n    }\r\n    If ($ExpirationTime -ne $NULL -AND $ExpirationTime -lt (Get-Date)) {\r\n      $Expired = $True\r\n    } Else {\r\n      $Expired = $False\r\n    }\r\n\r\n    # Check if it should be excluded\r\n    $Exclude = $False\r\n    If (($_.Properties.$ExcludeAttribute | Measure-Object).Count -gt 0) {\r\n      If ($_.Properties.$ExcludeAttribute&#x5B;0] -eq $ExcludeText) {\r\n        $Exclude = $True\r\n        $TotalExcludedObjects = $TotalExcludedObjects + 1\r\n      }\r\n    }\r\n\r\n    $Conflict = $False\r\n    If ($Name -Like &quot;*CNF:*&quot;) {\r\n      # Replace the Line Feed character in the name so that it's a nicely represented string.\r\n      $Name = $Name -replace &quot;`n&quot;,&quot;&quot;\r\n      $Conflict = $True\r\n      $TotalConflictingObjects = $TotalConflictingObjects + 1\r\n    }\r\n\r\n    If ($ParentOU -Like &quot;CN=Users*&quot;) {\r\n      $TotalDefaultUsersContainer = $TotalDefaultUsersContainer + 1\r\n    }\r\n\r\n    If (($_.Properties.iscriticalsystemobject | Measure-Object).Count -gt 0) {\r\n      $isCriticalSystemObject = $_.Properties.iscriticalsystemobject&#x5B;0]\r\n    } else {\r\n      $isCriticalSystemObject = &quot;&quot;\r\n    }\r\n\r\n    $UMIntegrationObject = $False\r\n    If (($_.Properties.'msrtcsip-line' | Measure-Object).Count -gt 0 -AND\r\n        ($_.Properties.otheripphone | Measure-Object).Count -gt 0 ) {\r\n      If ($_.Properties.'msrtcsip-line' -like &quot;tel:*&quot; -AND \r\n          $_.Properties.otheripphone -like &quot;sip:*&quot; -AND\r\n          $_.Properties.otheripphone -like &quot;*;opaque=app:exum:*&quot; ) {\r\n        $UMIntegrationObject = $True\r\n        $TotalUMIntegrationObjects = $TotalUMIntegrationObjects + 1\r\n      }\r\n    }\r\n\r\n    $ADFSObject = $False\r\n    If ($ParentOU -Like &quot;*CN=ADFS,CN=Microsoft,CN=Program Data*&quot;) {\r\n      $ADFSObject = $True\r\n      $TotalADFSFarmObjects = $TotalADFSFarmObjects + 1\r\n    }\r\n\r\n    If (($_.Properties.info | Measure-Object).Count -gt 0) {\r\n      $notes = $_.Properties.info&#x5B;0]\r\n      $notes = $notes -replace &quot;`r`n&quot;, &quot;|&quot;\r\n    } else {\r\n      $notes = &quot;&quot;\r\n    }\r\n\r\n    If ($IncludeMemberOf) {\r\n      $Members = &quot;&quot;\r\n      $groups = $_.Properties.memberof | ForEach {\r\n        $groupDN = $_\r\n        $objGroup = &#x5B;ADSI](&quot;LDAP:\/\/&quot; + $groupDN)\r\n        $Member = $objGroup.samaccountname\r\n          If ($Members -ne &quot;&quot; ) {\r\n            $Members += &quot;|&quot; + $Member\r\n          } else {\r\n            $Members += $Member\r\n          }\r\n          $objGroup = $null\r\n        }\r\n    }\r\n\r\n    $obj = New-Object -TypeName PSObject\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;Name&quot; -value $Name\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;ParentOU&quot; -value $ParentOU\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;Firstname&quot; -value $Firstname\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;Surname&quot; -value $Surname\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;NonAlphaCharsInSurname&quot; -value $nonalphacharsinsurname\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;Initials&quot; -value $Initials\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;E-Mail&quot; -value $EMail\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;MailEnabled&quot; -value $MailEnabled\r\n    If ($IncludeEmployeeAttributes) {\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;EmployeeID&quot; -value $EmployeeID\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;EmployeeNumber&quot; -value $EmployeeNumber\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;EmployeeType&quot; -value $EmployeeType\r\n    }\r\n    If ($IncludeExtendedDetails) {\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;DisplayName&quot; -value $DisplayName\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;Description&quot; -value $Description\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;TelephoneNumber&quot; -value $TelephoneNumber\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;Mobile&quot; -value $Mobile\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;Title&quot; -value $Title\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;Company&quot; -value $Company\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;Office&quot; -value $Office\r\n    }\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;Manager&quot; -value $Manager\r\n    If ($IncludeExchExtensionCustomAttributes) {\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;msExchExtensionCustomAttribute1&quot; -value $msExchExtensionCustomAttribute1\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;msExchExtensionCustomAttribute2&quot; -value $msExchExtensionCustomAttribute2\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;msExchExtensionCustomAttribute3&quot; -value $msExchExtensionCustomAttribute3\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;msExchExtensionCustomAttribute4&quot; -value $msExchExtensionCustomAttribute4\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;msExchExtensionCustomAttribute5&quot; -value $msExchExtensionCustomAttribute5\r\n    }\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;Exclude&quot; -value $Exclude\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;IsNew&quot; -value $IsNew\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;ExpirationTime&quot; -value $ExpirationTime\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;Expired&quot; -value $Expired\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;WhenCreated&quot; -value $whencreated\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;WhenChanged&quot; -value $whenchanged\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;Conflicting&quot; -value $Conflict\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;isCriticalSystemObject&quot; -value $isCriticalSystemObject\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;UMIntegrationObject&quot; -value $UMIntegrationObject\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;ADFSObject&quot; -value $ADFSObject\r\n    $obj | Add-Member -MemberType NoteProperty -Name &quot;Notes&quot; -value $Notes\r\n    If ($IncludeMemberOf) {\r\n      $obj | Add-Member -MemberType NoteProperty -Name &quot;MemberOf&quot; -value $Members\r\n    }\r\n\r\n    # PowerShell V2 doesn't have an Append parameter for the Export-Csv cmdlet. Out-File does, but it's\r\n    # very difficult to get the formatting right, especially if you want to use quotes around each item\r\n    # and add a delimeter. However, we can easily do this by piping the object using the ConvertTo-Csv,\r\n    # Select-Object and Out-File cmdlets instead.\r\n    if ($PSVersionTable.PSVersion.Major -gt 2) {\r\n      $obj | Export-Csv -Path &quot;$ReferenceFileFull&quot; -Append -Delimiter $Delimiter -NoTypeInformation -Encoding ASCII\r\n    } Else {\r\n      if (!(Test-Path -path $ReferenceFileFull)) {\r\n        $obj | ConvertTo-Csv -NoTypeInformation -Delimiter $Delimiter | Select-Object -First 1 | Out-File -Encoding ascii -filepath &quot;$ReferenceFileFull&quot;\r\n      }\r\n      $obj | ConvertTo-Csv -NoTypeInformation -Delimiter $Delimiter | Select-Object -Skip 1 | Out-File -Encoding ascii -filepath &quot;$ReferenceFileFull&quot; -append -noclobber\r\n    }\r\n\r\n    $TotalcontactsProcessed ++\r\n    If ($ProgressBar) {\r\n      Write-Progress -Activity 'Processing Contacts' -Status (&quot;Count: $($TotalcontactsProcessed) - Name: {0}&quot; -f $Name) -PercentComplete (($TotalcontactsProcessed\/$contactCount)*100)\r\n    }\r\n\r\n  }\r\n\r\n  # Dispose of the search and results properly to avoid a memory leak\r\n  $colResults.Dispose()\r\n\r\n  # Remove the quotes from the output file.\r\n  If ($RemoveQuotesFromCSV) {\r\n    (get-content &quot;$ReferenceFileFull&quot;) |% {$_ -replace '&quot;',&quot;&quot;} | out-file &quot;$ReferenceFileFull&quot; -Fo -En ascii\r\n  }\r\n\r\n  # Note that for the summary output I went with a hashtable instead of binding multiple objects together.\r\n  # Whilst some of the code may seem excessive and repetitive, I found this the simplest method to achieve\r\n  # the desired output.\r\n  $SummaryHashTable = @{}\r\n  $Item = 0\r\n\r\n  $Summaryobj = New-Object -TypeName PSObject\r\n  $percent = &quot;{0:P}&quot; -f ($TotalMailEnabledObjects\/$ContactCount)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Item&quot; -value ($Item = $Item + 1)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Statement&quot; -value &quot;Contacts that are mail-enabled&quot;\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Total_Count&quot; -value $TotalMailEnabledObjects\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Overall_Percentage&quot; -value $percent\r\n  $SummaryHashTable = $SummaryHashTable + @{&quot;Contacts that are mail-enabled&quot; = $Summaryobj}\r\n  $Summaryobj = $Null\r\n\r\n  $Summaryobj = New-Object -TypeName PSObject\r\n  $percent = &quot;{0:P}&quot; -f (($TotalMailDisabledObjects - $TotalADFSFarmObjects)\/$ContactCount)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Item&quot; -value ($Item = $Item + 1)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Statement&quot; -value &quot;Contacts that are mail-disabled (excluding ADFS Farm objects)&quot;\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Total_Count&quot; -value ($TotalMailDisabledObjects - $TotalADFSFarmObjects)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Overall_Percentage&quot; -value $percent\r\n  $SummaryHashTable = $SummaryHashTable + @{&quot;Contacts that are mail-disabled (excluding ADFS Farm objects)&quot; = $Summaryobj}\r\n  $Summaryobj = $Null\r\n\r\n  $Summaryobj = New-Object -TypeName PSObject\r\n  $percent = &quot;{0:P}&quot; -f ($TotalDefaultUsersContainer\/$ContactCount)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Item&quot; -value ($Item = $Item + 1)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Statement&quot; -value &quot;Contacts left in the default Users container&quot;\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Total_Count&quot; -value $TotalDefaultUsersContainer\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Overall_Percentage&quot; -value $percent\r\n  $SummaryHashTable = $SummaryHashTable + @{&quot;Contacts left in the default Users container&quot; = $Summaryobj}\r\n  $Summaryobj = $Null\r\n\r\n  $Summaryobj = New-Object -TypeName PSObject\r\n  $percent = &quot;{0:P}&quot; -f ($TotalUMIntegrationObjects\/$ContactCount)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Item&quot; -value ($Item = $Item + 1)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Statement&quot; -value &quot;Contacts that are UM Integration objects&quot;\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Total_Count&quot; -value $TotalUMIntegrationObjects\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Overall_Percentage&quot; -value $percent\r\n  $SummaryHashTable = $SummaryHashTable + @{&quot;Contacts that are UM Integration objects&quot; = $Summaryobj}\r\n  $Summaryobj = $Null\r\n\r\n  $Summaryobj = New-Object -TypeName PSObject\r\n  $percent = &quot;{0:P}&quot; -f ($TotalADFSFarmObjects\/$ContactCount)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Item&quot; -value ($Item = $Item + 1)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Statement&quot; -value &quot;Contacts that are ADFS Farm objects&quot;\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Total_Count&quot; -value $TotalADFSFarmObjects\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Overall_Percentage&quot; -value $percent\r\n  $SummaryHashTable = $SummaryHashTable + @{&quot;Contacts that are ADFS Farm objects&quot; = $Summaryobj}\r\n  $Summaryobj = $Null\r\n\r\n  $Summaryobj = New-Object -TypeName PSObject\r\n  $percent = &quot;{0:P}&quot; -f ($TotalConflictingObjects\/$ContactCount)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Item&quot; -value ($Item = $Item + 1)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Statement&quot; -value &quot;Contacts that are conflicting\/duplicate objects&quot;\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Total_Count&quot; -value $TotalConflictingObjects\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Overall_Percentage&quot; -value $percent\r\n  $SummaryHashTable = $SummaryHashTable + @{&quot;Contacts that are conflicting\/duplicate objects&quot; = $Summaryobj}\r\n  $Summaryobj = $Null\r\n\r\n  $Summaryobj = New-Object -TypeName PSObject\r\n  $percent = &quot;{0:P}&quot; -f ($TotalExcludedObjects\/$ContactCount)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Item&quot; -value ($Item = $Item + 1)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Statement&quot; -value &quot;Contacts that have their `'$ExcludeAttribute`' attribute set to `'$ExcludeText`'&quot;\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Total_Count&quot; -value $TotalExcludedObjects\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Overall_Percentage&quot; -value $percent\r\n  $SummaryHashTable = $SummaryHashTable + @{&quot;Contacts that have their `'$ExcludeAttribute`' attribute set to `'$ExcludeText`'&quot; = $Summaryobj}\r\n  $Summaryobj = $Null\r\n\r\n  $Summaryobj = New-Object -TypeName PSObject\r\n  $percent = &quot;{0:P}&quot; -f ($TotalExpirationTimeNotSet\/$ContactCount)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Item&quot; -value ($Item = $Item + 1)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Statement&quot; -value &quot;Contacts that have no expiration time set (expirationTime attribute)&quot;\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Total_Count&quot; -value $TotalExpirationTimeNotSet\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Overall_Percentage&quot; -value $percent\r\n  $SummaryHashTable = $SummaryHashTable + @{&quot;Contacts that have no expiration time set (expirationTime attribute)&quot; = $Summaryobj}\r\n  $Summaryobj = $Null\r\n\r\n  $Summaryobj = New-Object -TypeName PSObject\r\n  $percent = &quot;{0:P}&quot; -f ($TotalManagerNotSet\/$ContactCount)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Item&quot; -value ($Item = $Item + 1)\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Statement&quot; -value &quot;Contacts that have no manager set (manager attribute)&quot;\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Total_Count&quot; -value $TotalManagerNotSet\r\n  $Summaryobj | Add-Member -MemberType NoteProperty -Name &quot;Overall_Percentage&quot; -value $percent\r\n  $SummaryHashTable = $SummaryHashTable + @{&quot;Contacts that have no manager set (manager attribute)&quot; = $Summaryobj}\r\n  $Summaryobj = $Null\r\n\r\n  write-host -ForegroundColor Green &quot;Summary Totals:&quot;\r\n\r\n  $Output = $SummaryHashTable.values | ForEach {$_ } | ForEach {$_ } | Sort-Object Item\r\n  $Output | Format-Table -AutoSize\r\n\r\n  # Write-Output $Output | Format-Table\r\n  $Output | Export-Csv -Path &quot;$ReferenceFileSummaryTotals&quot; -Delimiter $Delimiter -NoTypeInformation\r\n\r\n  # Remove the quotes\r\n  If ($RemoveQuotesFromCSV) {\r\n    (get-content &quot;$ReferenceFileSummaryTotals&quot;) |% {$_ -replace '&quot;',&quot;&quot;} | out-file &quot;$ReferenceFileSummaryTotals&quot; -Fo -En ascii\r\n  }\r\n\r\n  write-host &quot;Notes:&quot; -foregroundColor Yellow\r\n  write-host &quot; - Contacts are typically used to represent external users for the purpose of e-mail.&quot; -foregroundColor Yellow\r\n  write-host &quot; - Contacts can be 'disabled' by mail-disabling them.&quot; -foregroundColor Yellow\r\n  write-host &quot;   - Always clearly document situations where contacts have been disabled. i.e. Are they`n     being kept for a reason, such as for their phone details, etc, or should  they be`n     deleted. Delete them if they are no longer valid.&quot; -foregroundColor Yellow\r\n  write-host &quot; - Contacts should not be left in the default Users container (ie. CN=Users). Move them to`n   a more appropriate and meaningful location.&quot; -foregroundColor Yellow\r\n  write-host &quot; - Lync or OCS\/Exchange Unified Messaging (UM) integration Objects are contact objects used`n   for Auto Attendant and Subscriber Access (Dial Plans) numbers for Enterprise Voice. Do`n   not treat them as a traditional contact object.&quot; -foregroundColor Yellow\r\n  write-host &quot; - ADFS Farm objects under the certificate sharing container need to be managed by the ADFS`n   team and not by this process. They are not a traditional contact object.&quot; -foregroundColor Yellow\r\n  write-host &quot; - A nice way to manage contacts is to set their expirationTime attribute. This will give`n   us the ability to implement a nice life cycle management process. You can go one step`n   further and add a user or mail enabled security group to the manager attribute. This`n   will give us the ability to implement some workflow when the contact is x days before`n   expiring.&quot; -foregroundColor Yellow\r\n\r\n  write-host &quot;`nCSV files to review:&quot; -foregroundColor Yellow\r\n  write-host &quot; - $ReferenceFileFull&quot; -foregroundColor Yellow\r\n  write-host &quot; - $ReferenceFileSummaryTotals&quot; -foregroundColor Yellow\r\n\r\n}\r\n<\/pre>\n<p>Enjoy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This PowerShell script is one of the most comprehensive you will find that provides a thorough overview and full report of all contact\u00a0objects in a domain. It is the culmination of many Active Directory audit and reviews and therefore contains valuable input from many customers. A lot of thought has been put into the logic &#8230; <a title=\"Script to Create a Summary Overview and Full Report of all Contact Objects in a Domain\" class=\"read-more\" href=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/2015\/01\/02\/script-to-create-a-summary-overview-and-full-report-of-all-contact-objects-in-a-domain-1484\" aria-label=\"Read more about Script to Create a Summary Overview and Full Report of all Contact Objects in a Domain\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[202,5],"tags":[428,284,337,385,386,374,384,387,379,378,341,340],"class_list":["post-1484","post","type-post","status-publish","format-standard","hentry","category-active-directory","category-scripting","tag-active-directory","tag-ad","tag-adds","tag-adfs-farm-objects","tag-certificate-sharing-container","tag-cnf","tag-contact","tag-life-cycle","tag-mail-disabled","tag-mail-enabled","tag-posh","tag-powershell"],"aioseo_notices":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/1484","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/comments?post=1484"}],"version-history":[{"count":11,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/1484\/revisions"}],"predecessor-version":[{"id":1622,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/1484\/revisions\/1622"}],"wp:attachment":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/media?parent=1484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/categories?post=1484"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/tags?post=1484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}