#Load sharepoint snapin
$snapin = Get-PSSnapin | Where-Object {$entry.Name -eq 'Microsoft.SharePoint.Powershell'}
if ($snapin -eq $null) 
{ 
    Add-PSSnapin "Microsoft.SharePoint.Powershell"
}

#Define variables
$logMessage =""
$siteURL = "http://contoso"
$site = Get-SPSite $siteURL
$sitesCSV = Import-Csv C:\Publishing-Sites.csv
#sort the object so that top level sites get created before lower level ones in order to avoid errors
$sitesCSV = $sitesCSV | Sort-Object {$_.EN_URL}
#array to contain the sites that are created
$added = @()
#CSV file is now in memory delete the original so that a new one can be added.
Remove-Item D:\Hub\Hub-Sites.csv 
$currentDate = get-date
$logFile = "C:\CreationLog.csv"

 
foreach($entry in $sitesCSV){

	$WebURL = $entry.EN_URL
	$WebURLFR = $entry.FR_URL
	$WebTitle = $entry.EN_Title
	$WebTitleFR = $entry.FR_Title
	$PageLayoutName = $entry.Template + ".aspx"

    #check row values for proper input

    #check if blank fields
    if(($webURL -eq "") -or ($WebTitle -eq "") -or ($PageLayoutName -eq ".aspx") -or ($WebURLFR -eq "") -or ($WebTitleFR -eq ""))
    {
        #blank fields found
        $row = "$currentDate,ERROR,Blank fields found,$entry"
        $row | Out-File -Append $logFile
        continue
    } 

    #check if french URL is full URL or more than one level
    if($WebURLFR -contains "/")
    {
        #french URL is bad
        $row = "$currentDate,ERROR,Bad French URL,$entry"
        $row | Out-File -Append $logFile
        continue
    }

    #check for over 256 characters for title and truncate
    if(($WebTitle.length -gt 254) -or ($WebTitleFR.length -gt 254))
    {
	$WebTitle = $WebTitle.substring(0,253);
	$WebTitleFR = $WebTitleFR.substring(0,253);
    }

    #check if english URL is full URL
    if(($WebURL -like "http*") -eq $false)
    {
        #french URL is bad
        $row = "$currentDate,ERROR,Bad english URL,$entry"
        $row | Out-File -Append $logFile
        continue
    }

    #check if URL contains special characters
    if(($WebURL.Replace("http://","") -notmatch "^[a-zA-Z0-9\s-]") -or ($WebURLFR -notmatch "^[a-zA-Z0-9\s-]"))
    {
        $row = "$currentDate,ERROR,URL contains special characters,$entry"
        $row | Out-File -Append $logFile
        continue
    }
    
    #check if site exists
    $exists = (Get-SPWeb $WebURL -ErrorAction SilentlyContinue) -ne $null

    if($exists -eq $true)
    {
        #site exists. Write to log file and move to next entry
        $row = "$currentDate,WARNING,Duplicate Site,$entry"
        $row | Out-File -Append $logFile
        continue
    }

    try{

	#Create English Site
        $logMessage = "Creating site"
	New-SPWEB -Url $WebUrl -Template CMSPUBLISHING#0 -Name $WebTitle -AddToQuickLaunch -UseParentTopNav -erroraction stop

	$web = Get-SPWeb $WebUrl
	#Enable French alternate language
        $logMessage = "Setting english alternate language"
	$web.IsMultilingual = $true;
	$web.AddSupportedUICulture(1036);
	$web.update();

	#Get Publishing Site and Web
        $logMessage = "Getting english publishing site"
	$PublishingSite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($Web.Site)
	$PublishingWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
	   
	#Get New Page Layout
        $logMessage = "Getting english page layout"
	$SitePageLayouts = $PublishingSite.GetPageLayouts($false)
	$NewPageLayout = $SitePageLayouts | ? {$_.Name -eq $PageLayoutName}

	#update landing page Page Layout and title
        $logMessage = "Setting English layout and title"
	$PublishingPage = $PublishingWeb.GetPublishingPage($WebURL + "/Pages/default.aspx")  
	$PublishingPage.CheckOut()
	$PublishingPage.Title = $WebTitle
        if($NewPageLayout -eq $null)
        {
            $row = "$currentDate,WARNING,Bad Template name,$entry"
            $row | Out-File -Append $logFile
        }
        else
        {
	    $PublishingPage.Layout = $NewPageLayout
        }
	    $PublishingPage.ListItem.Update();
	    $PublishingPage.CheckIn("Page layout Updated via PowerShell")

	$web.Update()
        #add the row to the added array
        $added += $entry
        #log site creation
        $row = "$currentDate,INFO,English Site Created,$entry"
        $row | Out-File -Append $logFile
	
    }
    catch
    {
        #there was an error.  Log error message to log file and move to next entry
        $row = "$currentDate,ERROR,$logMessage,$entry"
        $row | Out-File -Append $logFile
        continue
    }
    finally
    {
        
	$web.dispose()
    }    
}

if($added.length -le 0)
{
    return
}

#wait 5 minutes for variations to be created
Start-Sleep -Seconds 300

