functions/sitelinks/Test-FMSiteLink.ps1
function Test-FMSiteLink { <# .SYNOPSIS Compares a live sitelink setup with the configured desired state. .DESCRIPTION Compares a live sitelink setup with the configured desired state. .PARAMETER Server The server / domain to work with. .PARAMETER Credential The credentials to use for this operation. .EXAMPLE PS C:\> Test-FMSiteLink Tests the current forest for compliance with the sitelink configuration #> [CmdletBinding()] Param ( [PSFComputer] $Server, [PSCredential] $Credential ) begin { #region Functions function New-Update { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( $Identity, $Property, $OldValue, $NewValue ) $datum = [PSCustomObject]@{ PSTypeName = 'ForestManagement.SiteLink.Update' Identity = $Identity Property = $Property OldValue = $OldValue NewValue = $NewValue } Add-Member -InputObject $datum -MemberType ScriptMethod -Name ToString -Value { '{0}: {1} -> {2}' -f $this.Property, $this.OldValue, $this.NewValue } -Force $datum } #endregion Functions $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential $parameters['Debug'] = $false Assert-ADConnection @parameters -Cmdlet $PSCmdlet Invoke-Callback @parameters -Cmdlet $PSCmdlet Assert-Configuration -Type SiteLinks -Cmdlet $PSCmdlet Set-FMDomainContext @parameters $allSiteLinks = Get-ADReplicationSiteLink @parameters -Filter * -Properties Cost, Description, Options, Name, replInterval, siteList | Select-Object * $linksToExclude = @() $resultDefaults = @{ ObjectType = 'SiteLink' Server = $Server } foreach ($siteLink in $allSiteLinks) { $count = 1 foreach ($site in $siteLink.siteList) { try { Add-Member -InputObject $siteLink -MemberType NoteProperty -Name "Site$($count)" -Value (Get-ADObject @parameters -Identity $site -Properties Name).Name } catch { Add-Member -InputObject $siteLink -MemberType NoteProperty -Name "Site$($count)" -Value $site } $count++ } #region More than 2 sites in Sitelink if ($siteLink.siteList.Count -ge 3) { if (Get-PSFConfigValue -FullName 'ForestManagement.SiteLink.MultilateralLinks') { Write-PSFMessage -Level Verbose -String 'Test-FMSiteLink.Information.MultipleSites' -StringValues $siteLink.DistinguishedName, $siteLink.siteList.Count -Tag sitelink, multiple_sites -Target $siteLink.DistinguishedName New-TestResult @resultDefaults -Type MultipleSites -Identity $siteLink.Name -ADObject $siteLink -Properties @{ Name = $siteLink.Name DistinguishedName = $siteLink.DistinguishedName } } else { Write-PSFMessage -Level Warning -String 'Test-FMSiteLink.Critical.TooManySites' -StringValues $siteLink.DistinguishedName, $siteLink.siteList.Count -Tag sitelink, critical, panic -Target $siteLink.DistinguishedName New-TestResult @resultDefaults -Type TooManySites -Identity $siteLink.Name -ADObject $siteLink -Properties @{ Name = $siteLink.Name DistinguishedName = $siteLink.DistinguishedName } } $linksToExclude += $siteLink } #endregion More than 2 sites in Sitelink Add-Member -InputObject $siteLink -MemberType NoteProperty -Name IdealName -Value ('{0}-{1}' -f $siteLink.Site1, $siteLink.Site2) } $allSiteLinks = $allSiteLinks | Where-Object { $_ -notin $linksToExclude } } process { #region Test all sitelinks found in the forest foreach ($siteLink in $allSiteLinks) { if (-not (Get-FMSiteLink | Compare-SiteLink $siteLink)) { New-TestResult @resultDefaults -Type Delete -Identity $siteLink.Name -ADObject $siteLink -Properties @{ Name = $siteLink.Name Site1 = $siteLink.Site1 Site2 = $siteLink.Site2 IdealName = $siteLink.IdealName Cost = $siteLink.Cost Description = $siteLink.Description Options = $siteLink.Options ReplicationInterval = $siteLink.replInterval } continue } $configuredSitelink = Get-FMSiteLink | Compare-SiteLink $siteLink | Select-Object -First 1 $deltaProperties = @() #region Compare Properties if ($configuredSiteLink.Name -ne $siteLink.Name) { $deltaProperties += New-Update -Identity $siteLink.Name -OldValue $siteLink.Name -NewValue $configuredSitelink.Name -Property 'Name' } if ($configuredSiteLink.Cost -ne $siteLink.Cost) { $deltaProperties += New-Update -Identity $siteLink.Name -OldValue $siteLink.Cost -NewValue $configuredSitelink.Cost -Property 'Cost' } if ($configuredSiteLink.Description -ne ([string]($siteLink.Description))) { $deltaProperties += New-Update -Identity $siteLink.Name -OldValue ([string]($siteLink.Description)) -NewValue $configuredSitelink.Description -Property 'Description' } if ($configuredSiteLink.Option -ne ([int]($siteLink.Options))) { $deltaProperties += New-Update -Identity $siteLink.Name -OldValue ([int]($siteLink.Options)) -NewValue $configuredSitelink.Option -Property 'Options' } if ($configuredSiteLink.Interval -ne $siteLink.replInterval) { $deltaProperties += New-Update -Identity $siteLink.Name -OldValue $siteLink.replInterval -NewValue $configuredSitelink.Interval -Property 'ReplicationInterval' } #endregion Compare Properties if ($deltaProperties) { New-TestResult @resultDefaults -Type Update -Identity $siteLink.Name -ADObject $siteLink -Configuration $configuredSitelink -Properties @{ Name = $configuredSitelink.Name Site1 = $configuredSitelink.Site1 Site2 = $configuredSitelink.Site2 IdealName = $configuredSitelink.Name Cost = $configuredSitelink.Cost Description = $configuredSitelink.Description Options = $configuredSitelink.Option ReplicationInterval = $configuredSitelink.Interval } -Changed $deltaProperties } } #endregion Test all sitelinks found in the forest foreach ($configuredSitelink in (Get-FMSiteLink)) { if ($allSiteLinks | Compare-SiteLink $configuredSitelink) { continue } New-TestResult @resultDefaults -Type Create -Identity $configuredSitelink.Name -Configuration $configuredSitelink -Properties @{ Name = $configuredSitelink.Name Site1 = $configuredSitelink.Site1 Site2 = $configuredSitelink.Site2 IdealName = $configuredSitelink.Name Cost = $configuredSitelink.Cost Description = $configuredSitelink.Description Options = $configuredSitelink.Option ReplicationInterval = $configuredSitelink.Interval } } } } |