<# .SYNOPSIS This Powershell script will replicate Repos from a Master Server .DESCRIPTION This Powershell script will setup slave Repos from a specified Master. Assumption: The slave Repos will be setup on the current machine It will Scan the Repos on the Master Determine those that are mastered on the master (ignore non Master Repos) Determine those Repos not on the current machine Setup as Slave Replicas those Repos that are not on the current machine Add this machine to the Masters list of replicators Create the Repo and link it to the Master Copy in hook files from the master .PARAMETER Master Name of new the master server .EXAMPLE ReplicateRepos.ps1 -Master MasterMachine .NOTES Uses a number of cmdlets provided by VisualSVN. #> # # Param ( [ parameter (Mandatory=$true, HelpMessage="Enter the name of the Master Repository server")] [string] $MASTER ) # # Get Data about a named Repo on the local machine # function GetRepoInfo( $repoName ) { $repoData = Get-CimInstance -Namespace "root\VisualSVN" -ClassName VisualSVN_Repository | Where { $_.Name -eq $repoName } Return $RepoData } # # Get information on a named repo on the named Computer function GetRemoteRepoInfo( $repoName, $ComputerName ) { $repoData = Get-CimInstance -Namespace "root\VisualSVN" -ClassName VisualSVN_Repository -ComputerName $ComputerName | Where { $_.Name -eq $repoName } Return $RepoData } # # Convert Absolute Path to UNC on a named computer # Function AbsToUnc( $ComputerName, $absPath ) { return '\\' + $ComputerName + '\' + $absPath.Replace(":","$") } # # Verify that the Master exists # $masterSession = New-CimSession $MASTER -ErrorAction Ignore If($masterSession -eq $null) { Write-Error "The named computer ($MASTER) does not exist" -Category InvalidArgument Exit } # # Get a list of all Repos Mastered on the Master # Get-SvnRepository -CimSession $masterSession | Where { $_.Type -eq 'VdfsMaster' } | ForEach-Object { # # See if the Repo exists locally # $repoName = $_.Name $repoData = Get-SvnRepository $repoName -ErrorAction SilentlyContinue if ($repoData -ne $null) { Write-Host ("{0,20} : {1}" -f $repoName, 'Already Exists') Return } # # Get a list of Replication Slaves for the Repo # $repoRepData = Get-SvnRepositoryReplication $repoName -CimSession $masterSession $replicators = $repoRepData.Replicators + "$env:COMPUTERNAME$" Set-SvnRepositoryReplication $repoName -Replicators $replicators -CimSession $masterSession # # Create the Repo # Connect it to the Master # Write-Host ("{0,20} : {1}" -f $repoName, 'Creating Replica') $newRepo = New-SvnRepository $_.Name -Type VdfsSlave -MasterServer $MASTER # # Get Data about the new Repo # Need the Repo disk address # $repoInfo = GetRepoInfo $repoName If ($repoInfo -eq $null ) { Write-Error 'Cannot fetch Repo Info for created Repo: $repoName' Return } $HookDst = $repoInfo.Path # # Determine the source of the hooks # $masterRepo = GetRemoteRepoInfo $repoName $MASTER $masterHookPathUnc = AbsToUnc $MASTER ($masterRepo.Path + '\hooks') $specialHooks = Test-Path ($masterHookPathUnc + '\specialhooks') Write-Host ("{0,20} : {1}" -f $repoName, "Master Hooks: $masterHookPathUnc") #Write-Host ("{0,20} : {1}" -f $repoName, "Special Hooks: $specialHooks") $HookSrc = $masterHookPathUnc #Write-Host "HookDst: $HookDst" #Write-Host "HookSrc: $HookSrc" $HookFileCount = 0 Get-ChildItem $HookSrc -Filter '*.cmd' | ForEach-Object { $srcFile = $_.Name Write-Host ("{0,20} : {1}" -f $repoName, "Copy Hook: $srcFile") Copy-Item $_.FullName -Destination ($HookDst + '/hooks') $HookFileCount++ } If ($HookFileCount -eq 0 ) { Write-Host ("{0,20} : {1}" -f $repoName, "Warning: No Hook files found in the current Repository Store") } If ($specialHooks) { Write-Host ("{0,20} : {1}" -f $repoName, "Copy specialhooks") Copy-Item ($HookSrc + '\specialhooks') -Destination ($HookDst + '/hooks') } }