# Author: Hannes Siefert (Hannes.Siefert@FirstAttribute.com) # Description: Script imports .csv file of subnets sets AD sites accordingly # Version: 1.0 # Created on: 28.01.15 # Last Change: 30.01.15 # Changed by: Hannes Siefert # =========================================================================================== # Change History: # # Release: | Date: | Author: | Changes: # -----------+------------+---------------+------------------------------------------------- # 1.0 | 30.01.2015 | H. Siefert | Creation Add-Type -Assembly Microsoft.VisualBasic $dc = ($env:logonserver).SubString(2) $sitesPath = "CN=Sites,CN=Configuration," + (Get-ADDomain).DistinguishedName function get-filedate { $date = Get-Date $year = (($date.Year).ToString()).SubString(2,2) if($date.Month -lt 10) { $month = "0" + $date.Month } else { $month = ($date.Month).ToString() } if($date.Day -lt 10) { $day = "0" + ($date.Day).ToString() } else { $day = $date.Day } $fileDate = $year + $month + $day return $fileDate } $logPath = ".\log\" $fileDate = get-filedate $fileNameBig = "import-sites_" + $env:username + "_" + $fileDate + ".log" $fileNameSmall = "import-sites_" + $env:username + "_" + $fileDate + ".csv" $logFileBig = $logPath + $fileNameBig $logFileSmall = $logPath + $fileNameSmall function get-timestamp { $date = Get-Date if($date.Month -lt 10) { $month = "0" + ($date.Month).ToString() } else { $month = ($date.Month).ToString() } if($date.Day -lt 10) { $day = "0" + ($date.Day).ToString() } else { $day = ($date.Day).ToString() } if($date.Hour -lt 10) { $hour = "0" + ($date.Hour).ToString() } else { $hour = ($date.Hour).ToString() } if($date.Minute -lt 10) { $minute = "0" + ($date.Minute).ToString() } else { $minute = ($date.Minute).ToString() } if($date.Second -lt 10) { $second = "0" + ($date.Second).ToString() } else { $second = ($date.Second).ToString() } $timeStamp = ($date.Year).ToString() + "/" + $month + "/" + $day + "-" + $hour + ":" + $minute + ":" + $second return $timeStamp } function init-log { if((Test-Path $logPath) -eq $false) { Write-Host ("Creating log folder " + $logpath + "...") -ForegroundColor "Yellow" try { New-Item -ItemType Directory -Path $logPath -ErrorAction Stop | Out-Null } catch { Write-Warning ("Log path (" + $logPath + ") could not be created! Please change variable!") Exit } Write-Host ("Log folder successfully created.") -ForegroundColor "Green" } if((Test-Path $logFileBig) -eq $false) { $date = Get-Date Write-Host ("Creating log file " + $logFileBig + "...") -ForegroundColor "Yellow" try { "Date: " + $date | Out-File -Append -Encoding UTF8 -FilePath $logFileBig -ErrorAction Stop } catch { Write-Warning "Could not write to log file (" + $logFileBig + ") Please check!" Exit } Write-Host ("Log file successfully created.") -ForegroundColor "Green" ("UserName: " + $env:username) | Out-File -Append -Encoding UTF8 -FilePath $logFileBig ("Log file: " + $logFileBig) | Out-File -Append -Encoding UTF8 -FilePath $logFileBig } } function log-write { param([String]$output, $foregroundColor, $backgroundColor) $timeStamp = get-timestamp $output = $timeStamp + ": " + $output if($foregroundColor -ieq "warn") { Write-Warning $output } else { if(($backgroundColor -eq $null) -and ($foregroundColor -eq $null)) { Write-Host $output } if(($backgroundColor -eq $null) -and ($foregroundColor -ne $null)) { Write-Host $output -ForegroundColor $foregroundColor } if(($backgroundColor -ne $null) -and ($foregroundColor -eq $null)) { Write-Host $output -BackgroundColor $backgroundColor } if(($backgroundColor -ne $null) -and ($foregroundColor -ne $null)) { Write-Host $output -ForegroundColor $foregroundColor -BackgroundColor $backgroundColor } } try { $output | Out-File -Append -Encoding UTF8 -FilePath $logFileBig -ErrorAction Stop } catch { Write-Warning "Error writing to log file!!" Write-Host $_.Exception.Message } } function create-site { param($siteName, $location) $ldapFilterSite = "(&(objectClass=site)(objectCategory=site)(name=" + $siteName + "))" $siteAD = Get-ADObject -LDAPFilter $ldapFilterSite -SearchBase $sitesPath -Server $dc if($siteAD -eq $null) { try { $siteAD = New-ADReplicationSite -Name $siteName -Server $dc -PassThru -ErrorAction Stop } catch { log-write ("ADReplicationSite " + $siteName + " could not be created. Reason: " + $_.Exception.Message) -foregroundColor "warn" return $null } try { $siteAD = Set-ADReplicationSite -Identity $siteAD -Add @{location=$location} -Server $dc -ErrorAction Stop -PassThru } catch { log-write ("ADReplicationSite " + $siteAD.Name + " could not be set. Reason: " + $_.Exception.Message) -foregroundColor "warn" } } return $siteAD } function set-site { param($siteAD, $location) try { $siteAD = Set-ADReplicationSite -Identity $siteAD -Clear location -Server $dc -ErrorAction Stop -PassThru $siteAD = Set-ADReplicationSite -Identity $siteAD -Add @{location=$location} -Server $dc -ErrorAction Stop -PassThru } catch { log-write ("ADReplicationSite " + $siteAD.Name + " could not be set. Reason: " + $_.Exception.Message) -foregroundColor "warn" return $null } return $siteAD } function get-replicationPartner { param($country) return "EXAMPLE" } function get-subnetMask { param($subnet) if(($subnet -eq $null) -or ($subnet -eq [String]::Empty)) { return $null } $subnetMask = 0 $array = $subnet.Split(".") foreach($octet in $array) { if([Microsoft.VisualBasic.Information]::IsNumeric($octet)) { $charArray = ([Convert]::ToString($octet,2)).ToCharArray() foreach($bit in $charArray) { $subnetMask += $bit.ToString() } } else { return $null } } return $subnetMask } function get-siteAD { param($siteName) $ldapFilterSite = "(&(objectClass=site)(objectCategory=site)(name=" + $siteName + "))" $siteAD = Get-ADObject -LDAPFilter $ldapFilterSite -SearchBase $sitesPath -Server $dc -Properties location return $siteAD } function get-subnetAD { param($subnet) $ldapFilterSubnet = "(&(objectCategory=subnet)(objectClass=subnet)(name=" + $subnet + "))" $subnetAD = Get-ADObject -LDAPFilter $ldapFilterSubnet -SearchBase $sitesPath -Server $dc -Properties siteObject, location return $subnetAD } function create-subnet { param($subnet, $siteAD, $location) try { $subnetAD = New-ADReplicationSubnet -Name $subnet -Site $siteAD -Location $location -Server $dc -ErrorAction Stop -PassThru } catch { log-write ("ADReplicationSubnet " + $subnet + " could not be created. Reason: " + $_.Exception.Message) -foregroundColor "warn" return $null } return $subnetAD } function set-subnet { param($subnetAD, $siteAD, $location) try { $subnetAD = Set-ADReplicationSubnet -Identity $subnetAD -Site $siteAD -Location $location -Server $dc -ErrorAction Stop -PassThru } catch { log-write ("ADReplicationSubnet " + $subnet + " could not be set. Reason: " + $_.Exception.Message) -foregroundColor "warn" return $null } return $subnetAD } function get-siteLinkAD { param($siteAD, $replicationPartnerAD) $linkName = $replicationPartnerAD.Name + "-" + $siteAD.Name $ldapFilterSiteLink = "(&(objectCategory=siteLink)(objectClass=siteLink)(name=" + $linkName + "))" $siteLinkAD = Get-ADObject -LDAPFilter $ldapFilterSiteLink -SearchBase $sitesPath -Server $dc -Properties siteList return $siteLinkAD } function set-siteLinkAD { param($sitelinkAD, $siteAD, $replicationPartnerAD) try { $siteLinkAD = Set-ADReplicationSiteLink -Identity $siteLinkAD -Replace @{siteList=@($siteAD.distinguishedName,$replicationPartnerAD.distinguishedName)} -Server $dc -PassThru } catch { log-write ("ADReplicationSiteLink " + $siteLinkAD + " could not be set. Reason: " + $_.Exception.Message) -foregroundColor "warn" return $null } return $siteLinkAD } function create-siteLink { param($siteAD, $replicationPartnerAD) $linkName = $replicationPartnerAD.Name + "-" + $siteAD.Name try { $siteLinkAD = New-ADReplicationSiteLink -Name $linkName -SitesIncluded $replicationPartnerAD, $siteAD -Cost 100 -InterSiteTransportProtocol IP -PassThru -Server $dc -ErrorAction Stop } catch { log-write ("ADReplicationSiteLink " + $linkName + " could not be created. Reason: " + $_.Exception.Message) -foregroundColor "warn" return $null } return $siteLinkAD } function verify-replication { param($siteAD) $replicationPartner = get-replicationPartner $siteAD log-write ("Replication partner should be: " + $replicationPartner) $replicationPartnerAD = get-siteAD $replicationPartner if($replicationPartnerAD -ne $null) { log-write ("Replication partner found in AD.") -foregroundColor "Green" } else { log-write ("Replication partner could not be found in AD") -foregroundColor "Red" log-write ("Attempting to create replication partner...") -foregroundColor "Yellow" $location = "Unknown" $replicationPartnerAD = create-site $replicationPartner $location if($replicationPartnerAD -ne $null) { log-write ("Replication partner successfully created.") -foregroundColor "Green" } else { log-write ("Replication partner could not be created!") -foregroundColor "warn" return $null } } log-write ("Getting site link...") -foregroundColor "Yellow" $siteLinkAD = get-siteLinkAD $siteAD $replicationPartnerAD if($siteLinkAD -eq $null) { log-write ("Site link could not be found. Attempting to create it...") -foregroundColor "Yellow" $siteLinkAD = create-siteLink $siteAD $replicationPartnerAD if($siteLinkAD -eq $null) { log-write ("Site link could not be created!") -foregroundColor "warn" return $null } else { log-write ("Site link successfully created.") -foregroundColor "Green" return $siteLinkAD } } elseif(($siteLinkAD.siteList -contains $siteAD) -and ($siteLinkAD.siteList -contains $replicationPartnerAD)) { log-write ("Site link exists and is correct") -foregroundColor "Green" return $siteLinkAD } else { log-write ("Site link found but replication partner is wrong") -foregroundColor "Red" log-write ("Attempting to set replication partner...") -foregroundColor "Yellow" $siteLinkAD = set-siteLinkAD $siteLinkAD $siteAD $replicationPartnerAD if($siteLinkAD -eq $null) { log-write ("Replication partner could not be set!") -foregroundColor "warn" return $null } else { log-write ("Site link had incorrect replication partners and was corrected") -foregroundColor "Green" return $siteLinkAD } } } function delete-subnet { param($subnetAD) try { Remove-ADObject -Identity $subnetAD -Confirm:$false -Server $dc -ErrorAction Stop } Catch { log-write ("Subnet " + $subnetAD.Name + " could not be deleted. Reason: " + $_.Exception.Message) -foregroundColor "warn" return $false } return $true } function export { param($network) if(($network.SubnetStatus -eq "Error") -or ($network.SiteStatus -eq "Error") -or ($network.SiteLinkStatus -eq "Error")) { $network.OverallStatus = "Error" } else { $network.OverallStatus = "OK" } $network | Export-Csv -Delimiter ';' -Path $logFileSmall -NoTypeInformation -Append -Encoding UTF8 } function remove-newlines { param($string) $string = $string = ($string.Replace("`n"," ")).Replace("`r","") return $string } function check-csvPath { param($path) if($path.Length -le 4) { log-write("Entered path (" + $path + ") is not a valid path") -foregroundColor "Red" return $false } if($path -eq [String]::Empty) { log-write ("No path entered") -foregroundColor "Red" return $false } if($path -eq $null) { log-write ("No path entered") -foregroundColor "Red" return $false } try { $testPath = Test-Path -LiteralPath $path -ErrorAction Stop } catch { log-write ("Could not check entered path (" + $path + "). Reason: " + $_.Exception.Message) -foregroundColor "warn" return $false } if($testPath -eq $false) { log-write($path + " could not be found") -foregroundColor "Red" return $false } else { if($path.SubString($path.Length - 4,4) -ne ".csv") { log-write($path + " is not a .csv file") -foregroundColor "Red" return $false } else { $firstLine = Get-Content -First 1 -LiteralPath $path if($firstLine -ne "City;Address;Branch;Country;NetworkAddress;Status;Subnet;LocationCode") { log-write ($path + " has an invalid header (" + $firstLine + "). Header must be: City;Address;Branch;Country;NetworkAddress;Status;Subnet;LocationCode") -foregroundColor "Red" return $false } log-write ($path + " found") -foregroundColor "Green" return $true } } } function clean-path { param($path) if(($path -ne [String]::Empty) -and ($path -ne $null)) { $path = $path.TrimEnd("\") } return $path } function ask-csvPath { $path = Read-Host("Enter FULL path to .csv file") $path = clean-path $path while((check-csvPath $path) -eq $false) { $path = Read-Host("Enter FULL path to .csv file") $path = clean-path $path } return $path } init-log $csvPath = ask-csvPath $csv = Import-CSv -Path $csvPath -Delimiter ';' -Encoding UTF8 foreach($network in $csv) { log-write ("#### NEW LINE ####") $network | Add-Member NoteProperty "Location" $null $network | Add-Member NoteProperty "SiteStatus" $null $network | Add-Member NoteProperty "SubnetStatus" $null $network | Add-Member NoteProperty "SiteLinkStatus" $null $network | Add-Member NoteProperty "OverallStatus" $null log-write ("Network: " + $network.NetworkAddress) log-write ("SubnetBits: " + $network.Subnet) $subnetMask = get-subnetMask $network.Subnet log-write ("SubnetMask: " + $subnetMask) $subnet = $network.NetworkAddress + "/" + $subnetMask log-write ("Subnet: " + $subnet) if(($network.Address -ne $null) -and ($network.Address -ne [String]::Empty)) { $network.Address = remove-newlines $network.Address } else { $network.Address = "Unknown address" } if(($network.City -ne $null) -and ($network.City -ne [String]::Empty)) { $network.City = remove-newlines $network.City } else { $network.City = "Unknown city" } if(($network.Branch -ne $null) -and ($network.Branch -ne [String]::Empty)) { $network.Branch = remove-newlines $network.Branch } else { $network.Branch = "Unknown branch" } $location = $network.Branch + " - " + $network.City + " - " + $network.Address $network.location = $location log-write ("Location: " + $location) $network.Status = remove-newlines $network.Status if($network.Status -ieq "active") { log-write ("Status: " + $network.Status) if(($network.LocationCode -ne [String]::Empty) -and ($network.LocationCode -ne $null)) { $locationCode = ($network.Country + $network.LocationCode) log-write ("LocationCode: " + $locationCode) $siteAD = get-siteAD $locationCode if($siteAD -eq $null) { log-write ("Site " + $locationCode + " could not be found. Creating site...") -foregroundColor "Yellow" $siteAD = create-site $locationCode $location if($siteAD -eq $null) { log-write ("Site " + $locationCode + " could not be created!") -foregroundColor "warn" $network.SiteStatus = "Error" export $network continue } else { log-write ("Site " + $locationCode + " was successfully created") -foregroundColor "Green" $network.SiteStatus = "OK" } } else { log-write ("Site " + $locationCode + " found.") -foregroundColor "Green" if($siteAD.location -ne $location) { log-write ("Location of site has changed. Attempting to update...") -foregroundColor "Yellow" $siteAD = set-site $siteAD $location if($siteAD -ne $null) { log-write ("Location was successfully updated.") -foregroundColor "Green" $network.SiteStatus = "OK" } else { log-write ("Could not update location!") -foregroundColor "warn" $network.SiteStatus = "Error" } } else { $network.SiteStatus = "OK" } } log-write ("Verifying SiteLink...") -foregroundColor "Yellow" $siteLinkAD = verify-replication $siteAD if($siteLinkAD -eq $null) { log-write ("Error during site link verification") -foregroundColor "warn" $network.SiteLinkStatus = "Error" export $network continue } else { $network.SiteLinkStatus = "OK" log-write ("Site link successfully verified") -foregroundColor "Green" } log-write ("Getting subnet...") -foregroundColor "Yellow" $subnetAD = get-subnetAD $subnet if($subnetAD -eq $null) { log-write ("Subnet could not be found in AD. Attempting to create it...") -foregroundColor "Yellow" $subnetAD = create-subnet $subnet $siteAD $location if($subnetAD -ne $null) { log-write ("Subnet successfully created.") -foregroundColor "Green" $network.SubnetStatus = "OK" } else { log-write ("Subnet could not be created") -foregroundColor "warn" $network.SubnetStatus = "Error" export $network continue } } elseif($subnetAD.siteObject -eq $siteAD) { log-write ("Subnet was found and is assigned correctly") -foregroundColor "Green" $network.SubnetStatus = "OK" } else { log-write ("Subnet was found in AD, but is assigned to a wrong site. Attempting to correct...") -foregroundColor "Yellow" $subnetAD = set-subnet $subnetAD $siteAD $location if($subnetAD -ne $null) { log-write ("Subnet was successfully assigned to the new site") -foregroundColor "Green" $network.SubnetStatus = "OK" } else { log-write ("Subnet could not be assigned to the new site") -foregroundColor "warn" $network.SubnetStatus = "Error" } } if($subnetAD.location -ne $location) { log-write ("Location of subnet has changed. Attempting to update...") -foregroundColor "Yellow" $subnetAD = set-subnet $subnetAD $siteAD $location if($subnetAD -ne $null) { log-write ("Location was successfully updated.") -foregroundColor "Green" $network.SubnetStatus = "OK" } else { log-write ("Could not update location!") -foregroundColor "warn" $network.SubnetStatus = "Error" } } } else { log-write ("LocationCode is empty. Skipping...") -foregroundColor "Red" $network.SiteStatus = "Error" $network.SubnetStatus = "Error" } } elseif($network.Status -ieq "inactive") { log-write ("Status: " + $network.Status) log-write ("Getting subnet...") -foregroundColor "Yellow" $subnetAD = get-subnetAD $subnet if($subnetAD -eq $null) { log-write ("Subnet does not exists") -foregroundColor "Green" $network.SubnetStatus = "OK" } else { log-write ("Attempting to delete subnet...") -foregroundColor "Yellow" if((delete-subnet $subnetAD) -eq $true) { log-write ("Subnet successfully deleted") -foregroundColor "Green" $network.SubnetStatus = "OK" } else { log-write ("Error during deletion of subnet") -foregroundColor "warn" $network.SubnetStatus = "Error" } } } else { log-write ("Status: " + $network.Status) } Start-Sleep -Seconds 2 export $network }