SSRS bulk permission update 2008R2 to 2014

powershellssrs-2008-r2ssrs-2014

I'm moving SSRS reports from a 2008R2 server to a 2014 server. I've moved all the RDLs with a 3rd party tool only to find none of the permissions exist on the target. I'm attempting to copy the permissions over with Powershell but the script errors when attempting to set the policy with .SetPolicies. The object members appear to be incompatible between 2008 R2 and 2014. Is it possible to move the perms from 2008R2 to 2014 via Powershell?

$ReportServerUriSource = 
'http://my2008Source/ReportServer/ReportService2010.asmx?wsdl'
$ReportServerUriTarget = 
'http://my2014target/ReportServer/ReportService2010.asmx?wsdl'
$InheritParent = $true


 $rsProxy =       New-WebServiceProxy -Uri $ReportServerUriSource -
 UseDefaultCredential
$rsProxyTarget = New-WebServiceProxy -Uri $ReportServerUriTarget -
UseDefaultCredential


$SourceItems = $rsProxy.ListChildren("/MyReports", $true) | `
     SELECT TypeName, Path, ID, Name 

$targetFolder = $rsProxyTarget.GetPolicies($SourceItem.Path,
  [ref]$InheritParent)     

foreach($SourceItem in $SourceItems)
{
$Policies = $rsProxy.GetPolicies($SourceItem.Path, [ref]$InheritParent)

  if($InheritParent -eq $false)
 {
        $Policy = $rsProxy.GetPolicies($SourceItem.Path, 
[ref]$InheritParent)
        $rsProxyTargetPath = $rsProxyTarget.GetPolicies($SourceItem.Path,
[ref]$InheritParent) 
        if($rsProxyTargetPath)
        {
          $rsProxyTarget.SetPolicies($SourceItem.Path, $Policy)

           }

     }

}

Error:

Cannot convert argument "Policies", with value: "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1er_ReportService2010_asmx_wsdl.Policy[]", 
for "SetPolicies" to type "Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3er_ReportService2010_asmx_wsdl.Policy[]": "Cannot convert the 
"Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1er_ReportService2010_asmx_wsdl.Policy" value of type 
"Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1er_ReportService2010_asmx_wsdl.Policy" to type 
"Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy3er_ReportService2010_asmx_wsdl.Policy"."
At line:21 char:15
+               $rsProxyTarget.SetPolicies($SourceItem.Path, $Policy)
+               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

Best Answer

I was able to hack together a solution from a few different blogs-

function Add-SSRSItemSecurity
(
    [Parameter(Position=0,Mandatory=$true)]
    [Alias("url")]
    [string]$webServiceUrl,

    [Parameter(Position=1,Mandatory=$true)]
    [Alias("path")]
    [string]$itemPath,

    [Parameter(Position=2,Mandatory=$true)]
    [Alias("u")]
    [string]$groupUserName,

    [Parameter(Position=3,Mandatory=$true)]
    [Alias("r")]
    [string]$role,

    [Parameter(Position=2)]
    [bool]$inherit=$true
)

{

    #Fix item path if not starting with /
    if(!$itemPath.StartsWith("/")) { $itemPath = "/" + $itemPath}

    #Create Proxy
    Write-Host "[Add-SSRSItemSecurity()] Creating Proxy, connecting to : $webServiceUrl"
    $ssrsProxy = New-WebServiceProxy -Uri $webServiceUrl -UseDefaultCredential

    $type = $ssrsProxy.GetType().Namespace;
    $policyType = "{0}.Policy" -f $type;
    $roleType = "{0}.Role" -f $type;

    Write-Host "[Add-SSRSItemSecurity()] Retrieving all existing policies."
    $policies = $ssrsProxy.GetPolicies($itemPath, [ref]$inherit);

    $a = 1;
    foreach($policy in $policies)
    {

        foreach($r in $policy.Roles)
        {
            $msg = "[Add-SSRSItemSecurity()]  Existing Policy # {0} Group Name: {1}, Role: {2}" -f $a, $policy.GroupUserName, $r.Name
            Write-Host $msg
        }
        $a+=1;
    }

    $msg = "[Add-SSRSItemSecurity()] Total Existing Policies: " + $policies.Length;
    Write-Host $msg

    $Policy = $policies | 
    Where-Object { $_.GroupUserName -eq $groupUserName } | 
    Select-Object -First 1

    if (-not $Policy) {
        $Policy = New-Object ($policyType)
        $Policy.GroupUserName = $GroupUserName
        $Policy.Roles = @()
        $Policies += $Policy
        $msg = "[Add-SSRSItemSecurity()] Adding new policy: '{0}'" -f $GroupUserName
        Write-Host $msg
    }

    $r = $Policy.Roles |
        Where-Object { $_.Name -eq $role } |
        Select-Object -First 1
    if (-not $r) {
        $r = New-Object ($roleType)
        $r.Name = $role
        $Policy.Roles += $r
        $msg = "[Add-SSRSItemSecurity()] Adding new role: '{0}'" -f $role
        Write-Host $msg
    }

    #Set the policies
    $ssrsProxy.SetPolicies($itemPath,$policies);

}

$ReportServerUriSource = 'http://server1/ReportServer/ReportService2010.asmx?wsdl'
$ReportServerUriTarget = 'http://server2/ReportServer/ReportService2010.asmx?wsdl'
$rsProxy =       New-WebServiceProxy -Uri $ReportServerUriSource -UseDefaultCredential
$SourceItems = $rsProxy.ListChildren("/", $true) | `
         SELECT TypeName, Path, ID, Name



 $targetFolder = $rsProxyTarget.GetPolicies($SourceItem.Path,[ref]$InheritParent)     
 foreach($SourceItem in $SourceItems)
 {
  $Policies = $rsProxy.GetPolicies($SourceItem.Path, [ref]$InheritParent)
      if($InheritParent -eq $false)
     {
 $x = $Policies.Count
 $y = 0
 while($y -lt $x)
 {
     $name = ($Policies[$y]).Roles[0].Name

     $z = ($Policies[$y]).Roles.Count
     $q = 0

 while($q -lt $z)
     {
  Add-SSRSItemSecurity -webServiceUrl $ReportServerUriTarget `
                     -itemPath $SourceItem.Path`
                     -groupUserName ($Policies[$y]).GroupUserName`
                     -role ($Policies[$y]).Roles[$q].Name
         $q++
  }

     $y++
 }
}
}