diff --git a/src/modules/SdnDiag.Utilities.psm1 b/src/modules/SdnDiag.Utilities.psm1 index ccd93c17..64d4bdf0 100644 --- a/src/modules/SdnDiag.Utilities.psm1 +++ b/src/modules/SdnDiag.Utilities.psm1 @@ -515,7 +515,7 @@ function Copy-FileFromRemoteComputer { else { # try SMB Copy first and fallback to WinRM try { - Copy-FileFromRemoteComputerSMB -Path $Path -ComputerName $object -Destination $Destination -Force:($Force.IsPresent) -Recurse:($Recurse.IsPresent) -ErrorAction Stop + Copy-FileFromRemoteComputerSMB -Path $Path -ComputerName $object -Destination $Destination -Credential $Credential -Force:($Force.IsPresent) -Recurse:($Recurse.IsPresent) -ErrorAction Stop } catch { "{0}. Attempting to copy files using WinRM" -f $_ | Trace-Output -Level:Warning @@ -585,9 +585,6 @@ function Copy-FileFromRemoteComputerSMB { 'Force' = $Force.IsPresent 'Recurse' = $Recurse.IsPresent } - if ($Credential -ne [System.Management.Automation.PSCredential]::Empty -and $null -ne $Credential) { - $params.Add('Credential', $Credential) - } # set this to suppress the information status bar from being displayed $Global:ProgressPreference = 'SilentlyContinue' @@ -599,6 +596,17 @@ function Copy-FileFromRemoteComputerSMB { $msg = "Unable to establish TCP connection to {0}:445" -f $ComputerName throw New-Object System.Exception($msg) } + + # if credential is provided, create a PSDrive to the remote computer to authenticate the SMB session + [System.String]$psDriveName = $null + if ($Credential -ne [System.Management.Automation.PSCredential]::Empty -and $null -ne $Credential) { + $driveRoot = [System.IO.Path]::GetPathRoot($Path[0]).Replace(':','$') + $uncRoot = "\\{0}\{1}" -f $ComputerName, $driveRoot + $tempDriveName = "osPsDrive_{0}" -f [guid]::NewGuid().ToString() + $null = New-PSDrive -Name $tempDriveName -PSProvider FileSystem -Root $uncRoot -Credential $Credential -ErrorAction Stop + $psDriveName = $tempDriveName + "Mounted temporary PSDrive {0} to {1}" -f $psDriveName, $uncRoot | Trace-Output -Level:Information + } } process { @@ -630,6 +638,17 @@ function Copy-FileFromRemoteComputerSMB { } } } + + end { + if ($psDriveName) { + try { + Remove-PSDrive -Name $psDriveName -Force -ErrorAction Stop + } + catch { + "Unable to remove temporary PSDrive {0}. {1}" -f $psDriveName, $_.Exception.Message | Trace-Output -Level:Warning + } + } + } } @@ -749,7 +768,7 @@ function Copy-FileToRemoteComputer { else { # try SMB Copy first and fallback to WinRM try { - Copy-FileToRemoteComputerSMB -Path $Path -ComputerName $object -Destination $Destination -Force:($Force.IsPresent) -Recurse:($Recurse.IsPresent) -ErrorAction Stop + Copy-FileToRemoteComputerSMB -Path $Path -ComputerName $object -Destination $Destination -Credential $Credential -Force:($Force.IsPresent) -Recurse:($Recurse.IsPresent) -ErrorAction Stop } catch { "{0}. Attempting to copy files using WinRM" -f $_ | Trace-Output -Level:Warning @@ -822,9 +841,6 @@ function Copy-FileToRemoteComputerSMB { 'Force' = $Force.IsPresent 'Recurse' = $Recurse.IsPresent } - if ($Credential -ne [System.Management.Automation.PSCredential]::Empty -and $null -ne $Credential) { - $params.Add('Credential', $Credential) - } # set this to suppress the information status bar from being displayed $Global:ProgressPreference = 'SilentlyContinue' @@ -836,6 +852,17 @@ function Copy-FileToRemoteComputerSMB { throw New-Object System.Exception($msg) } + # if credential is provided, create a PSDrive to the remote computer to authenticate the SMB session + [System.String]$psDriveName = $null + if ($Credential -ne [System.Management.Automation.PSCredential]::Empty -and $null -ne $Credential) { + $driveRoot = [System.IO.Path]::GetPathRoot($Destination.FullName).Replace(':','$') + $uncRoot = "\\{0}\{1}" -f $ComputerName, $driveRoot + $tempDriveName = "osPsDrive_{0}" -f [guid]::NewGuid().ToString() + $null = New-PSDrive -Name $tempDriveName -PSProvider FileSystem -Root $uncRoot -Credential $Credential -ErrorAction Stop + $psDriveName = $tempDriveName + "Mounted temporary PSDrive {0} to {1}" -f $psDriveName, $uncRoot | Trace-Output -Level:Information + } + [System.IO.FileInfo]$remotePath = Convert-FileSystemPathToUNC -ComputerName $ComputerName -Path $Destination.FullName $params.Destination = $remotePath.FullName } @@ -862,6 +889,17 @@ function Copy-FileToRemoteComputerSMB { } } } + + end { + if ($psDriveName) { + try { + Remove-PSDrive -Name $psDriveName -Force -ErrorAction Stop + } + catch { + "Unable to remove temporary PSDrive {0}. {1}" -f $psDriveName, $_.Exception.Message | Trace-Output -Level:Warning + } + } + } } function Copy-FileToRemoteComputerWinRM {