Powershell Scripting Assistance : Copy file with error correction

Experts, Looking for additional PowerShell scripting assistance

Function copy-File1 {
Param(
	[Parameter(Mandatory=$true)]
	$FileName
)
	#Drive Locations
	$tempDir = "$($locations.tempdir)"
	$WorkingDir = "$($locations.working_Dir)"
    $tdrivedir = "$($locations.tdrivedir)"
	[string]$filenamenew = "$(&$filenames.cwf_FileNameNew)"
    [string]$Destination = "$(&$filenames.cwf_Destination)"
    [string]$WorkFileloc = "$(&$filenames.cwf_WorkFileLoc)"
	
	#filename Trim
	$FileName = $FileName.Trim()
	If ([string]::IsNullOrEmpty($FileName)) {
		Throw 'Argument FileName is empty!'
	}
	$filePath = Join-Path -Path $tempDir -ChildPath $FileName
	#Identify which File is being Processed
	Write-Host -ForegroundColor Green "Processing File ""$($filePath)"" ..." -NoNewline
	#Test File Destination Path to see if File Exists.. If it Exists Remove it
	If (Test-Path -Path $filePath) {
		Write-Host " $($filePath) Already Exists : Removing File From Temp Location" -NoNewline
		#Error Handling for Remove-Item Command
		Try {
			$itemtemp = Get-Item -Path $filePath -ErrorAction Stop
 			Remove-Item $itemtemp -ErrorAction Stop
			Write-Host -ForegroundColor Green " Successfully Removed File $FileName" -NoNewline
		
		#Add Error Handing for Copy Command
			Write-Host -ForegroundColor Green "Setting $($workingdir) location"
			Set-Location $WorkingDir;
			if (Test-Path -Path $workingdir){
				Try {
					Write-Host -foregroundcolor green "Path Successfully set to $($workingdir)"
					Write-Host -ForegroundColor Green "Copying "$($locations.tempdir)\$filename" to $Destination"
					copy-item -path "$($locations.tempdir)\$filename" -Destination $Destination
					if (Test-Path $filename) {
						Write-Host -foregroundcolor Green "The file $filename was successfully Copied"}

				} Catch {
							Write-Host "Error Message: $($_.Exception.Message)" -ForegroundColor Red;
							Write-Host -foregroundcolor red "$filename was not Copied Successfully"
				}
			
			}else {
					Write-Host "Couldn't set the proper location : script will Terminate";
					pause;
					end}			
		} Catch {
			Write-Host "Error Message: $($_.Exception.Message)" -ForegroundColor Red -NoNewline
		}
	} Else {
		Write-Host " $($filePath) does not exist." -NoNewline
			Write-Host -ForegroundColor Green "Setting $($workingdir) location"
			Set-Location $WorkingDir;
			if (Test-Path -Path $workingdir){
				Try {
					Write-Host -foregroundcolor green "Path Successfully set to $($workingdir)"
					Write-Host -ForegroundColor Green "Copying "$($locations.tempdir)\$filename" to $Destination"
					copy-item -path "$($locations.tempdir)\$filename" -Destination $Destination
					if (Test-Path $filename) {
						Write-Host -foregroundcolor Green "The file $filename was successfully Copied"}

				} Catch {
							Write-Host "Error Message: $($_.Exception.Message)" -ForegroundColor Red;
							Write-Host -foregroundcolor red "$filename was not Copied Successfully"
				}
			
			}else {
					Write-Host "Couldn't set the proper location : script will Terminate";
					pause;
					end}		
	}
}

Open in new window



The code above is a first attempt at a error handling copy file script. While the code appears to be executing correctly, it is not copying the file requested into the proper location as it appears to successfully do.

Thanks in advance for you assistance with this.

Can anyone shead some light on a more efficient way to accomplish this Properly.
LVL 15
ITguy565Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

oBdACommented:
* Where are the $locations and $filenames objects referenced in lines 7-12 coming from? And if they're regular strings, you don't need a subexpression.
* $tdrivedir and $filenamenew are never used in the function.
* In lines 10-12. the subexpressions start with an ampersand, so PowerShell is trying to execute whatever is in the variable following it. I don't think that's what's intended here.
* Don't use [type] at the left of the equal sign, unless you know exactly what you're doing (strongly typing a variable) and why you need it. PowerShell was designed so that you usually won't have to worry about types.
* You're testing for the existence of $workingDir after you (try to) set the location to said directory.
* There's no command "end" (line 74). If it's a function inside a larger script, you should rename it to the <Verb>-<Noun> syntax, and ideally add a 2 to 3 letter prefix in front of the noun, to distinguish your own functions from default cmdlets (Copy-MyFile, Copy-ItgFile, whatever). <Verb> should be from the list obtained by "Get-Verb".
* You have lots of unnecessary duplicate script - once an existing target file has been removed, you can run the same code as when the target file didn't exist yet.

