我正在尝试使用PowerShell从sharepoint文档库中操作xml文件。不幸的是我无法打开它并将其转换为xml。 :(我在文档库中有相同的文件,本地硬盘驱动器。当我从硬盘驱动器打开它时一切都很好。当我从Sharepoint文档库打开它时,转换为xml失败,因为在开头的一个额外的字符我用二进制文件比较了$ 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
答案 0 :(得分:2)
我在回答自己。 :)
文件前面的字符是UTF8编码的字节顺序标记。我发现我可以直接从sharepoint流加载xml文件。这解决了这个问题。我的目标是在sharepoint库中为Reporting Services数据源添加连接字符串。 .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")
实际上我意识到上面的代码不起作用。要修改报告,我必须使用ReportServer Web服务。现在是工作代码:
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);
}
}