<# .SYNOPSIS This Powershell script will update the hooks for ONE Repo an all servers .DESCRIPTION This Powershell script will update the hooks for ONE Repo an all servers from the current machine. It will Locate the Repo Master Determine the Replica machines (Slaves) This will give a complete list of machines to replicate hooks scripts Determine the source of the hooks scripts If the Master instance of the Repo has a 'specialhooks' marker file then the hooks in the Master Repo will be replicated to all slaves If the Master does not have the 'specialhooks' marker then then global hooks will be copied from the current machine For each slave it will: Locate the Machine path to Slave Repo Copy appropriate hook files to the Repo Propagate the specialhooks file Global Hook files are found in the Repostitory root and are *.cmd .PARAMETER Repo Name of the Repo to create .PARAMETER TestMode If present then no copy operations will be done .EXAMPLE UpdateRepoHooks.ps1 -Repo myRepo .NOTES Uses a number of cmdlets provided by VisualSVN. #> # Param ( [ parameter (Mandatory=$true, HelpMessage="Enter the name of the Repository")] [string] $Repo, [switch] $TestMode ) # # Get information on a named repo on the named Computer function GetRepoInfo( $repoName, $ComputerName ) { $repoData = Get-CimInstance -Namespace "root\VisualSVN" -ClassName VisualSVN_Repository -ComputerName $ComputerName | Where { $_.Name -eq $repoName } Return $RepoData } # # Get information on the current SVN server on the named Computer # function GetSvnInfo($ComputerName) { $repoData = Get-CimInstance -Namespace "root\VisualSVN" -ClassName VisualSVN_Service -ComputerName $ComputerName Return $RepoData } # # Convert Absolute Path to UNC on a named computer # Function AbsToUnc( $ComputerName, $absPath ) { return '\\' + $ComputerName + '\' + $absPath.Replace(":","$") } # Init Data $ALLSERVERS = @() # # Locate the Repo Master # Examine current machine and determine data about the repo # $repoData = GetRepoInfo $Repo $env:COMPUTERNAME If ($repoData -eq $null ) { Write-Error "The repo ($REPO) does not exist on the local machine" -Category InvalidArgument Return } #Write-Host 'RepoData:' , ($repoData | Format-List | Out-String) $CURMASTER = $repoData.MasterServer If (! $CURMASTER) { $CURMASTER = $env:COMPUTERNAME } Write-Host "Current Master:", $CURMASTER $CURMASTER = $CURMASTER.ToUpper() $ALLSERVERS += $CURMASTER # # Examine the repo on the Master # $RepoData = Get-SvnRepositoryReplication $REPO -CimSession $CURMASTER #Write-Host ($RepoData | Format-List | Out-String) $RepoData.Replicators | ForEach-Object { $name = $_ -match '\w+\\(\w+)' If ( $name ) { $ALLSERVERS += $matches[1].ToUpper() } else { Write-Error "Replicator data in unexepcted form: $_" -Category InvalidData Return; } } Write-Host "All Servers:", $ALLSERVERS # # Determine the root of the Repositores on this computer # This will be the source for the Hook Scripts # $SvnInfo = GetSvnInfo $env:COMPUTERNAME if ($SvnInfo -eq $null) { Write-Error 'Cannot get VisualSVN info' Exit } # Validate the Repo Root $repoRoot = $SvnInfo.RepositoriesRoot If (!(Test-Path $repoRoot)) { Write-Error 'RepositoriesRoot - Does not exist' Exit } Write-Host "Local Repo Root: ", $repoRoot # # Examine the 'Master' repo # Determine if it contains a specialhooks marker # $masterRepo = GetRepoInfo $Repo $CURMASTER $masterHookPathUnc = AbsToUnc $CURMASTER ($masterRepo.Path + '\hooks') $specialHooks = Test-Path ($masterHookPathUnc + '\specialhooks') Write-Host 'Master Hooks: ', $masterHookPathUnc Write-Host 'Special Hooks: ', $specialHooks # # Process each Machine in the set # $ALLSERVERS | ForEach-Object { Write-Host "Processing: ", $_ # # If the Master Repo had specialhooks, then copy the Master repo Hooks # Otherwise copy the global hooks # If ($specialHooks) { If ( $_ -eq $CURMASTER ) { Return } $HookSrc = $masterHookPathUnc } else { $HookSrc = $repoRoot } # # Get target Repo Information # Want the path to the hooks directory # $targetRepo = GetRepoInfo $Repo $_ $hookPath = $targetRepo.Path + '\hooks' $hookPathUnc = AbsToUnc $_ $hookPath # # Copy files to Remote Computer # Write-Host "Hooks Found", $hookPathUnc $HookFileCount = 0 Get-ChildItem $HookSrc -Filter '*.cmd' | ForEach-Object { $srcFile = $_.Name If ( ! $TestMode ) { Copy-Item $_.FullName -Destination $hookPathUnc } $HookFileCount++ } Write-Host ("{0,20} : {1}" -f $Repo, "Hooks copied: $HookFileCount") # # Propagate specialhook information # If ( ! $TestMode ) { If ($specialHooks) { Write-Host ("{0,20} : {1}" -f $Repo, "Copy specialhooks") Copy-Item ($HookSrc + '\specialhooks') -Destination $hookPathUnc } else { Remove-Item ($hookPathUnc + '\specialhooks') -ErrorAction SilentlyContinue } } }