Restructured:
Function Copy-File1 {
Param(
	[Parameter(Mandatory=$true)]
	$FileName
)
	#Drive Locations
	$tempDir = $locations.tempdir
	$workingDir = $locations.working_Dir
	$tdrivedir = $locations.tdrivedir
	$filenamenew = $filenames.cwf_FileNameNew
	$destination = $filenames.cwf_Destination
	$WorkFileloc = $filenames.cwf_WorkFileLoc
	
	$FileName = $FileName.Trim()
	If ([string]::IsNullOrEmpty($FileName)) {
		Throw 'Argument FileName is empty!'
	}
	$filePath = Join-Path -Path $tempDir -ChildPath $FileName
	#Identify which File is being Processed
	Write-Host "Processing file '$($filePath)' ..." -ForegroundColor Green -NoNewline
	Try {
		#Test File Destination Path to see if File Exists.. If it Exists Remove it
		If (Test-Path -Path $filePath) {
			$action = "Removing existing file '$($filePath)' from Temp location"
			Write-Host $action -NoNewline
			$itemTemp = Get-Item -Path $filePath -ErrorAction Stop
			Remove-Item $itemTemp -ErrorAction Stop
			Write-Host "Successfully removed file $($FileName)" -ForegroundColor Green -NoNewline
		}
		$action = "Setting '$($workingDir)' location"
		Write-Host -ForegroundColor Green $action
		If (Test-Path -Path $workingDir) {
			Set-Location -Path $workingDir
			Write-Host "Path successfully set to '$($workingDir)'" -ForegroundColor Green
			$action = "Copying '$($filePath)' to '$($destination)'"
			Write-Host $action -ForegroundColor Green
			Copy-Item -Path $filePath -Destination $Destination -ErrorAction Stop
			Write-Host "The file $($FileName) was successfully copied" -ForegroundColor Green
		} Else {
			Throw "Expected folder '$($workingDir)' not found!"
		}
	} Catch {
		Write-Host "Action failed: $($action)" -ForegroundColor Red
		Write-Host "Error Message: $($_.Exception.Message)" -ForegroundColor Red
		Write-Host "Script will terminate"
		pause
	}
}	

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ITguy565Author Commented:
oBdA, Thanks for the response.

Here are the definitions for what I am using in the script.  :

$locations = ""|Select Working_Dir, tempDir, tdrivedir, local_Working
    $locations.Working_Dir = {\\server1\c$\WORKING_DIR}
    $locations.local_Working = {(get-childitem C:\users\ -Recurse |? {($_.name -like "working_dir") -and ($_.Attributes -like "Directory*")}).fullname}
    $locations.tempDir = {\\server1\c$\WORKING_DIR\Temp}
    $locations.tdrivedir = {\\server2\c$\tempT}

Open in new window


When I try and execute the code above, it is returning with :

Processing file '' ...Action failed:
Error Message: Cannot bind argument to parameter 'Path' because it is null.
Script will terminate
Press Enter to continue...
0
ITguy565Author Commented:
Sorry for my delay in responding, we are finishing preparations for a hurricane at the moment.
0
oBdACommented:
You can take your time, I'm still in Kansas ...

$locations.Working_Dir = {\\server1\c$\WORKING_DIR}
...

Open in new window

You're defining a scriptblock here, that the function will then just turn into its string representation. That's overly complicated and hard to understand (because the scriptblock by itself will just fail), with no benefit.
I'd recommend to just use a regular string, because that's what you need and expect anyway.

$locations.local_Working = {(get-childitem C:\users\ -Recurse |? {($_.name -like "working_dir") -and ($_.Attributes -like "Directory*")}).fullname}

Open in new window

This is the only case where the scriptblock would actually work as such (so the $filenames variables are defined like that as well, I guess?).
But it would only make sense if in the time between the scriptblock's definition in the main script and the resolution in the function, the target folder you're looking for might have changed. If this folder is supposed to stay the same during the whole runtime of the script, you're better off with retrieving the folder at the script start and saving the path as a regular string.
And just in case: note that this might return more than one folder.

In other words:
Either
Replace lines 7-12 in my script above with the originals:
	$tempDir = "$($locations.tempdir)"
	$WorkingDir = "$($locations.working_Dir)"
	$tdrivedir = "$($locations.tdrivedir)"
	$filenamenew = "$(&$filenames.cwf_FileNameNew)"
	$Destination = "$(&$filenames.cwf_Destination)"
	$WorkFileloc = "$(&$filenames.cwf_WorkFileLoc)"

Open in new window


Or leave the script as is, and set the variables you're passing to regular strings instead of scriptblocks.
0
ITguy565Author Commented:
Thanks again oBdA
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.