#Import PVS PowerShell Module
#This script file is intended t0 provide an example script of how vDisk replication can be performed.

#This script was created by Rob Zylowski Citrix CCS with help from many folks
#It should be used as an example of how to perform PVS Disk replication.
#This script will interogate defined PVS master Servers to compile a list of stores and store paths.
#
#Although every effort has been made to ensure that these sample scripts work properly, 
#Citrix disclaims any responsibility for any and all liability or responsibility for any 
#damages that may result from using these scripts. 
#The sample scripts are provided to you as is, with no warranty or guarantees.
#

#Version 2.1 7-11-2018
#Version 2.3 9-25-2018
#Version 2.4 11-12-2018

try{
    Import-Module 'C:\Program Files\Citrix\Provisioning Services console\Citrix.PVS.SnapIn.dll' -ErrorAction Stop
} catch {
    Write-Host "PVS PowerShell Snap-In Not Found" -BackgroundColor Black -ForegroundColor Red
    $msg = "PVS PowerShell Snap-In Not Found on $env:computername.  Script terminated."
    Write-EventLog -LogName Application -Source $logSource -EventId 2 -EntryType Error -Message $msg -Category 0
    exit
}

function Get-ScriptDirectory
#This gets the current directlry which we use to store the text data files
{
 $Invocation = (Get-Variable MyInvocation -Scope 1).Value
 Split-Path $Invocation.MyCommand.Path
}

$ScriptSource = Get-ScriptDirectory

Write-Host "Preparing DataTable object"

# Prepare global ServerTable object
$Global:PVSManTable = New-Object system.Data.DataTable "PVSManTable"
[array]$Columns = $("Farm","Site", "Server", "Store", "Path")
ForEach ($Column in $Columns) {$PVSManTable.Columns.Add($(New-Object system.Data.DataColumn $Column,([string])))}
ForEach ($Column in $PVSManTable.Columns) {$Column.DataType = [Object]}


$MastersFile = Get-Content "$ScriptSource\..\config\masters.txt" -Encoding ASCII
$Masters = New-Object System.Collections.ArrayList

if ($MastersFile -is [System.Array])
{
	$FirstMaster = $MastersFile[0].ToLower()
	foreach ($MasterServer in $MastersFile)
	{
		if ($MasterServer -ne ""){$Masters.Add($MasterServer)>$null}
	}
}
else
{
	$FirstMaster = $MastersFile.ToLower()
	$Masters.Add($MastersFile)>$null
}

