Public/Copy-RemoteItemLocally.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<#
 .Synopsis
  Copies a remote file/folder to a local destination

 .Description
  Utility function for copying remote files locally. It leverages windows net use to map a share folder and supports network credentials for mounting the share.

 .Parameter Source
  The path to the file/folder to copy. It could be a network share or a local file path.

 .Parameter Destination
  The path to the destination folder. This path should be local to the machine executing the script. If not specified the item(s) will be copy to the temp folder

 .Parameter SourceCredential
  Used if the source is a network share for authentication.

 .Parameter Directory
  Specifies if the source is a directory or a file

 .Example
   # Copy a remote file
   Copy-RemoteItemLocally "\\otherpc\sharedfolder\myfile.doc" "C:\Mydocs\" (Get-Credential)

   # Copy a remote directory
   Copy-RemoteItemLocally "\\otherpc\sharedfolder\subfolder" "C:\Mydocs\" (Get-Credential) -Directory
#>

function Copy-RemoteItemLocally(){
    [CmdletBinding(SupportsShouldProcess=$False)]
    Param (
        [Parameter(Mandatory=$true,position=0)]
        [String] $Source,
        
        [Parameter(Mandatory=$false,position=1)]
        [String] $Destination,
        
        [Parameter(Mandatory=$false,position=2)]
        [PSCredential] $SourceCredential,
        
        [switch] $Directory
    )
    [string] $RetDest = $Destination
    # Get temp file/folder if Destination is not providered
    if (!$Destination) {
        $RetDest = $env:TEMP
        if (!$Directory) {
            $RetDest = (Join-Path $RetDest -ChildPath (Split-Path -Path $Source -Leaf))
        }
    }
    
    # Check the flag for networkshare
    $networkShare = $false
    try {
        if (($Source.StartsWith("\\")) -and (!(Test-Path $Source -ErrorAction SilentlyContinue))) {
            $networkShare = $true
        }
    } catch [System.UnauthorizedAccessException] {
        $networkShare = $true
    }
    
    if (!$networkShare) {
        Write-Verbose "File already accessible locally, returning existing source path"
        $RetDest = $Source
    } else {
        # Go parent directory path for file copy
        $sourceDir = $Source
        $destinationDir = $RetDest
        if(!$Directory){
            $sourceDir = (Split-Path($Source))
            $destinationDir = (Split-Path($destinationDir))
        }
        
        # Mapping networkshare drive
        if($networkShare){
            Write-Verbose "Network Share detected, need to map"
            Use-NetworkShare -SharePath $sourceDir -SharePathCredential $SourceCredential -Ensure "Present" | Out-Null
        }
        
        try {
            if (!$Directory) {
                Write-Verbose ("Copy File $Source $RetDest")
                if(!(Test-Path($destinationDir))){
                    New-Item -ItemType Directory -Force -Path $destinationDir | Out-Null
                }
                Copy-Item $Source $RetDest -Force | Out-Null
            } else {
                Write-Verbose ("Copy Directory $Source $RetDest")
                if (!(Test-Path($destinationDir))) {
                    New-Item -ItemType Directory -Force -Path $destinationDir | Out-Null
                }
                Get-ChildItem $sourceDir | ForEach-Object {
                    Copy-Item -Path $_.FullName -Destination  $destinationDir -Force -Container -Recurse | Out-Null
                }
            }
        } catch {
            $ErrorMessage = $_.Exception.Message
            Write-Error "An error occurred while copying files: $Source to $RetDest \n Error Message: $ErrorMessage"
        } finally {
            if ($networkShare) {
                try {
                    Use-NetworkShare -SharePath $sourceDir -SharePathCredential $SourceCredential -Ensure "Absent" | Out-Null
                } catch {
                    Write-Warning "Unable to disconnect share: $Source"
                }
            }
        }
    }
    
    
    return $RetDest
}