Maintaining Consistent Primavera P6 Client Configuration Files Across Multiple Users Using PowerShell – Part 2

PowerShell 5.0 icon

A refactored and updated version of the P6config.cmd script below allows for multiple profiles, both Local and Roaming. 

@echo off
setlocal enabledelayedexpansion
for %%A in (Local Roaming) do (
	set profpath=C:\Users\%username%\AppData\%%A\Oracle\Primavera P6\P6 Professional\18.8.0
	if exist !profpath! goto subroutine
	rem echo !profpath! does not exist.
	rem echo return
goto eof

copy "C:\Program Files\Oracle\Primavera P6\P6 Professional\18.8.0\Data\PrmBootStrapV2.xml" "!profpath!" /y 
powershell (Get-ChildItem '!profpath!\PrmBootStrapV2.xml').CreationTime = $(Get-Date) 
powershell (Get-ChildItem '!profpath!\PrmBootStrapV2.xml').LastAccessTime = $(Get-Date) 
powershell (Get-ChildItem '!profpath!\PrmBootStrapV2.xml').LastWritetime = $(Get-Date)
goto return


Maintaining Consistent Primavera P6 Client Configuration Files Across Multiple Users Using PowerShell

PowerShell 5.0 icon

In setting up Oracle’s Primavera P6 EPPM version 18.8, I discovered that users who connected to the client via Citrix were not picking up changes that were made to the default configuration file.

Normally, if that file is changed and is newer than the user’s own file, it will be overwritten with the default. In this case, users were not seeing the newer file, and when I looked, they often had no local profile on the Citrix server.

As it turned out, the user profiles were set up as roaming profiles that were deleted upon logoff. This wouldn’t necessarily be a problem, except that the their copy of the config file was always listed as newer than the default.

A workaround was to be logged into the server via RDP, and to have the user log in via Citrix. At that time, the config file could be manually copied, overwriting the user’s old file, and then (most importantly!) manually opening and saving the user’s file, so that it would remain in place in their roaming profile even after logoff.

This is clearly not a feasible practice in a production environment. However, an automated script that does this could solve this problem! Save the following as a .cmd file and make sure it is run prior to running the P6 client executable.

copy "C:\Program Files\Oracle\Primavera P6\P6 Professional\18.8.0\Data\PrmBootStrapV2.xml" "C:\Users\%username%\AppData\Roaming\Oracle\Primavera P6\P6 Professional\18.8.0" /y

powershell (Get-ChildItem 'C:\Users\%username%\AppData\Roaming\Oracle\Primavera P6\P6 Professional\18.8.0\PrmBootStrapV2.xml').CreationTime = $(Get-Date)
powershell (Get-ChildItem 'C:\Users\%username%\AppData\Roaming\Oracle\Primavera P6\P6 Professional\18.8.0\PrmBootStrapV2.xml').LastAccessTime = $(Get-Date)
powershell (Get-ChildItem 'C:\Users\%username%\AppData\Roaming\Oracle\Primavera P6\P6 Professional\18.8.0\PrmBootStrapV2.xml').LastWritetime = $(Get-Date)

As long as the Citrix server has PowerShell installed, this should work.

Update: Part 2 has a script that will allow for both Local and Roaming profiles.

Adding Lines to the Beginning and Ending of Files Using PowerShell

Stack Overflow PowerShell question

In dealing with an application with which I had little familiarity, I discovered that troubleshooting an app (in this case developed using ColdFusion) where many of the source code files are “included” dynamically can be difficult – especially when JavaScript scripts are combined that have functions with identical names.

Because so many of the functions were not only identically named, but also similarly constructed, I decided to add commented identifiers to the beginning and ending of each JS file.

This could be done in a number of ways, but given my recent forays into using PowerShell scripts, I chose that route again.

Stack Overflow PowerShell question
Stack Overflow and Google – developers’ best friends.

After some Googling and a brief visit to Stack Overflow, I learned about the two PowerShell “cmdlets” that would be most useful here: Set-Content and Add-Content.

The text of the script is below. What this script does is recursively search through the file path in line 1, choosing only files that have the extension after the filter switch (.js in this case). Looping through these file names, each file is read into memory (using Get-Content). The root of the file is then removed with the first replace command, and for aesthetics, I chose to change backslashes into forward slashes with the second one (lines 4 and 5). Notice that backslashes must be escaped by using an extra backslash, whereas forward slashes are not escaped. Also, in case you’re wondering, the backtick-n (`n) is the newline character in PowerShell. The Set-Content cmdlet is used to add the “$newline” string and then the original file content. The Add-Content cmdlet is then used to add the line marking the end of the file.

Get-ChildItem "C:\Folder\Subfolder" -recurse -Filter *.js | `
    $content = Get-Content $_.FullName
    $fullname = $_.FullName -replace "C:\\Folder\\Subfolder", ""
    $fullname = $fullname -replace "\\", "/"

    $newline = "// file: " + $fullname + " `n"
    Set-Content $_.FullName -value $newline, $content
    $endline = "// end of file: " + $fullname + " `n"
    Add-Content $_.FullName $endline