#start french site creation
$logMessage = "Start french site creation"
$siteURL = "http://contoso"
$RelationShipListName = "Relationships List"
$FieldName = "ObjectID"
$site = Get-SPSite $siteURL
$spWeb = Get-SPWeb $SiteURL


#iterate through @added as it now contains all the sites that have been created
foreach ($frenchRow in $added)
{
    
	try{
        $numberOfTries = 0
        $exists = $true
        do{

            $spRelationshipList = $spweb.GetList($RelationShipListName)
            $ENUrl = $frenchRow.EN_URL
	    $FRTitle = $frenchRow.Fr_Title
	    $NewFRUrl = $frenchRow.FR_URL
	
	    #Get French site URL
	    foreach($EN_Item in $spRelationshipList.Items)
	    {
		$EN_hyperlink = New-Object Microsoft.SharePoint.SPFieldUrlValue($EN_Item[$FieldName])
		if ($EN_hyperlink.URL -eq $ENUrl) 
		{
			$GroupGUID = $EN_Item["GroupGuid"]
			$ID = $EN_Item["ID"]
		}
	    }

	    foreach($FR_Item in $spRelationshipList.Items)
	    {
		$FR_hyperlink = New-Object Microsoft.SharePoint.SPFieldUrlValue($FR_Item[$FieldName])
		if (($GroupGUID -eq $FR_Item["GroupGuid"]) -and ($ID -ne $FR_Item["ID"]))
		{
			$CurrFRUrl = $FR_hyperlink.URL
		}
	    }
            
            #has variation been created?  
            #if not we wait 5 minutes for up to two tries in order to let the variation timer job do its thing

            $exists = (Get-SPWeb $CurrFRUrl -ErrorAction SilentlyContinue) -ne $null

            if($exists -eq $false)
            {
                Start-Sleep -Seconds 300
            }
            $numberOfTries++
            
        }while(($numberOfTries -le 6) -and ($exists -eq $false))

        if($exists -eq $false)
        {
            $row = "$currentDate,ERROR,Variation does not exist,$entry.ToString()"
            $row | Out-File -Append $logFile
            continue
        }
	
	    #Change the site Title
            $logMessage = "Change french title"
	    $web = Get-SPWeb $CurrFRUrl
	    $web.Title = $FRTitle
		
	    #Enable English alternate language
            $logMessage = "Enable French site alternate language"
	    $web.IsMultilingual=$true
	    $web.AddSupportedUICulture(1033)
	    $web.Update()

	    #Get Publishing Site and Web
            $logMessage = "Get french puglishing site"
	    $PublishingSite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($Web.Site)
	    $PublishingWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)

	    #update landing page  title
            $logMessage = "Update french landing page title"
	    $PublishingPage = $PublishingWeb.GetPublishingPage($CurrFRUrl + "/Pages/default.aspx")  
	    $PublishingPage.CheckOut()
	    $PublishingPage.Title = $FRTitle
	    $PublishingPage.ListItem.Update();
	    $PublishingPage.CheckIn("Page layout Updated via PowerShell")

	    $web.Update()
        
            $row = "$currentDate,INFO,French Site Customized,$entry"
            $row | Out-File -Append $logFile
    }
    catch
    {
        $row = "$currentDate,ERROR,$logMessage,$entry.ToString()"
        $row | Out-File -Append $logFile
        continue
    }
    finally
    {
	    
	    $web.dispose()
    }
}

#sort the @added array so that we can change the URL without breaking
$added = $added | Sort-Object {$_.EN_URL} -Descending
$logMessage = "Change French URL"
#iterate through @added a second time in order to change the URLs of the french sites now that they have been customized
foreach ($frenchRow in $added)
{
    $spRelationshipList = $spweb.GetList($RelationShipListName)
	try{
        $ENUrl = $frenchRow.EN_URL
	    $FRTitle = $frenchRow.Fr_Title
	    $NewFRUrl = $frenchRow.FR_URL
	
	    #Get French site URL
	    foreach($EN_Item in $spRelationshipList.Items)
	    {
		    $EN_hyperlink = New-Object Microsoft.SharePoint.SPFieldUrlValue($EN_Item[$FieldName])
		    if ($EN_hyperlink.URL -eq $ENUrl) 
		    {
			    $GroupGUID = $EN_Item["GroupGuid"]
			    $ID = $EN_Item["ID"]
		    }
	    }

	    foreach($FR_Item in $spRelationshipList.Items)
	    {
		    $FR_hyperlink = New-Object Microsoft.SharePoint.SPFieldUrlValue($FR_Item[$FieldName])
		    if (($GroupGUID -eq $FR_Item["GroupGuid"]) -and ($ID -ne $FR_Item["ID"]))
		    {
			    $CurrFRUrl = $FR_hyperlink.URL
		    }
	    }
	
	    $web = Get-SPWeb $CurrFRUrl
        #Change the French Site URL
	    Get-SPWeb $CurrFRUrl | Set-SPWeb -RelativeURL $NewFRUrl -ErrorAction Stop
        $web.Update()
        $row = "$currentDate,INFO,French Site URL Changed,$entry"
        $row | Out-File -Append $logFile
    }
    catch
    {
        $row = "$currentDate,ERROR,$logMessage,$entry.ToString()"
        $row | Out-File -Append $logFile
        continue
    }
    finally
    {
	    
	    $web.dispose()
    }
}