0

PowerShellを使用してSharePointドキュメントライブラリからxmlファイルを操作しようとしています。残念ながら、それを開いてxmlにキャストすることはできません。:(ドキュメントライブラリとローカルのハードドライブに同じファイルがあります。ハードドライブから開くと、すべて問題ありません。Sharepointドキュメントライブラリから開くと、先頭に余分な文字があるため、xmlへのキャストが失敗します。 file。$splistitem.File.OpenBinary()とget-content C:.... \ file.xmlの結果をバイナリで比較しました。問題は、バイトから文字列を取得することです。利用可能なすべてを試しました。エンコーディングが機能しませんでした。私のコードは次のとおりです。

   # Add SharePoint snapin if needed
    if ((Get-PSSnapin -Name Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue)     -eq $null)
    {
        Add-PSSnapin Microsoft.SharePoint.Powershell
    }

...
    $splistitem = ...
...

    $encode = New-Object System.Text.UTF8Encoding

    [xml]$xmlFromSharepoint = $encode.GetString($splistitem.File.OpenBinary()) #throws exception
    [xml]$xmlFromFile = get-content C:\....\file.xml #works fine

    $web.Dispose()

    Write-Host "Press any key to close ..."
    $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

スローされる例外は次のメッセージです。

        Cannot convert value "?<?xml version="1.0" encoding="utf-8"?> 
..." to type "System.Xml.XmlDocument". Error: "Data at the
    root level is invalid. Line 1, position 1."
    At C:\aaa.ps1:14 char:24
    + [xml]$xmlFromSharepoint <<<<  = $encode.GetString($splistitem.File.OpenBinary
    ())
        + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMet
       adataException
        + FullyQualifiedErrorId : RuntimeException
4

1 に答える 1

2

私は自分自身に答えています。:)

ファイルの前の文字は、UTF8エンコーディングのバイト順マークです。xmlファイルをSharePointストリームから直接ロードできることがわかりました。これは問題を解決します。私の目標は、SharePointライブラリのReportingServicesデータソースの接続文字列を変更することでした。.rsdsファイルは、接続文字列を保持する通常のxmlファイルです。これを変更するコードは次のとおりです。

# Add SharePoint snapin if needed
if ((Get-PSSnapin -Name Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue)     -eq $null)
{
    Add-PSSnapin Microsoft.SharePoint.Powershell
}

#Configure Connection strings
$web = Get-SPWeb "http://localhost/c1"
$reportsList = $web.Lists | Where-Object { $_.Title -eq "Reports" }
$dataSource = $reportsList.Items | Where-Object { $_.Name -eq "Datasource.rsds" }
$dataSource.File.CheckOut();
$xml = New-Object System.Xml.XmlDocument
$stream = $dataSource.File.OpenBinaryStream();
$xml.Load($stream)
$xml.DataSourceDefinition.ConnectString = "test"
$stream.Position = 0;
$stream.SetLength(0);
$xml.Save($stream);
$dataSource.File.SaveBinary($stream)
$dataSource.File.CheckIn("");
$web.Dispose()

Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

実際、上記のコードが機能しないことに気づきました。レポートを変更するには、ReportServerWebサービスを使用する必要があります。これが作業コードです。

function ConfigureConnectionString
{
param($webUrl, $connectionString)
    $reportServerURI = "http://$serverUrl/ReportServer"
    $ReportPathWildCard = "/";
    $NameSharedSchedule="NeverExpireCache";

    $reportServerURI2010 = "$reportServerURI/ReportService2010.asmx?WSDL"
    $RS = New-WebServiceProxy -Class 'RS' -NameSpace 'RS' -Uri $reportServerURI2010 -UseDefaultCredential
    $dataSources = $RS.ListChildren($ReportPathWildCard,$true) | Where-Object {$_.TypeName -eq "DataSource" -and $_.Path -like "*$webUrl*"}
    foreach($ds in $dataSources) {
        $dsDefinition = $RS.GetDataSourceContents($ds.Path)

        $dsDefinition.CredentialRetrieval = "Store"
        $dsDefinition.Enabled = "TRUE";
        $dsDefinition.UserName = "domain\user";
        $dsDefinition.Password = "Password";
        $dsDefinition.ConnectString = $connectionString;

        #Update the DataSource with this new content
        $RS.SetDataSourceContents($ds.Path, $dsDefinition);
    }
}
于 2012-11-16T10:52:11.777 に答える