SQL Agent作业失败,无法连接到远程服务器(Sharepoint)

SQL Agent Job fails with Unable to connect to the remote server (Sharepoint)


问题

我有一个PS1脚本,使用Microsoft.Online.SharePoint.PowerShell,从特定的Sharepoint库(Sharepoint Online)下载文件。
它在SQL服务器机器上通过SQL Server powershell成功运行,但在通过SQL Agent -> Powershell或cmdexec命令执行时失败,出现错误。调用参数为 "0 "的Exception "ExecuteQuery"。"

什么原因会导致这个错误,如何解决这个错误?

下面是PS1脚本写到日志的内容。
- 连接到SharePoint Online中的库时出错
- 调用参数为 "0 "的Exception "ExecuteQuery"。"无法连接到远程服务器"

以下是SQL Agent Job写入日志的内容。
在通过一个集合进行枚举时,发生了一个错误。该集合还没有被初始化。它还没有被请求,或者请求还没有被执行。它可能需要被明确请求。ps1:157 char:9 + $folder = $folders | Where {$_.Name -eq $FolderName} +

下面是这段脚本(同样,它在SQL Server powershell上运行良好,但通过SQL Agent Job运行时却失败了)。

 #Setup Credentials to connect
 $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
     
 Try
 {
     #Setup the context
     $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
     $Ctx.Credentials = $Credentials
          
     #Get the Library
     $List = $Ctx.Web.Lists.GetByTitle($LibraryName)
     $Ctx.Load($List)
     $folders = $List.RootFolder.Folders
     $Ctx.Load($folders)
     $Ctx.ExecuteQuery()
    
     Write-Log "Listed loaded."
 }
 Catch
 {
     Write-Log "Error connecting to library in SharePoint Online `n"
     Write-Log $_.Exception.Message
 }
    
 $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
    
 $Query.ViewXml= "@
 <View Scope='RecursiveAll'> 
 <Query>
    <Where>
       <Eq>
          <FieldRef Name='TaskStatus' />
          <Value Type='Text'>$TaskStatus</Value>
       </Eq>
    </Where>
 </Query>
 </View>"
    
 $count =0
 #Get List Items in Batches
 Do
 { 
     # $List.RootFolder.Folders[$FolderName]
    
     if ($FolderName -ne "")
     {
         $folder = $folders | Where {$_.Name -eq $FolderName}        
         $ctx.load($folder)
         $ctx.ExecuteQuery()
         $Query.FolderServerRelativeUrl = $folder.ServerRelativeUrl
     }
    
     $ListItems = $List.GetItems($Query)
     $Ctx.Load($ListItems)
     $Ctx.ExecuteQuery()
     $ListItems.Count
    
     #Update Postion of the ListItemCollectionPosition
     $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition
     $Query.ListItemCollectionPosition
       
     If ($ListItems.Count -eq 0) 
     {
     Write-Log "No items in library that meets CAML query condition `n" 
     Break
     }
    
     $downloadItemCount=1;
         
     #Extract the each list item from the List Items collection.
     ForEach($Item in $ListItems)
     {                  
             try
             {
    
                 $Ctx.Load($Item.File)
                 $Ctx.ExecuteQuery()  
    
                 $SourceFile=$Item.File.ServerRelativeUrl;
                 #$Folder_Name1 =  split-path $SourceFile  
                 #$Folder_Name1 =  split-path $Folder_Name1 -leaf;
                 #$TargetFile=$TargetFolder + "\"+$Folder_Name1+"\" + $Item.File.Name;
    
                 $TargetFile=$TargetFolder + "\" + $Item.File.Name;
                 If ($Action -ne "UpdateOnly")
                 {
                 FileDownLoadFromSPOnlineLibrary -SPOSiteURL $SiteURL -SourceFilePath $SourceFile -TargetFilePath $TargetFile 
    
                 $fileDownloadingMessage="Downloaded: "+$Item.File.Name; 
                 #Write-Host $fileDownloadingMessage -BackgroundColor DarkGreen
                 Write-Log $fileDownloadingMessage
                 }
    
                 $Item["TaskStatus"] = $UpdateStatus;
                 $Item[$DescriptionFieldname] = $UpdateDescription;
                 $Item.Update();
                 $Ctx.ExecuteQuery();
    
                 Write-Log "Set Task Status to Downloaded."
    
             $downloadItemCount++
    
             }
             catch
             { 
             $ErrorMessage = $_.Exception.Message +"in: " +$Item.File.Name
             Write-Host $ErrorMessage -BackgroundColor Red
             Write-Log $ErrorMessage 
             }
         }
     Break; #just do 1 item.    
    
 }While ($Query.ListItemCollectionPosition -ne $null)
答案1

你好,
SQL服务器中的PowerShell步骤是在SQLPS提供者的上下文中执行命令的。所以当你访问文件系统时,它没有任何线索。在 DBA.SE 上有一些问题显示了选项,但更简单的方法是直接使用cmdexec步骤并调用powershell.exe


I Hi
工作步骤实际上是作为cmdexec运行,并调用powershell,如。

powershell -Command "E:\ Data\ga\script\SPOnline.ps1"

该工作也是以Proxy的身份运行,这和代理账户有权限访问共享点库。

我还能够使用SQL Server powershell运行脚本并成功下载(这是SQLPS吗?provider?),但当我通过代理步骤调用脚本时就不行了:
那个代理账户还需要什么吗?

答案2

你好 ,

谢谢你的问题。

要配置SQL Server Agent
选择 "开始 "按钮,然后在 "开始 "菜单中,选择 "控制面板"。
在控制面板中,选择系统和安全,选择管理工具,然后选择本地安全策略。
在本地安全策略中,选择雪佛龙展开本地策略文件夹,然后选择用户权限分配文件夹。
右键单击你想配置的权限,以便与SQL Server一起使用,并选择属性。
在权限的属性对话框中,验证SQL Server Agent运行的账户是否被列出。如果没有,选择添加用户或组,在选择用户、计算机、服务账户或组对话框中输入SQL Server Agent运行的账户,然后选择确定。
对你想添加的每个权限都重复一遍,以便与SQL Server Agent一起运行。完成后,选择确定。


欲了解更多信息,请通过此链接。
https://docs.microsoft.com/en-us/sql/ssms/agent/configure-sql-server-agent?view=sql-server-ver15