Using PowerShell Scripts in VisualSVN Hooks
Throughout this post I'm focusing on VisualSVN, probably the simplest Subversion server to set up on Windows, but most of the stuff should be applicable to other Subversion builds for Windows as well. Hooks in Subversion can be used to execute custom logic before or after certain actions in repository: commit, lock, unlock and revision property change. They are defined by specifying a batch script that gets executed at that point. In my particular case I wanted to use a PowerShell script before commit to prevent certain files being committed to the repository.
PowerShell scripts can easily be executed from batch scripts by calling
PowerShell.exe and passing the script as the first argument, followed by its arguments. The batch file in my case is therefore really simple:
set repository=%1 set transaction=%2 PowerShell.exe D:\SVN\hooks\pre-commit %repository% %transaction%
This will execute
pre-commit.ps1 PowerShell script which contains all the necessary logic. Notice the full path to the script – the current path doesn't seem to be set by Subversion when calling the scripts.
To call this script from a specific hook in a repository you can open VisualSVN Server Manager, select the repository in the tree view on the left and invoke All Tasks > Manage Hooks... command from the context menu. In the next window double click on Pre-commit hook to open the editor and enter this script.
There is still one thing remaining in case you haven't used PowerShell on the machine before: you need to change the execution policy to allow running scripts (make sure PowerShell console was started with administrative privileges):
Without this step PowerShell will give a very descriptive error when attempting to run the script:
File D:\SVN\hooks\pre-commit.ps1 cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details.
Here it gets interesting: even after changing the execution policy the script still returned the same error when called by VisualSVN. Only after accidentally calling
Set-ExecutionPolicy without administrative privileges and seeing the following error message it occurred to me:
Set-ExecutionPolicy : Access to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell' is denied.
The PowerShell execution policy setting is stored in registry which means that it needs to be set individually for both 32 and 64 bit processes. VisualSVN is 32-bit application running 32-bit PowerShell. I was setting the execution policy from a 64-bit PowerShell console, keeping it intact for 32-bit processes. The solution immediately became obvious: start 32-bit PowerShell console with administrative privileges (by starting Windows PowerShell (x86) from start menu) and change the execution policy from there. After doing that the script started working from VisualSVN as well.