An important limitation that users have to face when they works with Performace Point Service’s tool, Dashboard Designer, is that it only allow users to choose those Master Pages that are physically located in the site where we want to deploy the Dashboard. It’s the reason that users cannot see those master pages that they have created and deployed in the Master Page Gallery in root site (/_catalogs/masterpage). Only can see default.master, minimal.master and v4.master, which there are phisically in each sub-site.

How can we fix this? Well, we already know that master page that we want to use exists, but exists in a higher level, so we need to replicate that master page, in every subsite where we want to deploy our Dashboard. We could build some console application to solve this, but, since I am a big fan of Windows PowerShell, we are going to build a script that replicate the master page that we want from Master Page Gallery in root site, to each subsite of site collection.

 

param
(
		[string]$siteCollection = "http:url-of-site-collection",
		[string]$masterPageName = "nightandday.master"	
);

$count = 0;

Function UploadMasterPageRecursive([Microsoft.SharePoint.SPWeb]$currentWeb, [System.Array]$masterBin)
{
    try
    {
        if ($count -eq 0){Write-Host  -NoNewLine "(*) Uploading Master Page in" $currentWeb.Title"..."; }
        
        1.- Get the list "Master Page Gallery"
        $mpg = $currentWeb.Lists | Where-Object {$_.Title -eq "Master Page Gallery"};        
        
        #2.- Upload master page using the binary.
        $mpgFolder =  $mpg.RootFolder;
        $mpgFiles = $mpgFolder.Files;
        $docUrl = $currentWeb.Url + "/_catalogs/masterpage/" + $masterPageName;        
       
		#If the page already exists, we do nothing.
        if($mpg.ParentWeb.GetFile($docUrl).Exists -eq $false)
        {        
            $newFile = $mpgFiles.Add($docUrl, $masterBin, $false);
            
            #If is enabled the version control, we approved the new master pager
            if ($mpg.EnableModeration)
            {
                #MinorCheckIn=0, MajorCheckIn=1, OverwriteCheckIn=2
                $newFile.CheckIn("File copied from " + $masterPageName + "allocated in root Master Pager Gallery" , 1);
                #Approve file
                $newFile.Approve("File automatically approved after copying");
            }            
            
            Write-Host "OK!" -ForeGroundColor green;
        }
        else{Write-Host "already exists!" -ForeGroundColor red;}
    }
    catch [System.Management.Automation.ExtendedTypeSystemException]
	{
		Write-Host $_.Exception.ToString()
	}   
        
    #3.- We access the sites children recursively
    if ($currentWeb.Webs.Count -gt 0)
    {
        $count = $count+1;
        $currentWeb.Webs | ForEach-Object {
            for ($i=0; $i -lt $count; $i++){Write-Host "   " -NoNewLine;};			
			Write-Host "(*) Uploading Master Page in" $_.Name -NoNewLine "..."; 
            UploadMasterPageRecursive $_ $masterBin;            
        }
        $count = $count-1;    
    }    
}



if ($siteCollection -ne "" -And $xmlFile -ne "")
{   
    try
    {
		#0.- We get the site collection.     
        $oSite = Get-SPSite $siteCollection;
        $oRootWeb = $oSite.RootWeb;
		#1.- We get the list "Mater Page Gallery"
        $mpg = $oRootWeb.Lists | Where-Object {$_.Title -eq "Master Page Gallery"};
        
        #2.- We get the master page in question.
        $master = $mpg.Items | Where-Object {$_.Name -eq $masterPageName }
        
        #3.- We get the binary code.
        $masterBin = $master.File.OpenBinary();
        
        #4.- We call recursively the function that replicates the master page
		#passing as argument the binary code, and the site where to replicate.
        UploadMasterPageRecursive $oRootWeb $masterBin;
    
    }
    catch [System.Management.Automation.ExtendedTypeSystemException]
	{
		Write-Host $_.Exception.ToString()
	}
}
else{Write-Host "Error: Faltan parámetros.";}

 

First, we access to Master Page Gallery in root site, to get the binary of the master page that we want, using the method OpenBinary(). Then, recursively, we access to each subsite in site collection, and create a new item  in the local Master Page Gallery, using the previous binary. Easy, don’t you?

I hope you find it useful