用于失败处理和重试的 PowerShell 重试循环

PowerShell Retry Loop for fail handling and retry

我在将重试循环添加到 Powershell Sharepoint 下载脚本时遇到了一些困难,非常感谢您帮助我添加到下面的脚本中。

我想做的是; 如果成功,则完成。

如果第 1 次失败,请在 x 秒后重试(比如 5 分钟)

如果第二次失败,请发送电子邮件告知存在问题,然后完成。

Function Download-FilesFromSharePointSiteLibrary()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $LibraryName,
        [Parameter(Mandatory=$true)] [string] $TargetFolder
    )

    Try {
        # Credentials to Connect to SharePoint
        $Username = "Test.User@email.com"
        $Password = Get-Content "C:\SharePoint\SharePoint-Credentials.txt" | ConvertTo-SecureString
        $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $Password)

        # Login to SharePoint Client
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Credentials

        # Get Files from SharePoint Site Library
        $List = $Ctx.Web.Lists.GetByTitle($LibraryName)
        $Ctx.Load($List)
        $Ctx.ExecuteQuery()

        # Get Files from SharePoint Site Library Folder
        $Folder = $List.RootFolder
        $FilesColl = $Folder.Files
        $Ctx.Load($FilesColl)
        $Ctx.ExecuteQuery()

        Foreach($File in $FilesColl)
        {
            $TargetFile = $TargetFolder+$File.Name
            # Download File from SharePoint Library Folder
            $FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx,$File.ServerRelativeURL)
            $WriteStream = [System.IO.File]::Open($TargetFile,[System.IO.FileMode]::Create)
            $FileInfo.Stream.CopyTo($WriteStream)
            $WriteStream.Close()
            # Delete File from SharePoint Library Folder
            $File.DeleteObject()
            $Ctx.ExecuteQuery()
        }
        # Success - End Program
        Write-host -f Green "Success!" $_.Exception.Message
  }
    Catch {
        # Failure - Sleep for 5 Minutes
        Write-host -f Red "Failure!" $_.Exception.Message
        Send-MailMessage -From "no-reply@email.com" -To "Test.User@email.com" -Subject "Failure: SharePoint Connector" -Body "Failure occurred with SharePoint Connector on Server.`n`n$_" -Priority "High" -SMTPServer "smtp.email.com" -Port "25"
        Start-Sleep -Seconds 300
    }
}

# SharePoint Site Parameters and Target Directory
$SiteURL="https://site.sharepoint.com/sites/Test"
$LibraryName="Library"
$TargetFolder="C:\SharePoint\Files\"

# Run Program
Download-FilesFromSharePointSiteLibrary -SiteURL $SiteURL -LibraryName $LibraryName -TargetFolder $TargetFolder

有很多方法可以做到这一点,这里是一个使用递归的例子。我已将您的函数从其原始代码中剥离出来,只是为了向您展示逻辑是如何工作的。

  1. 向函数添加一个-Retries参数,将其默认值保留为2以供测试。此值可以稍后更改,也可以在调用函数时更改 -Retries X 如果稍后需要重试,可以使用
  2. 如果try块失败,从catch块中的计数器减1。
  3. 如果 $Retries 还不是 0 (-not $PSBoundParameters.Retries),使函数调用自身传递相同的参数。
  4. 如果$Retries已达到0,发送邮件并结束功能。
function Download-FilesFromSharePointSiteLibrary {
[cmdletbinding()]
param (
    [Parameter(Mandatory=$true)] [string] $SiteURL,
    [Parameter(Mandatory=$true)] [string] $LibraryName,
    [Parameter(Mandatory=$true)] [string] $TargetFolder,
    [Parameter()] [int] $Retries = 2 # Retries 2 times by Default
)

    Try {
        # Original code goes here
        throw # Remove this after Testing
    }
    Catch {
        Write-Warning "Script Failed retrying..."
        Start-Sleep -Seconds 2
        # Add new subtracted Value to `$PSBoundParameters`
        $PSBoundParameters['Retries'] = (--$Retries)
        
        if(-not $PSBoundParameters.Retries) {
            Write-Warning "We are out of retries, sending Email"
            # If we're out of retries
            # Send Mail logic goes here
            return
        }
        Download-FilesFromSharePointSiteLibrary @PSBoundParameters
    }
}

Download-FilesFromSharePointSiteLibrary -SiteURL hello -LibraryName world -TargetFolder something

无需过多修改您的代码,您可以在使用 $global: 变量再次调用自身之前增加它 运行 的次数。

# Description: Download All Files from SharePoint Site Library, then Delete files from SharePoint.
# --------------------------------------------------

Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

Function Download-FilesFromSharePointSiteLibrary
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $LibraryName,
        [Parameter(Mandatory=$true)] [string] $TargetFolder
    )
    Begin 
    {
        if (-not $global:retriedTimes) {
            $global:retriedTimes = 0
        }
        $removeRetry = { Remove-Variable -Name "retriedTimes" -Scope "Global" }
    }
    Process
    {
        Try {
            # Credentials to Connect to SharePoint
            $Username = "Test.User@email.com"
            $Password = Get-Content "C:\SharePoint\SharePoint-Credentials.txt" | ConvertTo-SecureString
            $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $Password)

            # Login to SharePoint Client
            $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
            $Ctx.Credentials = $Credentials

            # Get Files from SharePoint Site Library
            $List = $Ctx.Web.Lists.GetByTitle($LibraryName)
            $Ctx.Load($List)
            $Ctx.ExecuteQuery()

            # Get Files from SharePoint Site Library Folder
            $Folder = $List.RootFolder
            $FilesColl = $Folder.Files
            $Ctx.Load($FilesColl)
            $Ctx.ExecuteQuery()

            Foreach($File in $FilesColl)
            {
                $TargetFile = $TargetFolder+$File.Name
                # Download File from SharePoint Library Folder
                $FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx,$File.ServerRelativeURL)
                $WriteStream = [System.IO.File]::Open($TargetFile,[System.IO.FileMode]::Create)
                $FileInfo.Stream.CopyTo($WriteStream)
                $WriteStream.Close()
                # Delete File from SharePoint Library Folder
                $File.DeleteObject()
                $Ctx.ExecuteQuery()
            }
            # Success - End Program
            Write-host -f Green "Success!" $_.Exception.Message
            & $removeRetry
        }
        Catch {
            $global:retriedTimes += 1
            if ($global:retriedTimes -ge 2) {
                Send-MailMessage -From "no-reply@email.com" -To "Test.User@email.com" -Subject "Failure: SharePoint Connector" -Body "Failure occurred with SharePoint Connector on Server.`n`n$_" -Priority "High" -SMTPServer "smtp.email.com" -Port "25"
                & $removeRetry
                Break
            }
            # Failure - Sleep for 5 Minutes
            Write-host -f Red "Failure!" $_.Exception.Message
            Start-Sleep -Seconds 300
            Download-FilesFromSharePointSiteLibrary @PSBoundParameters
        }
    }
}

# SharePoint Site Parameters and Target Directory
$SiteURL="https://site.sharepoint.com/sites/Test"
$LibraryName="Library"
$TargetFolder="C:\SharePoint\Files\"

# Run Program
Download-FilesFromSharePointSiteLibrary -SiteURL $SiteURL -LibraryName $LibraryName -TargetFolder $TargetFolder
  • 添加了BeginProcess块来实现重试次数的全局变量。