<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>devtrends.com</title>
	<atom:link href="http://www.devtrends.com/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.devtrends.com</link>
	<description>developing trends in information technology</description>
	<lastBuildDate>Tue, 09 Mar 2010 04:51:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Deploying Applications with the Possibility of a Slow Connection (Robocopy)</title>
		<link>http://www.devtrends.com/index.php/deploying-applications-with-the-possibility-of-a-slow-connection/</link>
		<comments>http://www.devtrends.com/index.php/deploying-applications-with-the-possibility-of-a-slow-connection/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 19:43:49 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[Batch Files]]></category>
		<category><![CDATA[Featured 2]]></category>
		<category><![CDATA[Microsoft O/S]]></category>
		<category><![CDATA[robocopy]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.devtrends.com/?p=523</guid>
		<description><![CDATA[Regardless of which software deployment suite you use in your organization, there is no way to avoid transferring the majority of the installation files to the local machine, whether that is a file copy or a load into memory / temporary location. For small application deployments, running them directly from a share location on a [...]]]></description>
			<content:encoded><![CDATA[<p>Regardless of which software deployment suite you use in your organization, there is no way to avoid transferring the majority of the installation files to the local machine, whether that is a file copy or a load into memory / temporary location. For small application deployments, running them directly from a share location on a server isn’t necessarily a bad idea, even if the user is connected remotely. However, on the other side of the spectrum, installing Microsoft Office from a server share, while connected remotely, is a bad idea.</p>
<p>So what is the solution? How about staging the files on the local hard drive prior to starting the installation? Your first thought might be a batch file or command script that uses xcopy – at least that was my first thought. However, xcopy assumes that your connection will not drop and that it is fairly fast. What happens when the user is remote and while copying the files the user disconnects from the Internet and Virtual Private Network (VPN)? The file copy process has to start over…</p>
<p>With robocopy, a Microsoft product, you can configure it to copy with resume capabilities. In addition, if you show the installation process to your users (different discussion), each file in the copy process displays its current transferred status (0-100%).</p>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/02/robocopy1.jpg"><img class="alignnone size-medium wp-image-524" title="robocopy1" src="http://www.devtrends.com/wp-content/uploads/2010/02/robocopy1-300x151.jpg" alt="" width="300" height="151" /></a></p>
<p><strong>Getting RoboCopy</strong></p>
<p>Robocopy is available for free from Microsoft as part of the Microsoft Windows Server 2003 <a href="http://go.microsoft.com/fwlink/?LinkId=72969" target="_blank">Resource Kit Tools</a>. The command line options are somewhat daunting, something you’d expect to see from the “grep &#8211;help” command in Linux. In this article we only use a small amount of the power that is Robocopy. For those that dislike command line tools, but still need the functionality of Robocopy, have a look at the GUI tools available for Robocopy.</p>
<ul>
<li><a href="http://technet.microsoft.com/en-us/magazine/2006.11.utilityspotlight.aspx" target="_blank">Utility Spotlight Robocopy GUI</a></li>
<li><a href="http://technet.microsoft.com/en-us/magazine/2009.04.utilityspotlight.aspx" target="_blank">Utility Spotlight RichCopy</a></li>
</ul>
<p><strong>Simple Deployment Script (Adobe Reader)</strong></p>
<p>Below is an example for deploying Adobe Reader to clients utilizing the Robocopy tool.</p>
<pre style="padding-left: 30px;">@ECHO OFF</pre>
<pre style="padding-left: 30px;">rem Create log folder, just in case it does not exist
md C:\installer
md C:\installer\logs
md C:\installer\AdobeReader9.3.0</pre>
<pre style="padding-left: 30px;">rem Bring down the files to the local drive
"\\installer\dist$\robocopy.exe" "\\installer\dist$\AdobeReader" "c:\installer\AdobeReader9.3.0" *.* /E /Z</pre>
<pre style="padding-left: 30px;">rem begin installation
msiexec.exe /i c:\installer\AdobeReader9.3.0\AcroRead.msi TRANSFORMS=c:\installer\AdobeReader9.3.0\AcroRead.mst /qn /l*v C:\installer\logs\AdobeReader9.3.0.log</pre>
<p><strong>Robocopy Command Line Options</strong></p>
<pre>C:\&gt;robocopy /?

-------------------------------------------------------------------------------
   ROBOCOPY     ::     Robust File Copy for Windows     ::     Version XP010
-------------------------------------------------------------------------------

  Started : Fri Feb 05 10:30:35 2010

              Usage :: ROBOCOPY source destination [file [file]...] [options]

             source :: Source Directory (drive:\path or \\server\share\path).
        destination :: Destination Dir  (drive:\path or \\server\share\path).
               file :: File(s) to copy  (names/wildcards: default is "*.*").

::
:: Copy options :
::
                 /S :: copy Subdirectories, but not empty ones.
                 /E :: copy subdirectories, including Empty ones.
             /LEV:n :: only copy the top n LEVels of the source directory tree.

                 /Z :: copy files in restartable mode.
                 /B :: copy files in Backup mode.
                /ZB :: use restartable mode; if access denied use Backup mode.

  /COPY:copyflag[s] :: what to COPY (default is /COPY:DAT).
                       (copyflags : D=Data, A=Attributes, T=Timestamps).
                       (S=Security=NTFS ACLs, O=Owner info, U=aUditing info).

               /SEC :: copy files with SECurity (equivalent to /COPY:DATS).
           /COPYALL :: COPY ALL file info (equivalent to /COPY:DATSOU).
            /NOCOPY :: COPY NO file info (useful with /PURGE).

             /PURGE :: delete dest files/dirs that no longer exist in source.
               /MIR :: MIRror a directory tree (equivalent to /E plus /PURGE).

               /MOV :: MOVe files (delete from source after copying).
              /MOVE :: MOVE files AND dirs (delete from source after copying).

       /A+:[RASHNT] :: add the given Attributes to copied files.
       /A-:[RASHNT] :: remove the given Attributes from copied files.

            /CREATE :: CREATE directory tree and zero-length files only.
               /FAT :: create destination files using 8.3 FAT file names only.
               /FFT :: assume FAT File Times (2-second granularity).
               /256 :: turn off very long path (&gt; 256 characters) support.

             /MON:n :: MONitor source; run again when more than n changes seen.
             /MOT:m :: MOnitor source; run again in m minutes Time, if changed.

      /RH:hhmm-hhmm :: Run Hours - times when new copies may be started.
                /PF :: check run hours on a Per File (not per pass) basis.

             /IPG:n :: Inter-Packet Gap (ms), to free bandwidth on slow lines.

::
:: File Selection Options :
::
                 /A :: copy only files with the Archive attribute set.
                 /M :: copy only files with the Archive attribute and reset it.
    /IA:[RASHCNETO] :: Include only files with any of the given Attributes set.
    /XA:[RASHCNETO] :: eXclude files with any of the given Attributes set.

 /XF file [file]... :: eXclude Files matching given names/paths/wildcards.
 /XD dirs [dirs]... :: eXclude Directories matching given names/paths.

                /XC :: eXclude Changed files.
                /XN :: eXclude Newer files.
                /XO :: eXclude Older files.
                /XX :: eXclude eXtra files and directories.
                /XL :: eXclude Lonely files and directories.
                /IS :: Include Same files.
                /IT :: Include Tweaked files.

             /MAX:n :: MAXimum file size - exclude files bigger than n bytes.
             /MIN:n :: MINimum file size - exclude files smaller than n bytes.

          /MAXAGE:n :: MAXimum file AGE - exclude files older than n days/date.
          /MINAGE:n :: MINimum file AGE - exclude files newer than n days/date.
          /MAXLAD:n :: MAXimum Last Access Date - exclude files unused since n.
          /MINLAD:n :: MINimum Last Access Date - exclude files used since n.
                       (If n &lt; 1900 then n = n days, else n = YYYYMMDD date).

                /XJ :: eXclude Junction points. (normally included by default).

::
:: Retry Options :
::
               /R:n :: number of Retries on failed copies: default 1 million.
               /W:n :: Wait time between retries: default is 30 seconds.

               /REG :: Save /R:n and /W:n in the Registry as default settings.

               /TBD :: wait for sharenames To Be Defined (retry error 67).

::
:: Logging Options :
::
                 /L :: List only - don't copy, timestamp or delete any files.
                 /X :: report all eXtra files, not just those selected.
                 /V :: produce Verbose output, showing skipped files.
                /TS :: include source file Time Stamps in the output.
                /FP :: include Full Pathname of files in the output.

                /NS :: No Size - don't log file sizes.
                /NC :: No Class - don't log file classes.
               /NFL :: No File List - don't log file names.
               /NDL :: No Directory List - don't log directory names.

                /NP :: No Progress - don't display % copied.
               /ETA :: show Estimated Time of Arrival of copied files.

          /LOG:file :: output status to LOG file (overwrite existing log).
         /LOG+:file :: output status to LOG file (append to existing log).

               /TEE :: output to console window, as well as the log file.

               /NJH :: No Job Header.
               /NJS :: No Job Summary.

::
:: Job Options :
::
       /JOB:jobname :: take parameters from the named JOB file.
      /SAVE:jobname :: SAVE parameters to the named job file
              /QUIT :: QUIT after processing command line (to view parameters).

              /NOSD :: NO Source Directory is specified.
              /NODD :: NO Destination Directory is specified.
                /IF :: Include the following Files.</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.devtrends.com/index.php/deploying-applications-with-the-possibility-of-a-slow-connection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bart&#8217;s Preinstalled Environment (BartPE) Windows LiveCD</title>
		<link>http://www.devtrends.com/index.php/barts-preinstalled-environment-bartpe-windows-livecd/</link>
		<comments>http://www.devtrends.com/index.php/barts-preinstalled-environment-bartpe-windows-livecd/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 16:30:39 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[Windows XP]]></category>
		<category><![CDATA[LiveCD]]></category>
		<category><![CDATA[Rescue]]></category>
		<category><![CDATA[Windows PE]]></category>

		<guid isPermaLink="false">http://www.devtrends.com/?p=518</guid>
		<description><![CDATA[As much as I love the old school Disk Operating System (DOS) environment, the benefits of working with DOS, even for firmware updating, is fading away. Who has a floppy drive any more? Well I do, I purchased one with my Dell laptop and even though it is the slide in type (pull out the [...]]]></description>
			<content:encoded><![CDATA[<p>As much as I love the old school Disk Operating System (DOS) environment, the benefits of working with DOS, even for firmware updating, is fading away. Who has a floppy drive any more? Well I do, I purchased one with my Dell laptop and even though it is the slide in type (pull out the CD/DVD drive), it has a USB connector on the side of it. However, when it came time to create a bootable floppy, I couldn&#8217;t find any disks laying around. So, create a bootable DOS CD &#8211; still has limitations if you try to emulate a floppy.</p>
<p>Regardless, the 1.44MB limitation is irritating at minimum. Working with 1.44MB floppies today is almost as bad as working with old DOS programs in Windows 95 that can&#8217;t figure out how to use extended memory (above 640KB). It seems that many firmware updates are larger than a floppy, and if you try to fit it along with the bootable files, MSDOS.SYS et cetera, you&#8217;ll be quite unsuccessful. So, screw DOS boot disks &#8211; let&#8217;s make a Windows LiveCD!</p>
<p><strong>BartPE</strong></p>
<p>To ensure that everyone knows, Bart Lagerweij is the master mind, I am merely shareing my experiences with his exceptional work.</p>
<p>Go ahead and review <a href="http://www.nu2.nu/pebuilder/" target="_blank">Bart&#8217;s PE page</a>. Download and install the latest PEBuilder application from that link. You should also review the licensing notice.</p>
<p>In this example we are going to create a Windows XP PE LiveCD. To get started you will need a Windows XP Professional non-OEM CD, which Bart&#8217;s pebuilder application will use to create the bootable LiveCD, and a blank CD for the final product.</p>
<p><em>Note: unless you have two CD drives, I would recommend copying the contents of your Windows XP cd to your hard drive.</em></p>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/02/PE-Builder-1.jpg"><img class="alignnone size-medium wp-image-519" title="PE Builder 1" src="http://www.devtrends.com/wp-content/uploads/2010/02/PE-Builder-1-300x252.jpg" alt="" width="300" height="252" /></a></p>
<p>Open Bart&#8217;s PE Builder and set the source to the location where the Windows XP files reside. Under media output, choose &#8220;Burn to CD/DVD&#8221;. Click on the Builder menu and choose &#8220;Build ISO/CD (F5)&#8221;.</p>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/02/PE-Builder-2.jpg"><img class="alignnone size-medium wp-image-520" title="PE Builder 2" src="http://www.devtrends.com/wp-content/uploads/2010/02/PE-Builder-2-300x252.jpg" alt="" width="300" height="252" /></a></p>
<p>Assuming you receive no errors during the build and burn process, you should now have a bootable Windows XP LiveCD.</p>
<p>-Aaron Gilbert</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devtrends.com/index.php/barts-preinstalled-environment-bartpe-windows-livecd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Move Files with Folder Actions and AppleScript</title>
		<link>http://www.devtrends.com/index.php/move-files-with-folder-actions-and-applescript/</link>
		<comments>http://www.devtrends.com/index.php/move-files-with-folder-actions-and-applescript/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 05:09:17 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[Featured 2]]></category>
		<category><![CDATA[Folder Actions]]></category>
		<category><![CDATA[POSIX]]></category>

		<guid isPermaLink="false">http://www.devtrends.com/?p=512</guid>
		<description><![CDATA[In relation to my article on Combining PDFs in Apple Automator, I needed to automate moving files from one location to another, with the final destination name of the file being different than the original. At first I thought this would be 5 minutes in AppleScript, until I realized, as with all programming, that I [...]]]></description>
			<content:encoded><![CDATA[<p>In relation to my article on <a href="http://www.devtrends.com/index.php/combine-pdfs-in-apple-automator/">Combining PDFs in Apple Automator</a>, I needed to automate moving files from one location to another, with the final destination name of the file being different than the original. At first I thought this would be 5 minutes in AppleScript, until I realized, as with all programming, that I would run into programming language complexities. The first one was moving to a mounted location, the second was formatting dates and the third was getting a single object in the array, added_items, to output the UNIX style path.</p>
<p>The script to accomplish this task ended up looking like this:</p>
<pre style="padding-left: 30px;"><strong>on</strong> adding folder items to this_folder after receiving added_items<strong>
  repeat</strong> <strong>with</strong> this_item <strong>in</strong> added_items<strong>
    set</strong> destpath <strong>to</strong> "/Volumes/[mount name]/[share]/" <strong>as</strong> string<strong>
    set</strong> datestring <strong>to</strong> ((year <strong>of</strong> (current date)) * 10000) + ((month <strong>of</strong> (current date) <strong>as</strong> integer) * 100) + (day <strong>of</strong> (current date)) <strong>as</strong> integer<strong>
    set</strong> destfilename <strong>to</strong> "thefile_" &amp; datestring &amp; ".pdf" <strong>as</strong> string<strong>
    set</strong> sourcepath <strong>to</strong> POSIX path <strong>of</strong> this_item<strong>
  end</strong> <strong>repeat
end</strong> adding folder items to</pre>
<p>If you are familiar with Visual Basic, the &#8220;repeat with this_item in added_items&#8221; would be similar to &#8220;for each this_item in added_items&#8221;. This creates a single object (this_item) from the array of objects (added_items). The destpath is a variable of the location that we will write the final file, which in this case is a mounted server.</p>
<p><strong>datestring</strong></p>
<p>The date format was not as easy to accomplish as I would have expected, especially considering that AppleScript is supposed to simple to use with its English language type structure. To create a date of 20100101, I had to use traditional math starting with the current year multiplied by 10000, which would end up:</p>
<pre style="padding-left: 30px;">2010 * 10000 = 20100000</pre>
<p>Next I needed to add the month in the appropriate location in the integer. This was accomplished by current month multiplied by 100, which would end up:</p>
<pre style="padding-left: 30px;">01 * 100 = 100</pre>
<p>Add the month to the year integer and you have:</p>
<pre style="padding-left: 30px;">20100000 + 100 = 20100100</pre>
<p>Finally, we need to add the day, which as you can imagine, needs no modification:</p>
<pre style="padding-left: 30px;">20100100 + 01 = 20100101</pre>
<p>The final number is stored in the variable datestring.</p>
<p><strong>sourcepath</strong></p>
<p>After about 30 minutes of frustration, working with other avenues to accomplish the same task, I finally found an AppleScript example that used &#8220;POSIX path of&#8221;. Being that I am a native Windows guy, POSIX is fairly foreign to me, however, it is key to making sure the shell command, &#8220;mv&#8221;, works properly.</p>
<p>If you were to use:</p>
<pre style="padding-left: 30px;">set sourcepath to name of this_item</pre>
<p>you  would get a path separated with colons, such as harddrive:Volumes:[mount name]:[share], which is clearly useless in a shell environment. So instead, we must request the POSIX path, which is the full path and file name of &#8220;this_item&#8221;:</p>
<pre style="padding-left: 30px;">set sourcepath to POSIX path of this_item</pre>
<p>That is it&#8230;assign this script to a folder using the Folder Actions functionality of the Mac operating system.</p>
<p>-Aaron Gilbert</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devtrends.com/index.php/move-files-with-folder-actions-and-applescript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alert (Display Dialog) in AppleScript</title>
		<link>http://www.devtrends.com/index.php/alert-display-dialog-in-applescript/</link>
		<comments>http://www.devtrends.com/index.php/alert-display-dialog-in-applescript/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 04:40:12 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[display dialog]]></category>

		<guid isPermaLink="false">http://www.devtrends.com/?p=510</guid>
		<description><![CDATA[To display an alert or dialog prompt in AppleScript is easy, once you know the command string to use. For simple scripting, such as AppleScript or VBScript, I will frequently use alert dialogs to display the contents of variables. Hmm, any other reasons for a dialog prompt? Obviously, the true intent is to provide some [...]]]></description>
			<content:encoded><![CDATA[<p>To display an alert or dialog prompt in AppleScript is easy, once you know the command string to use. For simple scripting, such as AppleScript or VBScript, I will frequently use alert dialogs to display the contents of variables. Hmm, any other reasons for a dialog prompt? Obviously, the true intent is to provide some type of user interface/input&#8230;</p>
<pre style="padding-left: 30px;">display dialog the [string variable]
  buttons {"Yes", "No"}
  default button 1
  with icon 1
  giving up after [(x) seconds]</pre>
<p>To customize this, replace [string variable] with a string in quotes or a string variable name. The buttons array will let you define the text of each button, if you wanted only an &#8220;Ok&#8221; use {&#8220;Ok&#8221;}. The default button 1 defines which button is automatically selected. Giving up after (x) seconds will close the dialog automatically if the user does not respond.</p>
<pre style="padding-left: 30px;">set my_variable to text returned of (display dialog the [string variable]
  buttons {"Yes", "No"}
  default button 1
  with icon 1)</pre>
<p>The above example allows you to use a &#8220;display dialog&#8221; as a user prompt, requiring some type of input that the remaining AppleScript can then process through logic, if, select, et cetera.</p>
<p>As you might have imagined, there are more options available for &#8220;display dialog&#8221;, including user input (text and multiple buttons). If you want more information on the &#8220;display dialog&#8221; method, check out this article on <a href="http://en.wikibooks.org/wiki/AppleScript_Programming/Advanced_Code_List/Display_Dialog" target="_blank">wikibooks</a>.</p>
<p>-Aaron Gilbert</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devtrends.com/index.php/alert-display-dialog-in-applescript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Startup Notification</title>
		<link>http://www.devtrends.com/index.php/startup-notification/</link>
		<comments>http://www.devtrends.com/index.php/startup-notification/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 21:16:01 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[Workstation Management]]></category>
		<category><![CDATA[GPO]]></category>
		<category><![CDATA[Startup]]></category>

		<guid isPermaLink="false">http://www.devtrends.com/?p=500</guid>
		<description><![CDATA[How do you know when an approved and domain-joined workstation is turned on prior to someone even signing into the workstation? Or maybe, you are asking, why would I even want to know this? For those that work with network vulnerabilities scanning, such as the product by McAfee’s Foundstone division, this may be of importance. [...]]]></description>
			<content:encoded><![CDATA[<p>How do you know when an approved and domain-joined workstation is turned on prior to someone even signing into the workstation? Or maybe, you are asking, why would I even want to know this? For those that work with network vulnerabilities scanning, such as the product by McAfee’s Foundstone division, this may be of importance. Imagine this scenario. Holiday season arises, everyone loves to take time off and you have an employee that took 2-3 weeks off. When that employee returns, there is a good chance that their computer will be out-dated. From a security standpoint, this is minimal, as it would likely begin receiving updates immediately following a successful sign-on. However, from a political standpoint, if Foundstone is used as a means of judging overall “security”, this workstation could significantly lower that score.</p>
<p>I already know what you are thinking…however, that does not eliminate the fact that dashboard reports are favored by CIOs, IT Directors and the like. Better have that score up to 100%!</p>
<p><strong>StartupNotification</strong></p>
<p>I wrote an application, StartupNotification, that helps with maintaining good scores. Keep in mind that this application only provides a means for notifying the appropriate personnel when a workstation is brought on the network that could potentially “damage”. Second, for this application to be effective in notifying, it must be added as a domain GPO or local policy startup script.</p>
<p><span style="text-decoration: underline;">How It Works</span></p>
<p>Ran from a Windows computer startup script, StartupNotification checks a SQL database for previous records associated with the name of the workstation running StartupNotification. If no records exist, it reports an “Untracked” workstation; if record(s) exist and the latest record is (x) days old, it reports a “Tracked” workstation. After checking the status of the workstation, StartupNotification will create a new record with the workstation name and date of transaction, which will be used at the next StartupNotification check in.</p>
<p><span style="text-decoration: underline;">The Application</span></p>
<p>Download <a href="http://www.devtrends.com/wp-content/uploads/2010/01/StartupNotification.zip">source code</a> (written in Visual Studio 2008).</p>
<p>If you are interested in this application working in your environment, then there are a few things your must do…</p>
<ol>
<li>Create a SQL table with the necessary fields.</li>
<li>Update the application code with your connection string for the database.</li>
<li>Update the email notification messages.</li>
<li>Update the SMTP “from” email address.</li>
</ol>
<p>This is simple, I’ll help you along the way if you follow the steps below carefully:</p>
<p><em>SQL Database and Table</em></p>
<p>I use Microsoft SQL Server 2005; however, this could be easily ported to MySQL, another SQL database, or even a Microsoft Access database. I created a separate database named STARTUPNOTIFICATION for the purpose of holding the table. The table layout is simple, as shown below:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="213" valign="top">field name</td>
<td width="213" valign="top">data type</td>
<td width="213" valign="top">specifics</td>
</tr>
<tr>
<td width="213" valign="top"><strong>ID</strong></td>
<td width="213" valign="top"><strong>int</strong></td>
<td width="213" valign="top"><strong>primary key, no NULL</strong></td>
</tr>
<tr>
<td width="213" valign="top"><strong>Workstation</strong></td>
<td width="213" valign="top"><strong>nvarchar(50)</strong></td>
<td width="213" valign="top"><strong>NULL</strong></td>
</tr>
<tr>
<td width="213" valign="top"><strong>Date</strong></td>
<td width="213" valign="top"><strong>datetime</strong></td>
<td width="213" valign="top"><strong>no NULL</strong></td>
</tr>
<tr>
<td width="213" valign="top"><strong>IPaddress</strong></td>
<td width="213" valign="top"><strong>nvarchar(50)</strong></td>
<td width="213" valign="top"><strong>NULL</strong></td>
</tr>
</tbody>
</table>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/01/createtable.zip">createscript.sql</a></p>
<p>You must have a SQL user account that can SELECT and INSERT to this table. It is recommended that this account be a separate account and not the “sa” account or some other powerful, generic account.</p>
<p><em>Update Connection String</em></p>
<p>Locate the “mySQL.ConnectionString” property in the code, as shown the screen shot below, and update the string to match your server and database.</p>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/01/connectionstring.jpg"><img class="alignnone size-medium wp-image-501" title="connectionstring" src="http://www.devtrends.com/wp-content/uploads/2010/01/connectionstring-300x70.jpg" alt="connectionstring" width="300" height="70" /></a></p>
<p><em>Update Email Notification Messages</em></p>
<p>Locate the “sendEmail” function calls, as shown in the screen shot below, and update the strings to display the text you want to be included in the email. As an example, I have another application I wrote that grabs information on the workstation and user at sign-in; I place a link to display who has signed in to that workstation in the email for quick identification of the workstation location.</p>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/01/emailnotifications.jpg"><img class="alignnone size-medium wp-image-502" title="emailnotifications" src="http://www.devtrends.com/wp-content/uploads/2010/01/emailnotifications-300x132.jpg" alt="emailnotifications" width="300" height="132" /></a></p>
<p><em>Update SMTP “From” Address</em></p>
<p>The final line that needs your attention is the email address that is used as the sender for this application. In most cases you should use a “do not reply” type email address. Locate the sendEmail function near the bottom of the code and modify the msg.From property line, as shown the screen shot below.</p>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/01/smtpfromaddress.jpg"><img class="alignnone size-medium wp-image-503" title="smtpfromaddress" src="http://www.devtrends.com/wp-content/uploads/2010/01/smtpfromaddress-300x119.jpg" alt="smtpfromaddress" width="300" height="119" /></a></p>
<p>That is all, compile and set to run as in a startup script. For GPO startup scripts, the application could reside in the NETLOGON path as permissions have not been granted by a signed in user.</p>
<p>Aaron Gilbert</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devtrends.com/index.php/startup-notification/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Combine PDFs in Apple Automator</title>
		<link>http://www.devtrends.com/index.php/combine-pdfs-in-apple-automator/</link>
		<comments>http://www.devtrends.com/index.php/combine-pdfs-in-apple-automator/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 02:38:17 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[Automator]]></category>
		<category><![CDATA[Featured 2]]></category>
		<category><![CDATA[Folder Actions]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[.scpt]]></category>

		<guid isPermaLink="false">http://www.devtrends.com/?p=489</guid>
		<description><![CDATA[There is a dream that I will become specialized in one area, with my aspirations pointed towards network engineering. However, until I get there I will be good at everything, a jack-of-all-trades that seemingly cannot understand the meaning of “no”. This type of quality creates immediate opportunity that pays well but slows growth in specialized [...]]]></description>
			<content:encoded><![CDATA[<p>There is a dream that I will become specialized in one area, with my aspirations pointed towards network engineering. However, until I get there I will be good at everything, a jack-of-all-trades that seemingly cannot understand the meaning of “no”. This type of quality creates immediate opportunity that pays well but slows growth in specialized areas. My father always told me that I make too much to be rich, which I did not understand until I realized that my current efforts, which provide well, have a negative effect on crossing over into the entrepreneur realm.</p>
<p>Enough of that…today I step out of my Microsoft box and into the world of Apple and create some Automator workflows to combine multiple PDFs, in alphabetical order, from one folder and output into another folder.</p>
<p><strong>Apple Automator!</strong></p>
<p>The requirements of this task was to combine single page PDF files automatically, with the only user intervention being manual placement of the PDFs into a folder. This was accomplished with a two step process: (1) create the workflow in Automator; and (2) trigger the workflow using Apple’s Folder Actions feature.</p>
<p>For those that just want to steal, download <a href="http://www.devtrends.com/downloads/combinepdfs.zip">here</a>.</p>
<p>For me, this was the first time I have ever used Automator, and frankly, I was quite impressed with the ease and intuitive design. The basic process involved was to find the PDF files, sort that list, combine the PDFs, move that file to another location, add a date to the output file name and then remove the original list of PDF files.</p>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/01/fullworkflow.jpg"><img class="alignnone size-medium wp-image-490" title="fullworkflow" src="http://www.devtrends.com/wp-content/uploads/2010/01/fullworkflow-300x241.jpg" alt="fullworkflow" width="300" height="241" /></a></p>
<p>As shown in the screen shot above, this is easily accomplished using predefined Automator Actions, which includes the PDF actions. The first action is “Find Finder Items”, which allows us to specify a directory and other variables, such as file name specifics. In this case, I said all files that have a name that ends with .pdf. The second action is named “Sort Finder Items”, which takes the list as passed from “Find Finder Items”, notice the linking arrows between actions, and sorts them by name. The third will use the “Combine PDF Pages” action and will take the sort list of PDFs and make them into one PDF file.</p>
<p>The combined PDF is created in a temporary location with a random file name. The fourth action, “Move Finder Items” moves that file to a specific folder. Finally, the last in this group of actions is the “Rename Finder Items (Add Date or Time to Finder Item Names)”, which I have specified to add a date to the front of the file name.</p>
<p>The last two actions are in a different group for the reason that I do not want to work with the files/folders and provided by the last action in the previous group. Instead, similar to the start of the first group, the first action in this group is “Find Finder Items”, which allows us to specify a folder (same directory) and other variables, such as file name specifics. In this case, I said all files that have a name that ends with .pdf. The second and last action in this group moves those files to the Trash.</p>
<p><strong>Folder Actions</strong></p>
<p>Folder Actions employ AppleScripts that are triggered following a specific folder event. In this case and more common than not, the event is generally after files have been copied to the folder. As you may know, an AppleScript can accomplish a fair amount, including running Automator workflows and shell scripts. In this example, when we save the Automator workflow as a Plug-in, it will create two files, an application equivalent of the Automator workflow and an AppleScript that runs the Automator application.</p>
<p>To make an Automator workflow a folder action, you must save the Automator workflow as a “Plug-in”. At the Save As Plug-in dialog, you must choose ”Folder Actions” under “Plug-in for:” and then specify a folder to attach to. Name the plug-in accordingly and then click Save.</p>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/01/saveasplugin.jpg"><img class="alignnone size-medium wp-image-493" title="saveasplugin" src="http://www.devtrends.com/wp-content/uploads/2010/01/saveasplugin-300x156.jpg" alt="saveasplugin" width="300" height="156" /></a></p>
<p>Now that you have added an Automator workflow, right click on the folder and click on “Attach a Folder Action”. Choose the appropriate AppleScript – usually the same name as the Automator workflow you just saved.</p>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/01/whichscpt.jpg"><img class="alignnone size-medium wp-image-495" title="whichscpt" src="http://www.devtrends.com/wp-content/uploads/2010/01/whichscpt-300x208.jpg" alt="whichscpt" width="300" height="208" /></a></p>
<p>Assuming that Folder Actions are enabled and the script is set as a Folder Action to your folder, the Automator will run every time a file is copied into the folder.</p>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/01/folderactions.jpg"><img class="alignnone size-medium wp-image-494" title="folderactions" src="http://www.devtrends.com/wp-content/uploads/2010/01/folderactions-300x239.jpg" alt="folderactions" width="300" height="239" /></a></p>
<p><strong>Waiting until ALL Files are Copied</strong></p>
<p>If you copy more than one file at a time into the folder, you will likely run into an issue with this Automator/AppleScript combination where the script will begin before all files are completed copying. This is easily remedied by employing the following script example:</p>
<pre style="padding-left: 30px;">On adding folder items to this_folder after receiving added_items
  If folderReady(this_folder) then
    --((your Automator “tell” line goes here))
  End if
End adding folder items to

On folderReady(tFolder)
  Set myFolder to tFolder as alias
  Set firstSize to size of (info for myFolder)
  Delay 3
  Set newSize to size of (info for myFolder)

  Repeat while newSize ≠ firstSize
    Set firstSize to newSize
    Delay 3
    Set newSize to size of (info for myFolder)
  End repeat

  Return true
End folderReady</pre>
<p><a href="http://www.devtrends.com/wp-content/uploads/2010/01/combinepdfsscpt.jpg"><img class="alignnone size-medium wp-image-492" title="combinepdfsscpt" src="http://www.devtrends.com/wp-content/uploads/2010/01/combinepdfsscpt-300x245.jpg" alt="combinepdfsscpt" width="300" height="245" /></a></p>
<p>This script was taken from an example on <a href="http://macscripter.net/viewtopic.php?id=26564" target="_blank">MacScripter.Net</a>.</p>
<p>Aaron Gilbert</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devtrends.com/index.php/combine-pdfs-in-apple-automator/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Microsoft SteadyState as a Kiosk</title>
		<link>http://www.devtrends.com/index.php/using-microsoft-steadystate-for-a-kiosk/</link>
		<comments>http://www.devtrends.com/index.php/using-microsoft-steadystate-for-a-kiosk/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 17:04:11 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[Kiosk]]></category>
		<category><![CDATA[Windows XP]]></category>
		<category><![CDATA[SteadyState]]></category>

		<guid isPermaLink="false">http://www.devtrends.com/?p=170</guid>
		<description><![CDATA[Making a publicly accessed computer safe can be a challenging project, especially if you are concerned about what web sites are allowed. Although there are quite a few methods for making a kiosk, such as pre-engineered hardware and software, there is always a cheaper method of accomplishing the same task. I am not here to [...]]]></description>
			<content:encoded><![CDATA[<p>Making a publicly accessed computer safe can be a challenging project, especially if you are concerned about what web sites are allowed. Although there are quite a few methods for making a kiosk, such as pre-engineered hardware and software, there is always a cheaper method of accomplishing the same task. I am not here to argue that one is better than the other, only to share my experiences with creating a kiosk using products and knowledge I already had around.</p>
<p>There are a few pieces to the puzzle for any kiosk:</p>
<p>1. computer hardware, preferably equipment that can be physically locked down.<br />
2. user interface restriction software, including Internet access restriction.<br />
3. operating system state lock down.</p>
<p><strong>Piece 1</strong></p>
<p>For piece 1, I have used machines such as a Dell Optiplex and an Intel-based Apple Mac Mini. The Mini was a much better because of the size of the case and limited drives (one CD). For some public areas, I would recommend a physical enclosure for the computer case to prevent any physical access.</p>
<p><strong>Piece 2 and 3</strong></p>
<p>In some cases, the Microsoft <a title="SteadyState" href="http://www.microsoft.com/windows/products/winfamily/sharedaccess/default.mspx" target="_blank">SteadyState</a> product can handle 2 and 3. Prior to SteadyState, step 3 would require an additional product such as <a title="DeepFreeze" href="http://www.faronics.com/html/deepfreeze.asp" target="_blank">DeepFreeze</a> to &#8220;lock&#8221; the operating system state. You might be thinking, can SteadyState stand up to the 13 year old hacker that is going to break into your Kiosk? Unfortunately, I do not have the answer &#8211; however, a quick Google search might help you determine that because DeepFreeze is more popular there are more articles towards cracking it versus SteadyState.</p>
<p>Besides the disk &#8220;freezing&#8221;, SteadyState locks down the operating system using Windows policy configuration. Obviously if the computer is joined to a domain, the group policy objects (GPO) will override similar SteadyState configuration.</p>
<p><strong>More on Piece 3</strong></p>
<p>Controlling web access has been a problem in enterprises for years and a Kiosk is no exception. From a legal standpoint, you can&#8217;t fire outside users of a Kiosk if they do something inappropriate. This means that control of Internet has to be even more restricted, which can be quite difficult.</p>
<p>I would recommend the combination of two applications: (a) using a product such as NetNanny to lock down inappropriate categories; and (b) build a custom web browser such as shown in my article, <a href="http://www.devtrends.com/index.php/creating-a-custom-web-browser/" target="_self">creating your own custom web browser</a> using Microsoft Visual Studio Express 2008. The custom web browser will allow you to control functionality of Internet Explorer programmatically, such as a minimal interface, predefined control bar, et cetera.</p>
<p>As a final note, SteadyState allows the administrator to lock Internet Explorer down to specific web URLs. To save space on domain name restriction, (there is a character limit), use the following format to get the entire domain, *devtrends.com.</p>
<p><a href="http://www.developingtrends.net/wp-content/uploads/2009/11/lockdown.jpg"><img class="alignnone size-medium wp-image-481" title="lockdown" src="http://www.devtrends.com/wp-content/uploads/2009/11/lockdown-300x218.jpg" alt="lockdown" width="300" height="218" /></a></p>
<p>Have fun and do your research before you put a Kiosk out for everyone to use! As with all of my other posts, I am not responsible for your failures and guarantee nothing. Article is for educational purposes only.</p>
<p>-Aaron Gilbert</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devtrends.com/index.php/using-microsoft-steadystate-for-a-kiosk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VCB Backup Script, vcbMounter</title>
		<link>http://www.devtrends.com/index.php/vcb-backup-script-vcbmounter/</link>
		<comments>http://www.devtrends.com/index.php/vcb-backup-script-vcbmounter/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 06:13:22 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[Batch Files]]></category>
		<category><![CDATA[Featured 2]]></category>
		<category><![CDATA[VCB]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[vcbMounter]]></category>
		<category><![CDATA[VMware]]></category>

		<guid isPermaLink="false">http://www.devtrends.com/?p=474</guid>
		<description><![CDATA[Although the VMware Consolidated Backup (VCB) software receives considerable flack for lacking features or functionality, the fact that it provides you with access to the raw VMDK files is enough to alleviate all the missing functionality. As a side note, with Windows VMs, you can also use the vcbMounter program to mount the VM at [...]]]></description>
			<content:encoded><![CDATA[<p>Although the VMware Consolidated Backup (VCB) software receives considerable flack for lacking features or functionality, the fact that it provides you with access to the raw VMDK files is enough to alleviate all the missing functionality. As a side note, with Windows VMs, you can also use the vcbMounter program to mount the VM at a file level &#8212; which eliminates the need for backup client software on the VMs.</p>
<p><strong>Full VMDK Backups</strong></p>
<p>The first thing I&#8217;d like to point out is that the vcbMounter does not &#8220;mount&#8221; the datastore of the VM as one might imagine. When using the vcbMounter program to access the VMDK files, vcbMounter only copies the files to your VCB server. For smaller VMs, 30GB or so, this really isn&#8217;t much of an issue; however, for the larger VMs, say 300GB, this could pose a problem.</p>
<p>At first, you may be frustrated as the vcbMounter program is a quirky program. Unless you are lucky or brilliant, give yourself some time to play with the command options.</p>
<p>For my purposes, I use the following vcbMounter statement:</p>
<pre style="padding-left: 30px;">vcbmounter -h [VC or HOST] -u [USERNAME] -p [PASSWORD] -M 1 -a name:[VM NAME] -r [LOCATION]\%1_vmdk</pre>
<p><strong>vmdkbkp.bat</strong></p>
<p>As expected, I am backing up many VMs; who would have an ESX(i) host with only one VM? (that is an entirely different subject I may address another day). Instead of scheduling the full vcbMounter command with each backup script or scheduled task, I created a batch file I use to extract the VMDK files. If you are interested in my script, <a href="http://www.devtrends.com/downloads/vmdkbkp.zip">download here</a>.</p>
<pre style="padding-left: 30px;">@ECHO OFF
rem ----------------------------------------------------------------
rem Batch file to create a "mount" dump of a VM, as specified in %1.
rem Created, 11/23/2009, Aaron Gilbert, www.devtrends.com
rem
rem Usage: vmdkbkp.bat [server name]
rem  e.g.: vmdkbkp MYSERVERNAMEINESX
rem
rem ----------------------------------------------------------------

rem check to make sure the user supplied an argument
if "%1"=="" goto error

rem format date in yyyy-mm-dd to apply to a directory, use is %today%
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set today=%%c-%%a-%%b)

rem update the path statement so we can use vcbmounter
PATH=%PATH%;"C:\Program Files\VMware\VMware Consolidated Backup Framework\"

rem begin vcbmounter to copy the VMDK files down in file size (no 2GB split)
vcbmounter -h [VC or HOST] -u [USERNAME] -p [PASSWORD] -M 1 -a name:%1 -r [LOCATION]\%1_vmdk_%today%

rem lets finish up without error!
goto done

rem fail...
:error
echo.
echo Please provide one argument in the form of a VM server name, such as MYSERVERNAMEINESX
echo.

rem clean complete
:done</pre>
<p>The batch file requires only one argument, the name of the VM server you wish to backup. I use the batch file in conjunction with a non-traditional vcbMounter &#8220;mounting&#8221; approach. I &#8220;mount&#8221; with the intent of keeping that &#8220;mount&#8221; for an extended period of time. In addition to the vmdkbkp.bat file, I use another batch file to clean out the backup directory of all &#8220;mounted&#8221; directories older than a specific date. This allows me to keep the VMDK files on my backup-to-disk server for multiple weeks, while rotating out the older files.</p>
<pre style="padding-left: 30px;">@ECHO OFF
rem -------------------------------------------------------------
rem Batch file to remove all directories that are older than %1.
rem Created, 11/24/2009, Aaron Gilbert, www.devtrends.com
rem
rem Usage: clndir.bat [negative days]
rem  e.g.: clndir -3
rem
rem -------------------------------------------------------------

rem check to make sure the user supplied an argument
if "%1"=="" goto error

rem clean up the directory from all directories older than 3 days
forfiles.exe /p c:\backup\ /m *.* /d %1 /c "cmd /c if @isdir==TRUE rmdir /s /q @path"

rem lets finish up without error!
goto done

rem fail...
:error
echo.
echo Please provide one argument in the form of a negative number, such as -3
echo.

rem clean complete
:done</pre>
<p>Aaron Gilbert</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devtrends.com/index.php/vcb-backup-script-vcbmounter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux Backup Shell Script</title>
		<link>http://www.devtrends.com/index.php/linux-backup-shell-script/</link>
		<comments>http://www.devtrends.com/index.php/linux-backup-shell-script/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 06:39:39 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[Shell Scripting]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.devtrends.com/?p=467</guid>
		<description><![CDATA[Once again, I am pushing my knowledge limits with the Linux world. The exciting part is that, the deeper I go, the better Linux gets. Today, it is Shell scripting, which quite frankly puts DOS batch files out of business. Wait a moment, which came first?
Onward and upward, today I will share a script I [...]]]></description>
			<content:encoded><![CDATA[<p>Once again, I am pushing my knowledge limits with the Linux world. The exciting part is that, the deeper I go, the better Linux gets. Today, it is Shell scripting, which quite frankly puts DOS batch files out of business. Wait a moment, which came first?</p>
<p>Onward and upward, today I will share a script I use for backing files on my Ubuntu Server. To start off and to help explain what the script does, let me first explain my configuration. I have an ESXi 4.0 server with 3 VMs, all Ubuntu Server instances for Core services (DNS, DHCP, Directory services), Email (Yahoo&#8217;s Zimbra), and File (SAMBA shares, LAMP). All of the servers have 30GB primary partitions, provisioned through VMware and located on an internal 500GB SATA. The File server has a additional partition on the 500GB drive for all SAMBA shares and a partition located on an internal 1TB SATA drive that is used for backup.</p>
<p><a href="http://www.developingtrends.net/wp-content/uploads/2009/11/ESX-network.jpg"><img class="alignnone size-medium wp-image-472" title="ESX network" src="http://www.devtrends.com/wp-content/uploads/2009/11/ESX-network-300x272.jpg" alt="ESX network" width="300" height="272" /></a></p>
<p>The script provides backup functionality for my music, pictures, user&#8217;s folders, et cetera to the backup drive. The secondary partition on the 500GB drive is mounted to /datashare/ and the tertiary partition on the 1TB drive is mounted to /databackup/.</p>
<p><strong>The Script</strong></p>
<pre style="padding-left: 30px;">#!/bin/sh
#####
#  backup files script, version 1.
#
#  this script keeps one tar file per month for 12 months and rsyncs the entire contents
#  to $destination/daily_replica.
#  the idea is to run this script at least once per day to ensure proper sync and monthly tar.
#
#  created by Aaron @ www.devtrends.com
#####

# location of backup files (recursive sub-folders).
backup_files="/datastore/share"

# location to place tar files and /daily_replica/ directory.
destination="/databackup/share"

#### no editing beyong this line is required!
#### function for TARing
funcTar()
{
 options="--create --file="
 echo " -- tar'ing up $1 to $2/$3"
 echo "   \ creating new archive file: $3"
 tar $options$2/$3 $1
 echo "   \ tar backup completed."
}
#### end funcion

#### CREATE MONTHLY TAR FILE
# Create new archive filename.
month=$(date +%m)
year=$(date +%Y)
archive_file="backup-$month.tar"
full_path_archive_file="$destination/$archive_file"

# do I need to create a new monthly archive file?
# check if the file exists
if [ -f $full_path_archive_file ]; then

 # get file date
 filedate=$(stat -c %y $full_path_archive_file)
 # extract only the year of the file
 filedate=${filedate:0:4}

 # check if the file year is not the current year
 if [ ! $filedate == $year ]; then

 # remove old file
 rm $full_path_archive_file
 # create new tar
 funcTar $backup_files $destination $archive_file

 else

 echo " -- no tar'ing required today."

 fi

else

 # create new tar
 funcTar $backup_files $destination $archive_file

fi
#### DONE WITH TAR

#### rsync time...
echo " -- rsync $backup_files to $destination/daily_replica"
rsync -a $backup_files $destination/daily_replica
echo "   \ rsync completed."
####</pre>
<p>If you hate copy and paste, you may download the script <a href="http://www.devtrends.com/downloads/backup_share.zip" target="_blank">here</a>.</p>
<p><strong>Explanation</strong></p>
<p>For those that care, let me explain the script. The first two variables, $backup_files and $destination, should be the only variables you will need to change if you wish to use the script as I do.</p>
<pre style="padding-left: 30px;"># location of backup files (recursive sub-folders).
backup_files="/datastore/share"

# location to place tar files and /daily_replica/ directory.
destination="/databackup/share"</pre>
<p>The next block of code is the function used to create the tar file. The reason I made it into a function is because I use the same block of code twice in the main section of the script. No reason to duplicate code. However, the way I implemented the function may cause a problem if your $backup_files or $destination variables contain spaces. If anyone would like to revised, please share. The $1, $2, et cetera, are the argument variables as passed by the calling statement.</p>
<pre style="padding-left: 30px;">funcTar()
{
 options="--create --file="
 echo " -- tar'ing up $1 to $2/$3"
 echo "   \ creating new archive file: $3"
 tar $options$2/$3 $1
 echo "   \ tar backup completed."
}</pre>
<p>Next I define some variables that I will use throughout the script. The first two are date strings that contain the month (e.g. 11) and the year (e.g. 2009). The third and fourth variables hold the location of the tar file. The tar file name is comprised of the word &#8220;backup-&#8221; and then the variable of the month.</p>
<pre style="padding-left: 30px;">month=$(date +%m)
year=$(date +%Y)
archive_file="backup-$month.tar"
full_path_archive_file="$destination/$archive_file"</pre>
<p>The main section of code is next and consists of a nested if statement. The first if statement checks if a current backup tar file exists, if not, then it will create one, otherwise it will check the status of the current backup tar file. If the current tar file modified date is not in the current year, then it removes that tar file and recreates it, otherwise there is no need to tar anything. The most interesting piece is the substring command, ${filedate:0:4} which only returns characters 0,1,2,3 from the variable $filedate. You will also notice the use of stat, which, depending on your distribution of Linux, you may need to manually acquire.</p>
<pre style="padding-left: 30px;"># do I need to create a new monthly archive file?
# check if the file exists
if [ -f $full_path_archive_file ]; then
 # get file date
 filedate=$(stat -c %y $full_path_archive_file)
 # extract only the year of the file
 filedate=${filedate:0:4}

 # check if the file year is not the current year
 if [ ! $filedate == $year ]; then
  # remove old file
  rm $full_path_archive_file
  # create new tar
  funcTar $backup_files $destination $archive_file
 else
  echo " -- no tar'ing required today."
 fi

else
 # create new tar
 funcTar $backup_files $destination $archive_file
fi</pre>
<p>The last statement is the rsync command which synchronizes the entire content of the $backup_files location to the $destination/daily_replica/ location.</p>
<pre style="padding-left: 30px;">echo " -- rsync $backup_files to $destination/daily_replica"
rsync -a $backup_files $destination/daily_replica
echo "   \ rsync completed."</pre>
<p>Use this script at your own risk. If it turns out it didn&#8217;t back up your stuff, that is entirely your problem, not mine.</p>
<p>-Aaron Gilbert</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devtrends.com/index.php/linux-backup-shell-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheduling Database Backups with SQL Server Express</title>
		<link>http://www.devtrends.com/index.php/scheduling-database-backups-with-sql-server-express/</link>
		<comments>http://www.devtrends.com/index.php/scheduling-database-backups-with-sql-server-express/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 15:02:13 +0000</pubDate>
		<dc:creator>aaron</dc:creator>
				<category><![CDATA[sql express]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Scripts]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.devtrends.com/?p=458</guid>
		<description><![CDATA[In this article I will present a simple way to backup active databases from SQL Express without the need for the SQL Agent or shutting down the SQL Server database engine. For those that are not aware, the SQL Agent is not available with the Express editions of SQL Server. Never-the-less, SQL Express is quite [...]]]></description>
			<content:encoded><![CDATA[<p>In this article I will present a simple way to backup active databases from SQL Express without the need for the SQL Agent or shutting down the SQL Server database engine. For those that are not aware, the SQL Agent is not available with the Express editions of SQL Server. Never-the-less, SQL Express is quite powerful and is more frequently deployed in the enterprise than not, hence the need for third party software backup software/agents or free methods&#8230;such as this one.</p>
<p>This method uses OSQL and an input .sql file containing the SQL commands needed to backup the database(s). If you are unfamilar with the necessary SQL commands to back up a database, we can generate the script from the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=C243A5AE-4BD1-4E3D-94B8-5A0F62BF7796&amp;displaylang=en" target="_blank">SQL Server Management Studio Express </a>application.</p>
<p>1. Use SQL Management Server to script a Backup Job similar to the one below. The method for creating a script instead of performing the actual action is to begin the Backup task and use the &#8220;Script&#8221; button, choose Script Action to File:</p>
<p><a href="http://www.developingtrends.net/wp-content/uploads/2009/11/sql1.jpg"><img class="alignnone size-medium wp-image-461" title="sql1" src="http://www.devtrends.com/wp-content/uploads/2009/11/sql1-300x232.jpg" alt="sql1" width="300" height="232" /></a></p>
<p><a href="http://www.developingtrends.net/wp-content/uploads/2009/11/sql2.jpg"><img class="alignnone size-medium wp-image-462" title="sql2" src="http://www.devtrends.com/wp-content/uploads/2009/11/sql2-300x269.jpg" alt="sql2" width="300" height="269" /></a></p>
<pre style="padding-left: 30px; white-space: pre-wrap; word-wrap: break-word;">BACKUP DATABASE [(database name)] TO  DISK = N'C:\SQL Backups\(file name).bak' WITH NOFORMAT, NOINIT,  NAME = N'(backup name)-Full Database Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
GO</pre>
<p>Save the file to the location where you can find and use the file in the future. In my example, I saved all scripts to the C:\SQL Backups\ folder. If you use my example, make sure you replace the fields marked with () and omit the parentheses.</p>
<p>2. Verify that the SQL Server allows Windows and SQL Authentication. In the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=C243A5AE-4BD1-4E3D-94B8-5A0F62BF7796&amp;displaylang=en" target="_blank">SQL Server Management Studio Express </a>application, right click on the server, choose properties, and then click on the security tab. This change will require a restart of the SQL Server engine.</p>
<p>3. Create a local SQL user with the necessary access to the databases that you will be backing up. In my example I assigned sysadmin to the backup user, which I named SQLBackups.</p>
<p>4. Now we need to create a scheduled job in Windows &#8220;Scheduled Tasks&#8221; to run at the specified time of our choosing. Although you may place the full command in the scheduled task program text box, I would recommend placing the following in a batch file (stored with the .sql file):</p>
<pre style="padding-left: 30px; white-space: pre-wrap; word-wrap: break-word;">@ECHO OFF
del "[FULL PATH TO SQL BACKUP FILE]"
osql -S [SERVER]\[INSTANCE] -U [USERNAME] -P [PASSWORD] -i "[FULL PATH TO SQL FILE]"</pre>
<p>When replacing the values to match your configuration, omit the brackets []. In addition, ensure your have the SERVER\INSTANCE correct.</p>
<p>5. Thats it!</p>
<p>Common Error:</p>
<pre style="padding-left: 30px; white-space: pre-wrap; word-wrap: break-word;">Login failed for user 'SQLBackups'. The user is not associated with a trusted
SQL Server connection.</pre>
<p>You must enable Windows Auth and SQL Auth in server properties and then restart the SQL server service.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devtrends.com/index.php/scheduling-database-backups-with-sql-server-express/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
