classes/BindZoneClass.ps1
using namespace System.Collections.Generic class BindZone:List[BindRecord] { [ValidateNotNullOrEmpty()] [string]$Origin [List[string]]$RecordOrder [List[string]]$SortOrder BindZone () {} BindZone ( [string]$Path ) { $Records = Resolve-Path $Path | Get-Content if ( $Records[0] -match '^\$ORIGIN\s+(?<Origin>\S+)\s*$' ) { $this.Origin = $Matches.Origin $Records = $Records | Select-Object -Skip 1 } if ( -not $this.Origin ) { Write-Warning 'Zone did not include an $ORIGIN' } $this.__AddRecords( $Records ) } BindZone ( [string[]]$Records ) { $this.__AddRecords( $Records ) } BindZone ( [string[]]$Records, [string]$Origin ) { $this.Origin = $Origin $this.__AddRecords( $Records ) } BindZone ( [BindRecord[]]$Records, [string]$Origin ) { $this.Origin = $Origin $this.__AddRecords( $Records ) } hidden [void] __AddRecords ( [BindRecord[]]$Records ) { $this.AddRange( $Records ) } [void] SortZone ( [string[]]$RecordOrder, [string[]] $SortOrder ) { $this.Sort() } [string] ToString () { if ( [BindZone]::HasErrors( $this ) ) { Write-Error 'Zone Errors Present' -ErrorAction Stop } # figure out column widths $ColumnWidths = @{ HostName = ( [string[]]$this.HostName | Measure-Object -Maximum -Property Length ).Maximum TimeToLive = ( [string[]]$this.TimeToLive | Measure-Object -Maximum -Property Length ).Maximum RecordClass = ( [string[]]$this.RecordClass | Measure-Object -Maximum -Property Length ).Maximum RecordType = ( [string[]]$this.RecordType | Measure-Object -Maximum -Property Length ).Maximum RecordData = ( [string[]]$this.RecordData | Measure-Object -Maximum -Property Length ).Maximum } $Return = [System.Collections.Generic.List[string]]::new() if ( $this.Origin ) { $Return.Add( '$ORIGIN ' + $this.Origin ) } $Format = "{0,-$($ColumnWidths.HostName)} {1,$($ColumnWidths.TimeToLive)} {2,-$($ColumnWidths.RecordClass)} {3,-$($ColumnWidths.RecordType)} {4}" $this | ForEach-Object { $Return.Add( $_.ToString( $this.IndexOf($_), $Format ) ) } return $Return -join "`r`n" } [void] SaveAs ( [string]$Path ) { $this.ToString() | Set-Content -Path $Path } static [bool] HasErrors ( [BindZone]$Zone ) { $HasErrors = $false if ( -not $Zone.Origin ) { Write-Warning 'Zone does not contain an $ORIGIN' $HasErrors = $true } if ( $Zone[0].RecordType -ne 'SOA' ) { Write-Warning 'Zone does not start with SOA record' $HasErrors = $true } if ( ( $Zone | Where-Object RecordType -eq 'SOA' ).Count -lt 1 ) { Write-Warning 'Zone does not contain an SOA record' $HasErrors = $true } if ( ( $Zone | Where-Object RecordType -eq 'SOA' ).Count -gt 1 ) { Write-Warning 'Zone contains more than one SOA record' $HasErrors = $true } if ( $Zone | Where-Object RecordType -eq 'TXT' | Group-Object 'HostName' | Where-Object { ( $_.Group.TimeToLive | Select-Object -Unique ).Count -gt 1 } ) { Write-Warning 'Zone contains one or more TXT records with dissimilar TTL values, all TTL values at the same level must match for TXT records' $HasErrors = $true } return $HasErrors } } |