5
\$\begingroup\$

This code copies files to our Test server and places the executable on a file share for the tester to access. I'm new to Powershell, so I'm sure I'm not doing this in the most efficient way. Any criticisms would be appreciated.

# the destination that we are copying TO.
$codeToDeploy = "\\deployment_server\App-Shares\Developer_Area\Code to Deploy\";

# all the local folders we'll need
$myProjectFolder = "C:\MTS\ProjectFolder\Project\";
$myLocalOurProjectName =  ($myProjectFolder + "OurProjectName\bin\Debug\");
$myLocalLauncher = ($myProjectFolder + "OurProjectName_Launcher\bin\Debug\");
$myLocalWcfService = ($myProjectFolder + "ProjectWCFService\bin\");
$myLocalWebsite = ($myProjectFolder + "MTSWebsite\bin\");

#----------------------------------------------------------------
# 1. prep the "code to deploy" folder on the server to receive files
#----------------------------------------------------------------

# set our current folder
Set-Location $codeToDeploy

# create the name of the new top level folder with today's date 
$datedFolderName = "MM " + (get-date -Format "yyyy-MM-dd") + "\";

# create the date-named folder - overwrite if it already exists
New-Item $datedFolderName -ItemType directory -Force;

# set our current folder to the date-named folder
Set-Location $datedFolderName;

# create the sub folders
New-Item "OurProjectName Client" -ItemType directory -Force;
New-item "OurProjectName Launcher" -ItemType directory -Force;
New-item "ProjectWCFService\front end" -ItemType directory -Force;
New-item "Website\front end" -ItemType directory -Force;

#----------------------------------------------------------------
# 2. copy all the files from local debug to the target folders
#----------------------------------------------------------------

# copy to the MM Client folder
$destination = ($codeToDeploy + $datedFolderName + "OurProjectName Client\");
Set-Location $myLocalOurProjectName 
Copy-Item *.dll,OurProjectName.exe $destination -Force;

# copy to the Launcher Folder
$destination = ($codeToDeploy + $datedFolderName + "OurProjectName Launcher\");
Set-Location $myLocalLauncher;
Copy-Item OurProjectName_Launcher.exe $destination -Force;

# copy to the Service Folder
$destination = ($codeToDeploy + $datedFolderName + "ProjectWCFService\");
Set-Location $myLocalWcfService;
Copy-Item *.dll $destination -Force;
Set-Location -Path ..
Copy-Item AllService.svc -Destination ($destination + "front end\") -Force;

# copy to the Website Folder
$destination = ($codeToDeploy + $datedFolderName + "Website\");
$frontEnd = ($destination + "front end\")
Set-Location $myLocalWebsite;
Copy-Item *.dll $destination -Force;
Set-Location -Path ..
Copy-Item *.aspx,*.master,CSS,SiteImages $frontEnd -Recurse -Force;

#----------------------------------------------------------------
# 3. copy all the files from local debug to the server's
#    "client install\binaries" location for serving up to the launcher 
#----------------------------------------------------------------

# copy to the MM Client folder
$destination = "\\app-ttps2-tst\App-Shares\Project\Client Install\Binaries\OurProjectName\";
Set-Location $myLocalOurProjectName 
Copy-Item *.dll,OurProjectName.exe -Destination $destination -Force;

#----------------------------------------------------------------
# 4. copy all the files from local debug to the UI Testing location
#----------------------------------------------------------------

$folders = Get-ChildItem "\\nw\data\TnFS\Project\ProjectFolder\UI TESTING\MM *" | Sort-Object

#save the latest config file for later
#$latestConfigFile = $folders | Select-Object -Last  | Get-ChildItem OurProjectName.exe.config

# copy to the MM Client folder
$destination = "\\nw\data\TnFS\Project\ProjectFolder\UI TESTING\" + $datedFolderName;
New-Item $destination -ItemType directory -Force;

Set-Location $myLocalOurProjectName 
Copy-Item *.dll,OurProjectName.exe -Destination $destination -Force;
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

Simple program at first glance. I am glad to see some documentation there that explains what the code does. This is a good and important practice.

Set-Location

This is the only real problem I see with the code here. You rely on the working directory of PowerShell when copying files. You already know the directories you are using. Use the full paths and skip Set-Location altogether. This will reduce complexity and points of failure.

Instead of

# copy to the MM Client folder
$destination = ($codeToDeploy + $datedFolderName + "OurProjectName Client\");
Set-Location $myLocalOurProjectName 
Copy-Item *.dll,OurProjectName.exe $destination -Force;

Use

# copy to the MM Client folder
$destination = ($codeToDeploy + $datedFolderName + "OurProjectName Client\");
Copy-Item -Path $myLocalOurProjectName -Include "*.dll","OurProjectName.exe" -Destination $destination -Force

In this same vein use the parameter names when writing code. Position arguments are fine for testing but readability improves for you and others when you use named arguments.

New-Item

When creating new folders PowerShell will output the Directory Object when it is created. Most find this undesirable. To void the output a clean approach is to pipe Out-Null. There are other ways to do this as well.

New-Item $destination -ItemType directory -Force | Out-Null

You might like the output but just beware it is there and being generated by New-Item.

String based path creation

This can work fine but a better practice is to use cmdlets and methods to build paths reliably. This way you don't have to worry about leading and trailing as much. When it comes to stitching more that 2 folder/paths together Combine is your friend.

Instead of

$destination = ($codeToDeploy + $datedFolderName + "OurProjectName Client\");

Consider

[io.path]::Combine($codeToDeploy, $datedFolderName, "OurProjectName Client\")

Code Repetition

This is largely made moot by what was said previously but keep this in mind. You have small code blocks that are repetitions but use the same logic with just some strings changing. Functions should be used here so that if some logic has to be added you are making the change in one place as supposed to updating several snippets throughout the code.

Pointless Code

Understand that I really wanted another word other than pointless. You have at least one line that is not serving a purpose

$folders = Get-ChildItem "\\nw\data\TnFS\Project\ProjectFolder\UI TESTING\MM *" | Sort-Object

There was commented code related to the above line but, since it was commented, the above line serves no purpose. Something to watch out for.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.