DSCResources/ArcGIS_RemoteFile/ArcGIS_RemoteFile.psm1
function Download-File($url, $targetFile) { try { Start-BitsTransfer -Source $url -Destination $targetFile } catch { # Exception could happen if the bits service is not running $uri = New-Object "System.Uri" "$url" $request = [System.Net.HttpWebRequest]::Create($uri) $request.set_Timeout(15000) #15 second timeout $response = $request.GetResponse() if(-not ($responseContentLength -lt 1024)) { $totalLength = [System.Math]::Floor($response.get_ContentLength()/1024) } else { $totalLength = [System.Math]::Floor(1024/1024) } $responseStream = $response.GetResponseStream() $targetStream = New-Object -TypeName System.IO.FileStream -ArgumentList $targetFile, Create $buffer = new-object byte[] 10KB $count = $responseStream.Read($buffer,0,$buffer.length) $downloadedBytes = $count while ($count -gt 0) { $targetStream.Write($buffer, 0, $count) $count = $responseStream.Read($buffer,0,$buffer.length) $downloadedBytes = $downloadedBytes + $count } #Write-Progress -activity "Finished downloading file '$($url.split('/') | Select -Last 1)'" $targetStream.Flush() $targetStream.Close() $targetStream.Dispose() $responseStream.Dispose() } } function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $true)] [System.String] $Url ) $returnValue = @{ Url = $Url } $returnValue } function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.String] $Url, [System.String] $DestinationPath, [Parameter(Mandatory=$true)] [System.Boolean] $UseAzureFiles, [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $AFSCredential, [Parameter(Mandatory=$false)] [System.String] $AFSEndpoint, [System.Boolean] $Force, [ValidateSet("Present","Absent")] [System.String] $Ensure ) if(-not($DestinationPath)) { throw 'Destination Path not provided' } if($Ensure -ieq 'Present') { $DestinationFolder = Split-Path $DestinationPath -Parent if(-not(Test-Path $DestinationFolder)){ Write-Verbose "Creating Directory $DestinationFolder" New-Item $DestinationFolder -ItemType directory } if($url.StartsWith('http', [System.StringComparison]::InvariantCultureIgnoreCase)) { Write-Verbose "Downloading file $url to $DestinationPath" Download-File -url $url -targetFile $DestinationPath }else { if($UseAzureFiles){ $AvailableDriveLetter = AvailableDriveLetter New-PSDrive -Name $AvailableDriveLetter -PSProvider FileSystem -Root $AFSEndpoint -Credential $AFSCredential -Persist $FileSharePath = "$($AvailableDriveLetter):\\$($url)" Write-Verbose "Copying file $FileSharePath to $DestinationPath" Copy-Item -Path $FileSharePath -Destination $DestinationPath -Force Remove-PSDrive -Name $AvailableDriveLetter }else{ Write-Verbose "Copying file $url to $DestinationPath" Copy-Item -Path $url -Destination $DestinationPath -Force } } } elseif($Ensure -ieq 'Absent') { if($DestinationPath -and (Test-Path $DestinationPath)) { Remove-Item -Path $DestinationPath -Force:$Force } } } function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] [System.String] $Url, [System.String] $DestinationPath, [Parameter(Mandatory=$true)] [System.Boolean] $UseAzureFiles, [Parameter(Mandatory=$False)] [System.Management.Automation.PSCredential] $AFSCredential, [Parameter(Mandatory=$false)] [System.String] $AFSEndpoint, [System.Boolean] $Force, [ValidateSet("Present","Absent")] [System.String] $Ensure ) $result = $false if($DestinationPath -and (Test-Path $DestinationPath)) { $result = $true } if($Ensure -ieq 'Present') { if($result) { if($url.StartsWith('http', [System.StringComparison]::InvariantCultureIgnoreCase)) { # File Exists locally. Check the remote location Write-Verbose 'File Exists locally. Check if the remote URL has Changed using Last-Modified Header' $HasRemoteFileChanged = $true $response = $null try { $response = Invoke-WebRequest -Uri $Url -UseBasicParsing -UseDefaultCredentials -TimeoutSec 15 -Method Head -ErrorAction Ignore } catch{ $HasRemoteFileChanged = $false } if($response) { [DateTime]$RemoteFileLastModTime = $response.Headers['Last-Modified'] if($RemoteFileLastModTime -le (Get-Item -Path $DestinationPath).CreationTime) { $HasRemoteFileChanged = $false } } if($HasRemoteFileChanged) { # File has changed - needs to be downloaded again $result = $false } } else { if(-not($UseAzureFiles)){ if((Get-Item -Path $Url).LastWriteTime -gt (Get-Item -Path $DestinationPath).CreationTime) { # File has changed - needs to be copied again $result = $false } }else{ $result = $false } } } $result } elseif($Ensure -ieq 'Absent') { (-not($result)) } } Function AvailableDriveLetter () { param ([char]$ExcludedLetter) $Letter = [int][char]'C' $i = @() #getting all the used Drive letters reported by the Operating System $(Get-PSDrive -PSProvider filesystem) | %{$i += $_.name} #Adding the excluded letter $i+=$ExcludedLetter while($i -contains $([char]$Letter)){$Letter++} Return $([char]$Letter) } Export-ModuleMember -Function *-TargetResource |