【问题标题】:With PowerShell and ReportingService2010, how to change empty shared datasource or custom datasource to shared datasource?使用 PowerShell 和 ReportingService2010,如何将空的共享数据源或自定义数据源更改为共享数据源?
【发布时间】:2020-11-13 08:51:12
【问题描述】:

我在这里陷入了僵局。我开始使用 PowerShell 编写脚本来处理将共享数据源设置为文件夹的所有报告。

我的逻辑: 对于文件夹中的每个报告和报告的每个数据源:

如果数据源名称与要替换的名称匹配 1:如果它的引用已经设置:用共享的替换它 2:如果它是自定义数据源:将其替换为共享数据源 3:如果它的引用为空:用共享的替换它

案例 1 完美运行,而案例 2 和案例 3 失败。我不明白为什么在第一种情况下它接受单个元素,而在另一种情况下,它没有告诉我它需要一个数组:

Impossible de convertir l'argument «DataSources» (valeur «SSRS.ReportingService2010.DataSource») de «SetItemDataSources
» en type «SSRS.ReportingService2010.DataSource[]»: «Impossible de convertir la valeur «
SSRS.ReportingService2010.DataSource» du type «SSRS.ReportingService2010.DataSource» en type «
SSRS.ReportingService2010.DataSource[]».»
Au caractère Ligne:87 : 1
+ $proxy.SetItemDataSources($ssrsItem.Path, $newDataSource);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

这是我想出的全部代码(它很冗长,但我认为它有助于提高可读性):

# Usage : SetConnection "msbireports" "/2134_DELIVRI/Test/PS1" "EDUCFI_SSAS" "/2134_DELIVRI/Test/PS1/Datasources/EDUCFI_SSAS.rds" true
function SetConnection(
    $reportServerName = $(throw "reportServerName is required."),
    $serverPath = $(throw "serverPath is required."),
    $connectionName = $(throw "connectionName is required."),
    $toConnection = $(throw "toConnection is required."),
    $replaceCustom = $(throw "replaceCustom is required.")
    )
{
    Write-Host "> Connecting to $reportServerName" -ForegroundColor Yellow
    $reportServerUri = "https://{0}/ReportServer/ReportService2010.asmx" -f $reportServerName
    $proxy = New-WebServiceProxy -Uri $reportServerUri -Namespace SSRS.ReportingService2010 -UseDefaultCredential
    Write-Host "  Done !" -ForegroundColor Yellow
    Write-Host ""
    
    # List everything on the Report Server, not recursively, but filter to keep Reports
    Write-Host "> Getting Items from $serverPath"
    $items = $proxy.ListChildren($serverPath, $false) | Where-Object {$_.TypeName -eq "Report"}
    
    Write-Host "Found $($items.Length) reports..."
    Write-Host ""
    # Loop through reports and data sources
    Foreach($ssrsItem in $items)
    {
        # Handling report.rdl...
        Write-Host "> Handling $($ssrsItem.Path).rdl"
        
        # Get Datasources having the wanted name
        $dsItems = $proxy.GetItemDataSources($ssrsItem.Path)
        $dsTarget = $proxy.GetItemDataSources($ssrsItem.Path) | Where-Object {$_.Name -eq $connectionName}
        if ($dsTarget.Length -eq 0)
        {
            Write-Host ">> Skipped : no DataSource named $connectionName" -ForegroundColor Gray
            Write-Host ""
        }
        else
        {
            Foreach($dsItem in $dsItems)
            {
                if ($dsItem.Name -eq $connectionName)
                {
                    # Check if the object has a reference or not (i.e. : its filled shared datasource or not : custom dataset OR empty filled shared datasource)
                    if($dsItem.Item.PSObject.Properties.Match('Reference').Count)
                    {
                        # Does the shared Datasource already points to the good one ?
                        if ($dsItem.Item.Reference -eq $toConnection)
                        {
                            Write-Host ">> Nothing done : $connectionName already set up as $toConnection" -ForegroundColor Gray
                            Write-Host ""
                        }
                        else
                        {
                            # Shared Datasource with an already filled Shared Datasource which points diffrently : change it.
                            Write-Host ">> Changing $connectionName from $($dsItem.Item.Reference) to $toConnection..." -ForegroundColor Gray
                            $dsItem.Item.Reference = $toConnection;
                            $proxy.SetItemDataSources($ssrsItem.Path, $dsItem);
                            Write-Host "  Done!" -ForegroundColor Green
                            Write-Host ""
                        }
                    }
                    else
                    {
                        # Two cases here : 1. Custom Datasource or 2. SharedDatasource but empty or 
                        # Check for Custom Datasource (has a property called Enabled which ShareDatasource has not)
                        if($dsItem.Item.PSObject.Properties.Match('Enabled').Count)
                        {
                            if ($replaceCustom -eq "replace")
                            {
                                Write-Host ">> Changing Custom Connection $connectionName to a Shared one pointing to $toConnection..." -ForegroundColor Gray

                                $newDataSource = New-Object("SSRS.ReportingService2010.DataSource")
                                $newDataSource.Name = $connectionName
                                $newDataSource.Item = New-Object ("SSRS.ReportingService2010.DataSourceReference")
                                $newDataSource.Item.Reference = $toConnection
                                
                                $proxy.SetItemDataSources($ssrsItem.Path, $newDataSource);

                                Write-Host "  DOES NOT WORK !" -ForegroundColor RED
                                Write-Host ""
                            }
                            else
                            {
                                Write-Host ">> Nothing done : $connectionName set up as a Custom Connection, but was told not to change it" -ForegroundColor Gray
                                Write-Host ""
                            }
                        }
                        else
                        {
                            Write-Host ">> OF TYPE SHARED... But not really ???"
                            $newDataSource = New-Object("SSRS.ReportingService2010.DataSource")
                            $newDataSource.Name = $connectionName
                            $newDataSource.Item = New-Object ("SSRS.ReportingService2010.DataSourceReference")
                            $newDataSource.Item.Reference = $toConnection

                            $proxy.SetItemDataSources($ssrsItem.Path, $newDataSource);
                            Write-Host "  DOES NOT WORK !" -ForegroundColor RED
                            Write-Host ""
                        }
                    }
                }
            }
        }
    }
}

