PowerShell SharePoint Online ExecuteQuery错误 - 超时

时间:2017-07-27 07:23:43

标签: sharepoint sharepoint-online csom

这个让我困惑了好几天......它的工作时间超过了一半,但是在调用ExecuteQuery()命令时经常会给我这个错误:

  

使用“0”参数调用“ExecuteQuery”的异常:“操作已超时”

PowerShell:

$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($webURL) 
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Credentials.UserName,$Credentials.Password) 

$web = $ctx.Web  
$ctx.Load($web) 

#Retrieve Library
$list = $ctx.Web.Lists.GetByTitle($ITPurchaseRequestListName)
$ctx.load($list)

$files = $list.rootFolder.files
$ctx.load($files)
$ctx.executeQuery()

##########
if((test-path $tempPath) -eq $False)
{
    new-item -itemtype directory -path $temppath
}

foreach($file in $files)
{
    $ctx.load($file)
    $ctx.executeQuery()

    $fileRef = $file.ServerRelativeURL
    $fileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($ctx, $fileRef);

    $fileName = $tempPath + $file.Name
    $fileStream = [System.IO.File]::Create($fileName)
    $fileInfo.Stream.CopyTo($fileStream);

    $fileStream.Close()

    start-sleep -seconds 2
}

如果我终止控制台会话并启动一个新的PowerShell窗口,它将运行几次运行,然后再次进行调用。有什么想法吗?

5 个答案:

答案 0 :(得分:1)

我认为使用foreach语句调用executeQuery()对性能不利。 最好使用" Include"在foreach语句之外加载文件对象的属性。

参考网址

https://msdn.microsoft.com/en-US/library/office/ee539350(v=office.14).aspx#Anchor_5

答案 1 :(得分:1)

除了其他评论和建议之外,6sc.com的人们还能够帮助我确定根本原因,即for循环中缺少stream.close()。

foreach($file in $results)
{

    $fileRef = $file["FileRef"];
    $fileName = $tempPath + $file["FileLeafRef"];

    $fileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($ctx, $fileRef);
    $fileStream = [System.IO.File]::Create($fileName);
    $fileInfo.Stream.CopyTo($fileStream);

    $fileStream.Close();
    $fileInfo.Stream.Close();
}

答案 2 :(得分:0)

将一个TRY..CATCH块添加到PowerShell脚本中,它将处理服务器超时,这将提供连续性执行。

TRY ... CATCH的另一个好处是,您将能够获得异常的详细信息,并且可以在单独的日志文件中捕获,为您提供有关该问题的其他线索。现在很难做出有根据的猜测,文件句柄可能正在使用,服务器I / O,文件可能在独占模式下打开,连接可能已经被打破了很短的时间,很难说。

使用TRY..CATCH捕获日期和时间+异常的详细信息将帮助您打开Windows事件查看器并准确了解发生的情况。

答案 3 :(得分:0)

我宁愿使用.OpenBinaryStream(),将其下载到内存中,然后保存到光盘。

代码:

foreach($file in $files)
{
    $data = $file.OpenBinaryStream();
    $ctx.Load($file);
    $ctx.ExecuteQuery();

    $memory = new-object system.io.MemoryStream
    $buffer = new-object system.byte[](1024*64)
    $pos = 0;
    while (($pos = $data.Value.Read($buffer, 0, $buffer.Length)) -gt 0)
    {
        $memory.Write($buffer, 0, $pos);
    }
    $memory.Seek(0, [System.IO.SeekOrigin]::Begin);   

    $fileStream = [System.IO.File]::Create($fileName)
    $memory.CopyTo($fileStream)
    $memory.Close()
    $fileStream.Close()
}

答案 4 :(得分:-1)

包括将$fileInfo.Stream.Close();用于魔术。