In a production environment the four eyes principle is often used so that a file can not be reviewed and released by the same user. In some cases the Vault configuration is not enough to configure it. This script shows how to configure this using powerVault and powerEvents by hooking up to theUpdateFileStates VaultEvent.


Crate a new event script

Open the powerEvents IDE and create a new event script with the name YourCompanyName.YourEyesPrinciple.ps1 in "C:\ProgramData\coolOrange\powerEvents\Events".


Register to Vault Lifecycle State changes

First the VaultEvent UpdateFileStates_Restrictions must be registered and configured so that it triggers when a file state gets updated and that it executes the function "FourEyesCheck":

Register-VaultEvent -EventName UpdateFileStates_Restrictions -Action FourEyesCheck


Define a FourEyesCheck function 

This function loops over the files that where selected for a Lifecycle State change. Only for Lifecycle State changes from "For Review" to "Released" the function checks if the user that created the last version of the file is the same user that is trying to release the file. If this is the case a restriction will be displayed in Vault and the user can not release the file.

Function FourEyesCheck ($files) {
    foreach ($file in $files) {
        if ($file._State -eq "For Review" -and $file._NewState -eq "Released") { #Adapt "For Review" and "Released" to your lifecycle definition
            if ($file._CreateUserName -eq $vaultConnection.UserName) {
                Add-VaultRestriction -EntityName $file.Name -Message "File can not be reviewed and released by the same user"
            }
        }
    }
}


JobServer user

When a UpdateRevisionTable or a property update job is executed the last version of the file could be from the user "JobServer" and the file could always be released by the same user that reviewed the file. To avoid this the function has to be extended to find the correct version where the file state was changed to "For Review" 


This extended script checks if the right transition is happening, then gets all file versions of the files that are changing state. The array gets reversed or else it would start counting from version 1. Then the script searches for the version where the state was "For Review" and checks if the user that created that version is the same user that is trying to release the file. If the user is not the same the next file is checked.

Function FourEyesCheck ($files) {
    foreach ($file in $files) {
        if ($file._State -eq "For Review" -and $file._NewState -eq "Released") { #Adapt "For Review" and "Released" to your lifecycle definition
            $allFileVersions = $vault.DocumentService.GetFilesByMasterId($file.MasterId)
            [array]::Reverse($allFileVersions)
            foreach ($version in $allFileVersions) {
                if ($version.FileLfCyc.LfCycStateName -eq "For Review") { #Adapt "For Review" to your lifecycle definition
                    if ($version.CreateUserName -eq $vaultConnection.UserName) {
                        Add-VaultRestriction -EntityName $file.Name -Message "File can not be reviewed and released by the same user"
                    }
                    else {
                        break
                    }       
                }
            }
        }
    }
}


See Also

Getting Started with powerEvents (coolOrange Wiki)

Register-VaultEvent (coolOrange Wiki)

Add-VaultRestriction (coolOrange Wiki)

UpdateFileStates (coolOrange Wiki)