SetConnection "msbireports" "/2134_DELIVRI/Test/PS1" "EDUCFI_SSAS" "/1446_EDUCFI/Datasources/EDUCFI_SSAS" "replace"

这让我发疯了。我也尝试以不同的方式执行此操作,即构建一个 DataSources 数组,并在报告处理结束时将其推送到 SetItemDataSources 但每次这两种情况都失败了,出现一个奇怪的错误,告诉我它无法转换一个数据源到..一个数据源。 (?!)

我的理智恳求您的帮助!

【问题讨论】:

    标签: reporting-services ssrs-2016


    【解决方案1】:

    好吧,在玩了一点代码之后,我改变了我的方法并构建了一个包含已经有效数据源和新数据源的数组,并在最后更改它们。这应该会更好,但我仍然有这个奇怪的转换错误......

    这是新代码:

    function SetConnection(
        $reportServerName = $(throw "reportServerName is required."),
        $serverPath = $(throw "serverPath is required."),
        $connectionName = $(throw "connectionName is required."),
        $toConnection = $(throw "toConnection is required."),
        $replaceCustom = $(throw "replaceCustom is required.")
        )
    {
        Write-Host "> Connecting to $reportServerName" -ForegroundColor Yellow
        $reportServerUri = "https://{0}/ReportServer/ReportService2010.asmx" -f $reportServerName
        $proxy = New-WebServiceProxy -Uri $reportServerUri -Namespace SSRS.ReportingService2010 -UseDefaultCredential
        Write-Host "  Done !" -ForegroundColor Yellow
        Write-Host ""
        
        # List everything on the Report Server, not recursively, but filter to keep Reports
        Write-Host "> Getting Items from $serverPath"
        $items = $proxy.ListChildren($serverPath, $false) | Where-Object {$_.TypeName -eq "Report"}
        
        Write-Host "Found $($items.Length) reports..."
        Write-Host ""
        # Loop through reports and data sources
        Foreach($ssrsItem in $items)
        {
            # Handling report.rdl...
            Write-Host "> Handling $($ssrsItem.Path).rdl"
            
            # Get Datasources having the wanted name
            $dsItems = $proxy.GetItemDataSources($ssrsItem.Path)
            $dsUpdated = @()
            $dsTarget = $proxy.GetItemDataSources($ssrsItem.Path) | Where-Object {$_.Name -eq $connectionName}
            if ($dsTarget.Length -eq 0)
            {
                Write-Host ">> Skipped : no DataSource named $connectionName" -ForegroundColor Gray
                Write-Host ""
            }
            else
            {
                Foreach($dsItem in $dsItems)
                {
                    if ($dsItem.Name -ne $connectionName)
                    {
                         $dsUpdated += $dsItem;
                    }
                    else
                    {
                        # Check if the object has a reference or not (i.e. : its filled shared datasource or not : custom dataset OR empty filled shared datasource)
                        if($dsItem.Item.PSObject.Properties.Match('Reference').Count)
                        {
                            # Does the shared Datasource already points to the good one ?
                            if ($dsItem.Item.Reference -eq $toConnection)
                            {
                                Write-Host ">> Nothing done : $connectionName already set up as $toConnection" -ForegroundColor Gray
                                Write-Host ""
                                $dsUpdated += $dsItem;
                            }
                            else
                            {
                                # Shared Datasource with an already filled Shared Datasource which points diffrently : change it.
                                Write-Host ">> Changing $connectionName from $($dsItem.Item.Reference) to $toConnection..." -ForegroundColor Gray
                                Write-Host ""
                                $dsItem.Item.Reference = $toConnection;                 
                                $dsUpdated += $dsItem;
                            }
                        }
                        else
                        {
                            # Two cases here : 1. Custom Datasource or 2. SharedDatasource but empty or 
                            # Check for Custom Datasource (has a property called Enabled which ShareDatasource has not)
                            if($dsItem.Item.PSObject.Properties.Match('Enabled').Count)
                            {
                                if ($replaceCustom -eq "replace")
                                {
                                    Write-Host ">> Changing Custom Connection $connectionName to a Shared one pointing to $toConnection..." -ForegroundColor Gray
                                    Write-Host ""
                                    $newDataSource = New-Object("SSRS.ReportingService2010.DataSource")
                                    $newDataSource.Name = $connectionName
                                    $newDataSource.Item = New-Object ("SSRS.ReportingService2010.DataSourceReference")
                                    $newDataSource.Item.Reference = $toConnection
                                    $dsUpdated += $newDataSource;
                                }
                                else
                                {
                                    Write-Host ">> Nothing done : $connectionName set up as a Custom Connection, but was told not to change it" -ForegroundColor Gray
                                    Write-Host ""
                                    $dsUpdated += $dsItem;
                                }
                            }
                            else
                            {
                                Write-Host ">> OF TYPE SHARED... But not really ???"
                                Write-Host ""
                                $newDataSource = New-Object("SSRS.ReportingService2010.DataSource")
                                $newDataSource.Name = $connectionName
                                $newDataSource.Item = New-Object ("SSRS.ReportingService2010.DataSourceReference")
                                $newDataSource.Item.Reference = $toConnection
                                $dsUpdated += $newDataSource;
                            }
                        }
                    }
                }
                
                $proxy.SetItemDataSources($ssrsItem.Path, $dsUpdated);  
                
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      • 2013-05-12
      • 2011-06-19
      • 1970-01-01
      相关资源
      最近更新 更多