DSCResources/xDownloadFile/xDownloadFile.psm1

function Get-TargetResource {
    [CmdletBinding()]
    [OutputType([System.Collections.Hashtable])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $SourcePath,
        
        [parameter(Mandatory = $true)]
        [System.String]
        $FileName,

        [parameter(Mandatory = $true)]
        [System.String]
        $DestinationDirectoryPath,

        [parameter()]
        [System.Management.Automation.PSCredential]
        $Credential,

        [parameter()]
        [System.String]
        [ValidateSet("Basic", "Digest", "Negotiate", "NTLM", "Passport")]
        $Authentication
    )
    $returnValue = @{
        SourcePath               = $SourcePath
        FileName                 = $FileName
        DestinationDirectoryPath = $DestinationDirectoryPath
    }
    $returnValue
}

function Set-TargetResource {
    [CmdletBinding()]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $SourcePath,
        
        [parameter(Mandatory = $true)]
        [System.String]
        $FileName,

        [parameter(Mandatory = $true)]
        [System.String]
        $DestinationDirectoryPath,

        [parameter()]
        [System.Management.Automation.PSCredential]
        $Credential,

        [parameter()]
        [System.String]
        [ValidateSet("Basic", "Digest", "Negotiate", "NTLM", "Passport")]
        $Authentication
    )

    Write-Verbose "Create Destination Directory"
    if (!(Test-Path $DestinationDirectoryPath)) {
        New-Item -Path $DestinationDirectoryPath -ItemType Directory -Force
    }

    $output = Join-Path $DestinationDirectoryPath $FileName
    $startTime = [System.DateTimeOffset]::Now
    Write-Verbose "Start to download file from $SourcePath"

    try {
        Get-BitsTransfer -ErrorAction Stop | Remove-BitsTransfer -ErrorAction Stop

        if ($null -ne $Credential -and -not [System.String]::IsNullOrEmpty($Authentication)) {
            $downloadJob = Start-BitsTransfer -Source $SourcePath `
                -Destination $output `
                -DisplayName "Download" `
                -Asynchronous `
                -RetryInterval 60 `
                -Priority Foreground `
                -Credential $Credential `
                -Authentication $Authentication
        }
        else {
            $downloadJob = Start-BitsTransfer -Source $SourcePath `
                -Destination $output `
                -DisplayName "Download" `
                -Asynchronous `
                -RetryInterval 60 `
                -Priority Foreground
        }

        while (-not ((Get-BitsTransfer -JobId $downloadJob.JobId).JobState -eq "Transferred")) {
            Start-Sleep -Seconds (20)
            Write-Verbose -Verbose -Message ("Waiting for $SourcePath, time taken: {0}" -f ([System.DateTimeOffset]::Now - $startTime).ToString())
            Write-Verbose -Message ($downloadJob | Format-List | Out-String)
        }
        Complete-BitsTransfer -BitsJob $downloadJob
    }
    catch {
        $wc = New-Object System.Net.WebClient
        [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
        if ($null -ne $Credential) {
            $wc.Credentials = $Credential
        }
        $wc.DownloadFile($SourcePath, $output)
        $wc.Dispose()
    }
    Write-Verbose "Complete download file from $SourcePath"
}


function Test-TargetResource {
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    param
    (
        [parameter(Mandatory = $true)]
        [System.String]
        $SourcePath,
        
        [parameter(Mandatory = $true)]
        [System.String]
        $FileName,

        [parameter(Mandatory = $true)]
        [System.String]
        $DestinationDirectoryPath,

        [parameter()]
        [System.Management.Automation.PSCredential]
        $Credential,

        [parameter()]
        [System.String]
        [ValidateSet("Basic", "Digest", "Negotiate", "NTLM", "Passport")]
        $Authentication
    )
    $output = Join-Path $DestinationDirectoryPath $FileName
    Test-Path $output
}


Export-ModuleMember -Function *-TargetResource