I consider myself to be a strong follower of the DRY principle. I practice it religiously. Lately, I have been applying DRY outside of my IDE, more specifically, with my build environments and daily developer tasks.
For example, every night I clean my build environment, sync up the latest code, and rebuild all products within my domain. The total time it takes to clean, sync, and build is over two hours, depending on hardware and connection speed. This has been reduced from over four hours. Now before I do all of this, I need to check my environment to ensure I have all the latest tools and versions of those tools, such as Visual Studio, SQL Server, windows updates, service packs, ect. This is just part of our build environment. Typically, we run this check until we receive a positive response, "all is well."
Rather than spend my time running these commands, I automate them, and run them around the clock using Task Scheduler, a BAT file, and PowerShell.
I create one scheduled task that runs once per hour, indefinitely. My scheduled task runs a BAT file that calls my PowerShell script. Within my PowerShell script, I create a Hashtable of commands to run and at which hour to run them. Each hour as the script is executed, I get the current hour and see if any tasks are available to run. For example, each night, sometime during the 2 AM hour, I start my full build. I realize that running once per hour limits the number of commands I can run, but for now, this imperfect solution meets my needs.
Nightly PowerShell Script -
Copy Code 1 # Local variables
2 $productRoot = "c:\Projects\dev"
3 $currentHour = (Get-Date).Hour
4 $list = New-Object System.Collections.Hashtable
5
6 # Define tasks to run each hour
7 # Hour 0 = 12:00-12:59 AM
8 # Hour 1 = 1:00-1:59 AM
9 # Hour 20 = 8:00-8:59 PM
10 $list.Add(20,"environmentCheck dev");
11 $list.Add(21,"environmentCheck test");
12 $list.Add(22,"environmentCheck system");
13 $list.Add(23,"projects clean sync");
14 $list.Add(2,"projects build full");
15
16 # if a task is defined for this hour, execute it
17 if($list.Contains($currentHour))
18 {
19 # Get the command to execute for this hour
20 $buildCommand = $list[$currentHour]
21
22 # Set the project bat path
23 $pathToBat = $productRoot + "\bin\project.bat"
24
25 # Set the cmd.exe's arguments
26 $arguments = "/C cd /d " + $productRoot + " & " + $pathToBat + " & " + $buildCommand
27
28 # Start up the DOS prompt, execute the commands
29 $process = New-Object -TypeName System.Diagnostics.Process
30 $process.StartInfo.FileName = "cmd.exe"
31 $process.StartInfo.Arguments = $arguments
32 $process.StartInfo.UseShellExecute = $false
33 $process.Start()
34 $process.WaitForExit()
35 }
Every morning, I expect to have fresh builds. My build system will email me with the results. However, adding email capabilities to the above script with PowerShell is doable. The above commands execute on my dev server, but executing them on remote servers is also doable, even with PowerShell 1.0 and something like the following.
Execute Command Remotely -
Copy Code1 $toServer = "my-remote-server"
2 ([WMICLASS]"\\$toServer\ROOT\CIMV2:win32_process").Create($command)
If my environment is not current and my builds are not working, I can lose productivity during normal business hours. Using a simple scheduled task and PowerShell helps me administer my server and keeps me from repeating the same tedious steps on a daily basis.
How else does PowerShell help me adhere to DRY? It enables me to administer my Hyper-V machines, configure websites, GAC and un-GAC assemblies, and much more.