2

I hope that this is a silly mistake and I am overlooking something really simple. I have a function to map a network drive and copy the contents of network drive to a destination. In the end, I return the destination path for re-use later. However, it seems to be returning different type of object for destination path. Following is the code snippet:

  function CopyDropFolder {
 param(
    [string] $dropFolder,
    [string] $releaseName,
    [string] $mapDrive
 )

 $stageDirectory= $('c:\temp\' + $releaseName + '-' + (Get-Date -Uformat %Y%m%d-%H%M).ToString() + '\')
 [string]$destinationDirectory = $stageDirectory
 Write-Host 'Mapping Folder ' $dropFolder ' as '  $mapDrive 
 MountDropFolder -mapfolder $dropFolder -mapDrive $mapDrive

 $sourceDir = $mapDrive + ':' + '\'  
 Write-Host 'Copying from mapped drive (' $sourceDir ') to ' $stageDirectory
 Copy-Item  $sourceDir -Destination $stageDirectory -Recurse
 Write-Host $destinationDirectory
 return $destinationDirectory  
 }

I call the function as follows:

$stageDirectory = CopyDropFolder -dropFolder $mapFolder -releaseName $releaseName -mapDrive $newDrive
Write-Host 'Staged to ' $stageDirectory 

The output from with the function (Write-Host $destinationDirectory) is:

c:\temp\mycopieddirectory-20161228-1422\

However from the main script where the call is made, output is:

Staged to  Z c:\temp\mycopieddirectory-20161228-1422\

It seems like the stageDirectory variable that is returned is somehow mapped with Z: which is the new drive that is mapped within the function.

Any ideas on how to actually return only the path that is printed above within the function?

1 Answer 1

2

PowerShell has the concept of pipelines. Everything you call that return a value which you don't assign to a variable or pipe e. g. to the Out-Null cmdlet will get returned from the function (even you don't explicitly use the return keyword). So you should pipe the output within your functions to Out-Null:

 function CopyDropFolder {
 param(
    [string] $dropFolder,
    [string] $releaseName,
    [string] $mapDrive
 )

 $stageDirectory= $('c:\temp\' + $releaseName + '-' + (Get-Date -Uformat %Y%m%d-%H%M).ToString() + '\')
 [string]$destinationDirectory = $stageDirectory
 Write-Host 'Mapping Folder ' $dropFolder ' as '  $mapDrive 
 MountDropFolder -mapfolder $dropFolder -mapDrive $mapDrive | Out-Null

 $sourceDir = $mapDrive + ':' + '\'  
 Write-Host 'Copying from mapped drive (' $sourceDir ') to ' $stageDirectory
 Copy-Item  $sourceDir -Destination $stageDirectory -Recurse | Out-Null
 Write-Host $destinationDirectory
 return $destinationDirectory  
 }

Also, you could refactor your method like this:

function Copy-DropFolder 
 {
     [CmdletBinding()]
     param
     (
        [string] $dropFolder,
        [string] $releaseName,
        [string] $mapDrive
     )

     $stageDirectory = Join-Path 'c:\temp\' ('{0}-{1}' -f $releaseName, (Get-Date -Uformat %Y%m%d-%H%M).ToString())

     MountDropFolder -mapfolder $dropFolder -mapDrive $mapDrive | Out-Null
     Copy-Item "$($mapDrive):\"  -Destination $stageDirectory -Recurse | Out-Null

     $stageDirectory
 }

Three main improvements:

  1. Using approved verb (Copy-DropyFolder)
  2. Using the Join-Path cmdlet
  3. Removed Write-Host outputs (you will find plenty of articles why you shouldn't use Write-Host).
Sign up to request clarification or add additional context in comments.

6 Comments

That is very interesting to know. I will try this and let you know the result.
Also, I am confused as to why would it effect the variable $destinationDirectory when I am using $stageDirectory as my destination variable
The Output might trick you, e. g. the MoutDropFolder may use Write-Host. can you try my refactored solution?
My apologies. Yes, I tried and forgot to add | output-null to the first statement. It works :) Thanks @Martin
Your refactored code works perfectly. So, what is the best practice to output to console as well as to the log file? I read in some post that Write-Host is not necessarily evil :) as we can redirect its output when executing.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.