Distributed File System (DFS) is a great way to ensure your remote sites can access resources over a local connection instead of a slow wide-area network (WAN) link. DFS is particularly convenient if you need to deploy packages to remote sites. However, DFS may not be an option for some organizations. If DFS isn’t an option for you, and your boss decided a new Corvette with a company logo painted on the side was more important than paying for a faster WAN link, you’ve still got options. Here’s how to use PowerShell as a DFS substitute.
Using PowerShell as an alternative to DFS
Sometimes DFS isn’t the answer for your environment. Maybe your remote sites are all on the same subnet, so namespaces can’t resolve to the closest server. Or maybe ‘DFS’ are the initials of the Ex who broke your heart and… you know… you’re just not ready. Whatever the reason, here’s an alternative to DFS which saves bandwidth when deploying to remote sites using PowerShell and Robocopy.
Step 1: Find a local computer to cache install files on
The first part of our deployment will run ‘Get Closest Server.ps1’ on our target machine to find a close server we can cache the install files on. Here's the script:
This script does the following:
Retrieves a text file with a list of possible cache servers, one hostname per line.
Pings each server in the list and finds the average ping time per hostname. Sorts the list, and saves the hostname with the lowest ping to an environment variable on the target machine.
In my testing, this has been a reliable way to find a server on the local network. Any machine at a different site should have a significantly higher ping time than the one onsite.
Step 2: Copy files from the Repository to the remote cache are target device
The next hurdle is getting the install files copied over from the Repository to the remote cache location, which will then transfer the files to the target machine. Here's the script:
Let's take a look at the different functions of this PowerShell script and break down what each one does.
The ‘CheckFilesAndCopy’ function does a few different things:
Checks to make sure the ‘PDQClosestServer’ environment variable exists. If not, something went wrong in the previous step, so it exits.
Checks to see if the install files already exist on the target machine. If they do, no reason to copy again.
If the files don’t exist or are out of date, the ‘RobocopyFiles’ function is called to copy the files.
Function ‘RobocopyFiles’ uses Robocopy to copy the install files:
Avoids collisions in case multiple deployments are attempting to copy from the repository to the same cache server at the same time. Does this by having a random delayed start, and by checking for lock files and creating a lock file.
Robocopy from the central repository to the cache server. Uses the /xo flag so it doesn’t recopy the files if they have the same name and modified date.
Robocopy from the cache server to the target machine. Uses the /xo flag so it doesn’t recopy the files if they have the same name and modified date.
Step 3: Run the install command
Now that the files have been copied to the target machine, you can run your silent install string. Just update your variables in the ‘Run Install.ps1’ script.
Step 4: Clean up local install files (optional)
Configuring PDQ Deploy to use the closest repository server
I like to separate the ‘Get Closest Server’ script into its own Deploy package so that I can run it separately to see where machines are. You can do that with an Inventory collection that looks at environment variables.*
Then I create a second deployment with three steps:
Nested ‘Get Closest Server'
Precache Installer Files
Run Install Command
*Bonus: Inventory report to display the closest servers of your target machines
After running ‘Get Closest Server’ and doing an environment variable scan (included in the default scan profile), your target machines will have an environment variable of the closest server. You can create a report to show you the information like this:
Where there's a will, there's usually a way (with PowerShell)
DFS is usually the best option for spreading out network load, but in situations when that’s not an option, you can use this method an alternative to DFS and script your deployments to use a cache server. I hope this method saves you some headaches copying files to your remote site in the Siberian wilderness with that spotty satellite connection, or your site in rural Vermont still running on dial-up.
If videos are more your thing, here’s the webcast Lex and I did on this subject. And, if you've made it this far and you're not already using PDQ Deploy and Inventory, I commend you for your determination and grit. However, a trial is just a click away. Check out Deploy and Inventory for free for 14 days. And if you'd rather manage remote devices with an agent-based solution, PDQ Connect might be the perfect solution for you.