Until I can figure out who to cross post between the Project Server PFE Team Blog and my own blog, I will double post.

My customer wanted to be able to provide his Portfolio Managers with read only access to all project sites in PWA.  Because an AD group for Portfolio Managers already exists, we can use that AD group in the script and add it to all project sites under PWA with Read Only permission.  Credit to Gerald Parish for helping me with the code.

As always, test this code in your test environment.

<#
#################
 Disclaimer
#################
 This software (or sample code or query) is not supported under any Microsoft standard support program or service.
 The software, sample code, or query is provided AS IS without warranty of any kind.
 Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose.
 The entire risk arising out of the use or performance of the software and documentation remains with you.
 In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the software be liable for any damages whatsoever
 (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss)
 arising out of the use of or inability to use the software or documentation, even if Microsoft has been advised of the possibility of such damages."
#>
Exit

<#
#################
Instructions
#################
Review the disclaimer above.  Remove or comment out the "Exit" in order to be able to run the script.
Go to the last line of this PowerShell script file. 
In that line, change the -site value to the PWA URL. 
Also, change the -newuser value to be the AD username or group that you want to provide Read Only permissions for.

For example,...
 AddReadOnlyUsers -site http://projects.contoso.com/pwa -newuser "contoso\Financial Applications Group"
becomes
 AddReadOnlyUsers -site http://projects.yourdomain.com/pwa -newuser "yourdomain\Financial Applications Group"

Run this entire script from the SharePoint 2010 Management Shell. 
The log file will be created in the same directory you run the .ps1 from.
#>


Function Local:AddReadOnlyUsers
{

[CmdletBinding()]
Param(
    [parameter(Mandatory=$true)][string]$Site,
    [parameter(Mandatory=$true)][string]$NewUser
 )

$global:Logfile = ".\" +[Datetime]::Now.ToString("MMddyyyy_hhmmss_tt") + "_User_log.txt"
try {Start-Transcript -Path $Logfile -ErrorAction Stop } Catch { $Error[0] }

$permLevel = "Read"
$SiteCollection = get-spsite $Site
$AllWebs = $SiteCollection.AllWebs
foreach ($webSite in $AllWebs) {
   Write-Host -NoNewline "($webSite.url) Adding $($NewUser)..."
   $oNewuser = $webSite.EnsureUser($NewUser)  
   if ($oNewuser -ne $null) {
      Write-Host -ForegroundColor Green "Complete"
      Write-Host -NoNewline "Granting $($permLevel) to $($NewUser)... "
      $roleDef = $webSite.RoleDefinitions[$permLevel]
      $RoleAss = New-Object Microsoft.SharePoint.SPRoleAssignment($oNewuser)
      $RoleAss.RoleDefinitionBindings.Add($roleDef)
      $webSite.RoleAssignments.Add($RoleAss)
      $webSite.Update()
      Write-Host "Complete"
   }
   else { Write-Host -ForegroundColor red "Error"; exit}
}

Stop-Transcript
}

AddReadOnlyUsers -site http://projects.contoso.com/pwa -newuser "contoso\Financial Applications Group"