foreach ($MasterServerName in $Masters)
{
	Write-Host "Connecting to Master Server $MasterServerName"
	Set-PvsConnection -Server $MasterServerName -ErrorAction SilentlyContinue
	$FarmInfo = Get-PvsFarm 
	$MasterFarm = $FarmInfo.FarmName
	$MasterServer = ""
	$MasterServer = Get-PvsServer -ServerName $MasterServerName -ErrorAction SilentlyContinue 
	$MasterStores = @{}
	#get Stores for Master
	
	$MasterStoresArray = Get-PvsStore
	foreach($Store in $MasterStoresArray)
	{
		$ServerStorePathOrig =  $Store.Path
		$ServerStorePath = $ServerStorePathOrig.Replace(":", "$")
		$StorePath = $ServerStorePath
		$myStore = $Store.Name
		Write-Host "Adding Master Store $myStore to Mater Store Hash"
		$MasterStores.Add($Store.StoreName,$Store.Path) >$null
	}

	if ($MasterServerName -eq $firstMaster)
	{
		$FirstMasterFQDN=$MasterServer.ServerFqdn
		$MaserServerObject = $MasterServer
	}
	if ($MasterServer.Name -eq $null){continue}

	# Creating global list
	Write-Host "Retrieving all required objects from PVS"
	[array]$AllSites = Get-PvsSite
	[array]$AllServers = Get-PvsServer
	[array]$AllStores = Get-PvsStore
	
	# Generate DataTable
	Write-Host
	Write-Host -ForegroundColor Blue "Generating synchronization table"
	ForEach ($Site in $AllSites) 
	{
		[string]$SiteID = $Site.SiteID
		$MasterSite = $Site.SiteName
		
		Write-Host -NoNewline "Retrieving replica servers for site "; Write-Host -ForegroundColor Blue $($Site.SiteName)
		ForEach ($Server in $AllServers) 
		{
			$ServerName = $Server.Name
			$ServerSiteName = $Server.SiteName
			
			Write-Host "Retrieving stores associated with server " -NoNewline; Write-Host -ForegroundColor Blue $($ServerName)
			$ServerStores = $null
			$ServerStores = Get-PVSServerStore -serverid $Server.serverId
			if ($ServerStores -eq $null)
			{
				write-host -ForegroundColor Red "Error retrieving $ServerName info "
				write-host -ForegroundColor black 
				continue
			}
			
			ForEach ($ServerStore in $ServerStores) 			
			{
				
				$Store = $AllStores | Where {$_.storeID -eq $($ServerStore.StoreID)}
				$StoreName = $Store.Name
				
				Write-Host "Retrieving slave servers associated with store " -NoNewline; Write-Host -ForegroundColor Blue $($Store.StoreName)
				$SlaveServers= Get-PVSServer -ServerName $ServerName
				
				ForEach ($Slave in $SlaveServers) 
				{
				
					$SlaveServerName = $Slave.ServerName
					#Connect to PVS Server to get FARM
					Set-PvsConnection -Server $SlaveServerName > $null
					if (!$?)
					{
						Write-Host "Error connecting to server [$ServerName].  This Server will be skipped. " -NoNewline -ForegroundColor Red; Write-Host -ForegroundColor Blue 
						continue
					}	
					$SlaveFarmInfo = Get-PvsFarm
					$SlaveFarm = $SlaveFarmInfo.FarmName
					
					$SlaveSite = $Slave.SiteName
				
					$SlaveStores = Get-PvsStore -ServerName $Slave.ServerName
					$SlaveStorePath = ""
					foreach ($SlaveStore in $SlaveStores)
					{
						if ($SlaveStore.Name -eq $Store.StoreName)
						{
							$SlaveStorePath = $SlaveStore.Path
						}
						#Destination
						$DPathIsShare = $true
						$StorePathTest = $SlaveStore.Path
						$SlaveStoreName = $SlaveStore.StoreName
						If ($SlaveStorePath[1] -eq ":") {
							$SlaveStorePath = $SlaveStorePath.Replace(":", "$")
							$DPathIsShare = $false
						}
						if(!$DPathIsShare)
						{					
							$SlaveStorePath="\\$SlaveServerName\$SlaveStorePath"
						}
					}
					Write-Host "	$($Slave.ServerName)"
					
					$TableRow2=$PVSManTable.NewRow()
					$TableRow2.Farm = $SlaveFarm
					$TableRow2.Site = $SlaveSite
					$TableRow2.Server = $SlaveServerName
					$TableRow2.Store = $Store
					$TableRow2.Path = $SlaveStorePath
					$PVSManTable.Rows.Add($TableRow2)
					
				}
			}
		}
	}
	
	$test = $null
}

$arrServerStore = New-Object System.Collections.ArrayList

if ($PVSManTable.Rows.Count -gt 0)
{
	#Now write the table out to a config file
	$manstorerowsfile = "$ScriptSource\..\config\manstoredrops.txt"
	if(Test-Path $manstorerowsfile){del $manstorerowsfile}
	$rowoutput2="Farm;Site;Store;Server;Path"
	$rowoutput2 | Out-File -LiteralPath $manstorerowsfile -Encoding ASCII
	ForEach ($row2 in $PVSManTable.Rows) 
	{

		$Farm = $row2.Farm
		$Site = $row2.Site
		$Server = $row2.Server
		$Store = $row2.Store.Name
		$Path = $row2.Path
		
		if ($arrServerStore -notcontains "$Server-$Store")
		{
			$arrServerStore.Add("$Server-$Store")>$null
			$rowoutput2="$Farm;$Site;$Server;$Store;$Path"
			$rowoutput2 | Out-File -LiteralPath $manstorerowsfile -Append -Encoding ASCII
		}
	}
}


