<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<rss version="0.91"><channel>
<title>sidefumbling feed</title>
<link>http://www.flobee.net/</link>
<description>Life as an Exchange admin, faith, family, and everything else.</description>
<language>EN</language>
<item>
<title><![CDATA[[Scripts] Exchange 2007 backup script updated to v1.2]]></title>
<description><![CDATA[<p>I added&nbsp;notification of what the checkmark means, automatically load the Exchange snapin if not already, and append the subject of the email with a status summary.&nbsp; If there are no backups that need attention, all okay is added.&nbsp; If there are, it says that attention is needed.&nbsp; This provides a quick way to know if anything needs attention.&nbsp; Download the script <a href="http://www.flobee.net/download/LastBackupReport.zip">here</a>.</p>]]></description>
<date>8/22/2008</date>
<time>10:51:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=166</link>
<id>166</id></item>
<item>
<title><![CDATA[[Scripts] Another minor update to the Exchange 2007 backup script]]></title>
<description><![CDATA[<p>Version 1.11 correctly resets the checkmark status during each loop; when cleared before because no backup has taken place, it remained as a null value for later backups that were successful.&nbsp; Updated version is available <a href="http://www.flobee.net/download/LastBackupReport.zip">here</a>.</p>]]></description>
<date>8/12/2008</date>
<time>4:00:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=165</link>
<id>165</id></item>
<item>
<title><![CDATA[[Scripts] Updated Exchange 2007 database backup script]]></title>
<description><![CDATA[<p>I have made some minor updates to my PowerShell script that reports (and emails) the last backup of each database in your organization.&nbsp; I was referencing the wrong variable when looping through the databases in a storage group, so each storage group in the report listed all the databases on the server.&nbsp; I also change the formatting a little so the text in different table cells in the same row actually look to be in the same row (the checkmark was offsetting that cell a bit).&nbsp; You can download v1.1 <a href="http://www.flobee.net/download/LastBackupReport.zip">here</a>.</p>]]></description>
<date>8/9/2008</date>
<time>6:57:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=164</link>
<id>164</id></item>
<item>
<title><![CDATA[[Exchange] PowerShell script to report last successful full backup of Exchange 2007]]></title>
<description><![CDATA[<p>This script is a port of my <a href="http://www.flobee.net/?view=plink&amp;id=112">original backup report</a> that was written in VBScript.&nbsp; That script reports on both 2003 and 2007 servers, but lacked some of the features that I wanted to put in.&nbsp; PowerShell natively supports date-awareness, which makes it much easier to add the number one feature I wanted to add: highlighting servers that haven't had backups since a specified period of time.</p><p>Because I am using the native Exchange cmdlets instead of WMI or CDOEXM, this only reports on Exchange 2007 servers.&nbsp; I figure accommodating both is more work than it is worth, so I just modified my VBScript version to not include any server in the Exchange 12 admin group and I have both run every day until my migration to 2007 is complete.</p><p>The script reports the last successful full backup of any Exchange 2007 server with the mailbox role installed.&nbsp; It checks for the presence of storage groups and databases within them.&nbsp; It notes if a backup is currently in progress, as well as if a backup has never completed.&nbsp; If a backup has not completed in the last 72 hours (modifiable), it is highlighted in red so it is easy to spot.&nbsp; If a backup is less than the defined number of hours old, I use the Marlett font to display a green checkmark.&nbsp; This allows for a checkmark without having to reference an external image or embed one.&nbsp; Lastly, the report is emailed.&nbsp; The script is shown below, but you can also just <a href="http://www.flobee.net/download/LastBackupReport.zip">download</a> it.</p><code><div class="code">#Last Backup Report for Exchange 2007 servers<br />#Version 1.0 - 7/9/08<br />#--------------------------------------------<br /><br />#Begin customization-------------------------<br />$SmtpServer = "server.domain.com" #Enter FQDN of SMTP server<br />$SmtpFrom = "Exchange Backups <exchangebackupreport@domain.com>" #Enter sender email address<br />$SmtpTo = "user1@domain.com","user2@domain.com" #Enter one or more recipient addresses in an array<br />$SmtpSubject = "Exchange 2007 Last Backup Report" #Enter subject of message<br />$iNomHours = "72" #Enter number of hours since last backup that requires attention<br />#End customization---------------------------<br /><br />$date = Get-Date<br />$sSpace = "&nbsp;&nbsp;&nbsp;&nbsp;"<br />$sOutput = "<table>"<br />#Checkmark to indicate last backup within nominal time<br />$sCheckMark = "<span style=""font-family: Marlett; color: green; font-size: 14pt; font-weight: bold"">a</span>"<br /><br />#Retrieve Exchange servers with mailbox role<br />$ExServer = Get-ExchangeServer | where {$_.IsMailboxServer -eq $True} | Sort-Object Name<br />Foreach ($server in $ExServer)<br />	{<br />	$sOutput += "<tr><td><font size=2><u><b>$server</b></u></font></td><td></td></tr>"<br />	#Retrieve storage groups for a given server<br />	$StorageGroup = $server | Get-StorageGroup | Sort-Object Name<br />	#Check for absence of any storage groups<br />	If (($StorageGroup | Measure-Object Name).Count -eq $null)<br />		{<br />		$sOutput += "<tr><td><font size=2>" + $sSpace + "No storage groups present.</font></td></tr>"<br />		}<br />	Else<br />		{<br />		Foreach ($sg in $StorageGroup)<br />			{<br />			$sOutput += "<tr><td><font size=2>" + $sSpace + $sg.Name + "</font></td></tr>"<br />			#Retrieve mailbox databases for a given storage group<br />			$MailboxDatabase = $StorageGroup | Get-MailboxDatabase -Status | Sort-Object Name<br />			#Check for absence of any databases in storage group<br />			If (($MailboxDatabase | Measure-Object Name).Count -eq $null)<br />				{<br />				$sOutput += "<tr><td><font size=2>" + $sSpace + $sSpace + "No mailbox stores present.</font></td></tr>"<br />				}<br />			Else<br />				{<br />				Foreach ($db in $MailboxDatabase)<br />					{<br />					$sBackupRunning = ""<br />					#Note if backup is currently running<br />					If ($db.BackupInProgress -eq $true)<br />						{$sBackupRunning = "<font size=2 color=blue>(Backup In Progress)</font>"}<br />					#Determine if backup has ever completed<br />					If ($db.LastFullBackup -ne $null)<br />						{<br />						$sBackupDay = $db.LastFullBackup.get_DayofWeek()<br />						$sBackupDateTime = $db.LastFullBackup.ToString("g")<br />						#Flag if last completed backup started longer than defined variable<br />						If (($date - $db.LastFullBackup).TotalHours -gt $iNomHours)<br />							{<br />							$sLastBackup = "<font size=2>Last Backup Started At: <font color=red>" + $sBackupDay + ", " + $sBackupDateTime + "</font></font>"<br />							}<br />						Else<br />							{<br />							$sLastBackup = "<font size=2>Last Backup Started At: " + $sBackupDay + ", " + $sBackupDateTime + " </font>" + $sCheckmark<br />							}<br />						}<br />					Else<br />						{<br />						$sLastBackup = "<font size=2>No full backup has completed yet.</font>"<br />						}<br />					$sOutput += "<tr><td><font size=2>" + $sSpace + $sSpace + $db.Name + " </font></td><td>" + $sLastBackup + $sBackupRunning + "</td></tr>"<br />					}<br />				}<br />			}<br />		}<br />	}<br />$sOutput += "</table>"<br />	<br />#Email results<br />$SmtpClient = New-Object System.Net.Mail.SmtpClient<br />$MailMessage = New-Object System.Net.Mail.MailMessage<br />$SmtpClient.Host = $SmtpServer<br />$MailMessage.From = $SmtpFrom<br />Foreach ($address in $smtpTo)<br />	{$MailMessage.To.Add($address)}<br />$MailMessage.Subject = $SmtpSubject<br />$MailMessage.IsBodyHTML = $true<br />$MailMessage.Body = $sOutput <br />$SmtpClient.Send($MailMessage)  <br /></div></code>]]></description>
<date>7/23/2008</date>
<time>7:28:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=163</link>
<id>163</id></item>
<item>
<title><![CDATA[[Windows Mobile] Pocket Controller skin for AT&T tilt]]></title>
<description><![CDATA[<p>If you use <a target="_blank" href="http://www.soti.net">SOTI</a>'s Pocket Controller Professional to control your Windows Mobile device from your desktop, you know that you can display the screen in a skin and control the virtual hardware buttons&nbsp;in PCP.&nbsp; You can download skins from within PCP, but only during the first year of purchase.&nbsp; They consider the skin catalog a &quot;service.&quot;&nbsp; After the year is up, you have to purchase the application again (at an upgrade price), which includes product upgrades for the year, too.&nbsp; However, PCP hasn't even been updated in a year, so it seems a pretty cheap way to earn revenue, considering SOTI even solicits images from customers to add to the skin catalog.&nbsp; (They used to provide the entire skin catalog free of charge.)</p><p>My work installation is beyond the one year of service, so I couldn't download a skin for my AT&amp;T Tilt.&nbsp; My home installation (separate license), however, was within the service year, so I downloaded the skin and copied it to my work installation.&nbsp; I could not find anything in the program or on SOTI's site regarding copyright of the skin images, so I am posting the Tilt images (displayed half-size) for anyone who needs it.</p><p><a target="_blank" href="http://www.flobee.net/images/ATT-TILT_Vertical.png"><img class="" height="323" alt="Tilt vertical image" width="172" src="http://www.flobee.net/images/ATT-TILT_Vertical.png" /></a></p><p><a target="_blank" href="http://www.flobee.net/images/ATT-TILT_Horizontal.png"><img class="" height="275" alt="Tilt horizontal image" width="321" src="http://www.flobee.net/images/ATT-TILT_Horizontal.png" /></a></p>]]></description>
<date>6/25/2008</date>
<time>10:16:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=162</link>
<id>162</id></item>
<item>
<title><![CDATA[[Exchange] Cannot enter a product key for a 64-bit Exchange 2007 server from the 32-bit management tools]]></title>
<description><![CDATA[<p>The 32-bit version of Exchange 2007 cano be used in a non-production environment only.&nbsp; As such, there is no need to license the product by entering a product key.&nbsp; Doing so will only result in the error &quot;Invalid product key&quot;.</p><p>A side effect of this limitation is that you can also not enter a product key for a valid 64-bit server from a 32-bit installation such as the management tools on a 32-bit OS.&nbsp; I have a PowerShell script that configures a server, depending on the roles that are installed.&nbsp; However, the first thing it does for all servers is apply the product key.&nbsp; This fails because I am running my configuration script from a 32-bit management installation.</p><p>I consider this a bug.&nbsp; The only solution is to run the Set-ExchangeServer command with the -ProductKey parameter on a 64-bit installation of the management tools.</p>]]></description>
<date>6/5/2008</date>
<time>10:42:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=161</link>
<id>161</id></item>
<item>
<title><![CDATA[[Faith] Going to see MercyMe for fourth time.  Woohoo!]]></title>
<description><![CDATA[<p>MercyMe goes to a lot of places for touring, but they don't seem to hit Portland very often.&nbsp; Two of the three times I have gone to see them has been in the metro area, with the other being up in Washington for a county fair.&nbsp; Perhaps this is because Oregon, based on some metric, is the most unchurched state in the country.&nbsp; I like to think that we may have fewer regular Sunday service attendees per capita, but that we make up for it by having a much higher percentage of those who actually have a personal relationship with Jesus.</p><p>This time, Jen and I will be traveling four hours and 270 miles to the booming metropolis of Central Point, where they will be performing with Casting Crowns on July 27.&nbsp; The drive will be worth it since we have seats in Row 2 (!!), which will be the best seats we have ever had seeing them.</p><p>I look forward to seeing them since they are my favorite CCM band, along with Chris Tomlin.&nbsp; And I look forward to Bart's new Hymned album, which he has already recorded and I assume will come out later this year.&nbsp; If you are a poor, lost soul who hasn't had the opportunity to listen to MercyMe, go to their <a target="_blank" href="http://www.mercyme.org">website</a> to hear them, or visit their <a target="_blank" href="http://www.mercyme.org/blog">blog</a> to see how even grown men can be childish at heart.</p>]]></description>
<date>6/2/2008</date>
<time>5:17:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=160</link>
<id>160</id></item>
<item>
<title><![CDATA[[Misc] Replace the starter string on a Ryobi 875r trimmer]]></title>
<description><![CDATA[<p>For the second time since I have owned it, the starter string on my Ryobi multi-attachment trimmer broke.&nbsp; Must be poor design causing too much friction and slowing wearing down the nylon until it frays and breaks.</p><p>One of the difficult parts to remove, if you haven't done it before, is the clutch drum.&nbsp; To do so, you need to remove spark plug and insert a screw driver into the combustion chamber to keep the piston from moving.&nbsp; Then use a Torx 15 driver and insert it into the whole in the front of the drum.&nbsp; Turn the driver&nbsp;counter-clockwise while holding the engine/chassis still to remove the screw holding the drum in place.</p><p>After you remove the springs holding the clutch together, loosen the clutch with a wrench and remove it.&nbsp; Then you can remove the gray plastic cover that houses the starter string, pulley, and spring.&nbsp; When you remove the pulley retaining parts, you can lift out the pulley.&nbsp; You need to be careful when doing so because the spring will uncoil all over the place if you don't reign it in while lifting the pulley out.</p><p>I slowly let the spring uncoil so I can work with the pulley.&nbsp; Now you can replace the broken string.&nbsp; The frustrating part for me at this point&nbsp;was keeping the spring in place while trying to attache the pulley.&nbsp; After several failed attempts, I figured out a better way.&nbsp; I was trying to mount the pulley with the string wound around it, which means that the spring has to be uncoiled a bit.&nbsp; But this leads to the spring not wanting to remain flat when the pulley is being mounted on the shaft.&nbsp; <strong>The better thing to do is to unwind the the starter string so it is fully extended.&nbsp; You can then wind the spring as tight as it will go around the pulley (less one or two revolutions).</strong></p><p><strong>Even though the spring has more potential energy at this point, there is enough friction between each revolution of the spring that it makes it less prone to want to jump off the pulley.</strong>&nbsp; I found it much easier to mount the pulley when the spring is wound tighter around it.</p><p>I hope this trick will help you if you need to replace the starter string on your Ryobi trimmer.</p>]]></description>
<date>5/24/2008</date>
<time>4:22:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=159</link>
<id>159</id></item>
<item>
<title><![CDATA[[Windows Mobile] Upgraded Wizard to 6.1]]></title>
<description><![CDATA[<p>The Faria ROM I have been using for awhile started having issues recently.&nbsp; I was having to soft reset more often (sometimes a couple of times per day), and I couldn't turn on WiFi anymore.&nbsp; Memory would start at about 21MB and slowly work its way down, though a lot of that is probably due to the applications installed.</p><p>So I figured it was time to either reflash with the Faria ROM or use another.&nbsp; I settled on another, discussed <a target="_blank" href="http://forum.xda-developers.com/showthread.php?t=367019">here</a> at XDA Developers.&nbsp; This is a 6.1 ROM, which is nice because of some of the improvements, such as native threaded SMS.&nbsp; I also have more memory after a reset: about 24MB versus 21MB with Faria.&nbsp; Usage feels much snappier, too.&nbsp; I thought that it might simply be because OMAPClock is included, but when I checked it I was still running at 180MHz.&nbsp; So if it feels snappy now, I can't wait to try it at 252MHz, which is what I normally run at.</p><p align="center"><img class="" height="575" alt="HTC Wizard with WinMo 6.1" width="310" src="http://www.flobee.net/images/htcwizard61.png" /></p>]]></description>
<date>3/7/2008</date>
<time>11:52:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=158</link>
<id>158</id></item>
<item>
<title><![CDATA[[Exchange] [Scripts] Convert a mailbox GUID to the user and display name]]></title>
<description><![CDATA[<p>If certain MAPI limits are reached when working with sessions, items, attachments, etc., Exchange will deny further access to that user to that object type.&nbsp; When this happens event ID 9646 is logged in the Application log.&nbsp; The description of the event contains a mailbox GUID that is causing the issue, but the GUID alone does nothing to indicate what user/mailbox is affected.</p><p>Microsoft KB <a target="_blank" href="http://support.microsoft.com/kb/899663">899663</a>&nbsp;instructs how to manually transpose GUID into a format that can be used in an LDAP filter so that you can search for a match.&nbsp; Why do all this by hand when a script can do it for you?&nbsp; I took an existing script I had that already does the transposition and added an AD search to return the matching dn.&nbsp; The dn is passed to a name translation function that converts the dn to the NT4 format (domain\username) and displays the match with username and display name.</p><p>In addition to the VBScript file, I have also included a compiled version that uses SAPIEN Script Host as the engine.&nbsp; This is a self-contained, runs-in-memory-only, no-DOS-box-comes-up engine from PrimalScript.&nbsp; Running the compiled version is nice since you don't have to ensure that CScript is the default host and no DOS box appears while the script is running.</p><p>The zip file with both versions is available on the <a href="http://www.flobee.net/download">download </a>page.</p>]]></description>
<date>2/27/2008</date>
<time>1:39:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=157</link>
<id>157</id></item>
<item>
<title><![CDATA[[OCS] Web component shares cannot use DFS]]></title>
<description><![CDATA[<p>I tried mapping the location of the OCS presentation, metadata, and address book shares using DFS paths, only to get an error in the Create Pool Wizard.&nbsp; The example in the wizard does show \\server\share, but I couldn't imagine that it would be so archaic as to require hard-coded, specific servers in the UNC path.</p><p>The deployment guide doesn't explicitly state that you can or cannot use DFS.&nbsp; It does say that the wizard validates the path by attempting to set permissions, but it doesn't say if it is trying to set share or NTFS permissions.&nbsp; If it is trying to set share permissions, that isn't going to work with DFS.&nbsp; To top it off, there are no log files created during this test, so you can't tell exactly what it is trying to do.</p><p>I resorted to calling Microsoft so I could ask them, and the confirmed that you have to go old-school and use \\server\share mapping.&nbsp; I expressed my dismay at such an antiquated requirement and that it goes against best practices of hard-coding server names.&nbsp; The engineer said that the product group has had several requests from customers to enable support for DFS, so I can only hope it will come in a service pack.</p>]]></description>
<date>1/10/2008</date>
<time>12:16:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=156</link>
<id>156</id></item>
<item>
<title><![CDATA[[Faith] MercyMe: All That Is Within Me]]></title>
<description><![CDATA[<p>My <a target="_blank" href="http://www.mercyme.org">favorite CCM band</a> released a new album a couple weeks ago.&nbsp; I preordered it from <a target="_blank" href="http://www.musicchristian.com">MusicChristian</a> and it arrived on the day of release.&nbsp; I eagerly popped it into the CD player, and like &quot;Coming Up To Breathe&quot;, my first reaction based on Track 1 was that this isn't the band I know and love.&nbsp; &quot;Goodbye Ordinary&quot; is heavier, for them, in electric guitar than I prefer, not to say that I dislike the song altogether.&nbsp; &quot;Time Has Come&quot; starts with a sound that, if I didn't know to whom I was listening, I would think it is Chris Tomlin.&nbsp; Not until &quot;I Know&quot; does MercyMe's traditional sound come through.&nbsp; I like &quot;God With Us&quot; (except the end with the strings), &quot;Sanctified,&quot; &quot;You Reign,&quot; and &quot;Grace Tells Another Story.&quot;&nbsp; &quot;Alright&quot; is a feel-good track with an &quot;Ooh ooh&quot; ditty.&nbsp; I really like the false ending that segues into a tag that is repeated.&nbsp; They have done this on several tracks in the past, and there is just something about when they do that that I really like.&nbsp; Maybe it is to help burn the tag lyrics into your head or practice harmonizing with them.&nbsp; (If the former, it is &quot;Count up your joy when the world comes crashing / Hold your head up and keep on dancing.&quot;)&nbsp; &quot;My Heart Will Fly&quot; continues their sound, but my favorite track is &quot;Finally Home.&quot;&nbsp; Bart Millard has such a beautiful voice that you can just focus on his lyrics and singing.&nbsp; Aside from the electric guitar with its distortion coming through, this is a simple acoustic song, more about telling its story than the music (reminds me of &quot;MawMaw's Song&quot;).&nbsp; I really like the one-voice melody that Bart sings, which progresses into a two-, then three-/ four-, and maybe even five-voice polyphony.</p><p>After listening to the album a number of times, I really enjoy it, and I am glad that I don't judge it based on my first impression of the first track.&nbsp; This was the same with &quot;Coming Up To Breathe,&quot; where repeated listening is what endeared the album to me.&nbsp; Hopefully for their tour they will choose to stop by Portland.&nbsp; Their album tours have not led them this way recently, though they have been to Puyallup for the WWC Fair and to Tualatin with Audio Adrenaline.&nbsp; I have seen them perform three times, so I look forward to the next time.</p>]]></description>
<date>12/3/2007</date>
<time>7:35:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=155</link>
<id>155</id></item>
<item>
<title><![CDATA[[Humor] Funny video that's been sitting in my temp folder]]></title>
<description><![CDATA[<p>This video has been sitting in my temp directory since July, 2005.&nbsp; I figured some day I would get to it, and since I am cleaning my temp directory, that day is today.&nbsp; The video is a clip from an HBO comedy performance where the comedian mimes actions to Natalie Imbruglia's &quot;Torn.&quot;&nbsp; He does it with amazingly smooth transitions from each action to the next, not to mention how he choose to mime certain words.</p><p><!-- begin embedded WindowsMedia file... --><table cellpadding="0" align="center" border="0"><tbody><tr><td><OBJECT id='mediaPlayer' width="320" height="285"      classid='CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95'     codebase='http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701'    standby='Loading Microsoft Windows Media Player components...' type='application/x-oleobject'>     <param name='fileName' value="http://www.flobee.net/media/HollowMen.wmv">      <param name='animationatStart' value='true'>      <param name='transparentatStart' value='true'>     <param name='autoStart' value="false">      <param name='showControls' value="true">      <param name='loop' value="false">     <EMBED type='application/x-mplayer2' pluginspage='http://microsoft.com/windows/mediaplayer/en/download/'        id='mediaPlayer' name='mediaPlayer' displaysize='4' autosize='-1'         bgcolor='darkblue' showcontrols="true" showtracker='-1'        showdisplay='0' showstatusbar='-1' videoborder3d='-1' width="320" height="285"       src="http://www.flobee.net/media/HollowMen.wmv" autostart="false" designtimesp='5311' loop="false">      </EMBED>      </OBJECT></td></tr><!-- ...end embedded WindowsMedia file --><!-- begin link to launch external media player... --><tr><td align="center"><a style="font-size: 85%" target="_blank" href="http://www.flobee.net/media/HollowMen.wmv">Launch in external player</a> <!-- ...end link to launch external media player... --></td></tr></tbody></table></p>]]></description>
<date>10/31/2007</date>
<time>3:15:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=154</link>
<id>154</id></item>
<item>
<title><![CDATA[[Outlook] Finally, a replacement for Lookout, aptly named Lookeen]]></title>
<description><![CDATA[<p>After Microsoft bought Lookout, by far the best Outlook indexer, they incorporated its functionality into Windows Desktop Search.&nbsp; WDS is a horrible app, in my opinion.&nbsp; Microsoft chose to intentionally disallow Lookout as an add-in in Outlook 2007.&nbsp; I have tried other indexers that work with Outlook, but none could compare to the efficient and fast Lookout.&nbsp; I settled on <a target="_blank" href="http://www.caelo.com/products/features.php">Nelson Email Organizer</a> (NEO), which is a standalone application.&nbsp; It does do some nice things, but it just isn't the same.</p><p>A successor to Lookout has found: <a target="_blank" href="http://www.lookeen.net/">Lookeen</a>.&nbsp; Like Lookout, it is a COM add-in just for indexing your mailbox (not a bloated app that also indexes your mailbox).&nbsp; It is very fast, and offers a nice feature that Lookout never did: it display results in a tabbed window, so you can view results by their item type (messages, appointments, contacts, files, etc.).&nbsp; Lookeen is in beta right now, but you can <a target="_blank" href="http://www.lookeen.net/getitnow/index.php">download</a> it and give it a try.&nbsp; I haven't tried any complex searches, but my early results are very positive.</p>]]></description>
<date>10/25/2007</date>
<time>11:20:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=153</link>
<id>153</id></item>
<item>
<title><![CDATA[[Outlook] Limitation using automatic formatting in all versions of Outlook]]></title>
<description><![CDATA[<p>There is a limitation in the use of automatic formatting to control how a message is displayed in a folder's message list.&nbsp; I had been trying to use automatic formatting to change the color of messages in a particular folder if they contain a certain word in the body.&nbsp; I have a rule that moves some daily reports I receive into the folder, and rather than open each report if nothing has changed in the results of the report since it last ran, I wanted to have messages that contain a word that is in them when they have been updated to display differently.&nbsp; This way I can simply delete the reports with unchanged data, but still open them if I want to (which is why I am not using a rule to delete them upon arrival).</p><p>However, the automatic formatting was not being applied to messages that contained the keyword.&nbsp; I tried several different ways within the conditions editor of applying the formatting, all with the same results.&nbsp; I decided to open a case with Microsoft since we have loads of Premier incidents available to use.&nbsp; I had to work through several engineers until I finally got to the Outlook development team who had to look at the source code to determine why it wasn't working.</p><p>That is when they discovered the culprit: a limitation that is by design.&nbsp; When using automatic formatting, only the first 256 characters of the message body will be searched.&nbsp; This is for performance reasons.&nbsp; I couldn't understand why this would be the case since rules will search all of a message body.&nbsp; Then I realized why and it does make sense:&nbsp; Automatic formatting is part of the view for a folder.&nbsp; Views are calculated and applied each time you switch to that folder, so displaying the font face/color/size and bold/italics of each message in the folder list is dynamically applied each time you switch to the folder.&nbsp; The default automatic formatting rules for a folder include unread, overdue, and expired messages, plus group headers, etc.&nbsp; There is definitely a performance risk if Outlook had to search the entire message body of every message in a folder to determine how it should be displayed.&nbsp; To mitigate this, message body searches are limited to 256 characters when part of automatic formatting.</p><p>Rules aren't subject to this limitation because they are one-time processes.&nbsp; Rules are applied only when a message arrives or is sent (or when you manually run one).&nbsp; So the workaround for my issue is to use a rule to search the body for a keyword, assign a category to it if there is a match, and then move it to the folder.&nbsp; I then use automatic formatting to change how a message is displayed if the category is the one I assigned.&nbsp; I have to create a rule for each keyword I am looking for (since I am also looking for reports that have errors), which isn't as efficient as defining multiple automatic formatting rules, but it is an acceptable workaround since the results are the same.</p>]]></description>
<date>8/31/2007</date>
<time>8:56:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=152</link>
<id>152</id></item>
<item>
<title><![CDATA[[Windows Mobile] How to CID Unlock an AKU2 Cingular 8125 (HTC Wizard)]]></title>
<description><![CDATA[<p>Getting WM6 on my Cingular 8125 proved to be a much more vexing challenge than I anticipated, especially considering the development for it over at xda-developers.com.&nbsp; The main issue was getting the 8125 CID Unlocked, which allows non-home carrier ROMs to be installed.&nbsp; Running a multitude of tools to unlock the device resulted in failure but I couldn't figure out why because it was supposed to work, especially on the Wizard.</p><p>Then I found <a target="_blank" href="http://forum.xda-developers.com/showthread.php?t=263116">this</a> post on xda-developers.com which indicates that Wizards that have been upgraded to Windows Mobile 5 with AKU2 (notable for the DirectPush functionality) have the portion of the DOC (Disk on Chip) that stores the carrier ID set to read-only.&nbsp; Faria's instructions show how to successfully CID Unlock the device by first downgrading the ROM to a non-AKU2 version.&nbsp; Of course, it can't be any ROM since the CID is still locked, so it has to be one from Cingular or something cooked.</p><p>I could not find anywhere the Cingular 1.8 ROM that is recommend to use.&nbsp; I trolled Google, AT&amp;T forums, xda-developers, Google Groups, but the binaries had been pulled awhile ago.&nbsp; The other option was a cooked ROM that doesn't check for a carrier ID.&nbsp; Again, I could not find the one mentioned, until I found a forum post that linked to another <a target="_blank" href="http://www.mobismart.net/forums/viewtopic.php?p=4916">post</a> on a French forum where the ROM is available.&nbsp; That took awhile to download.</p><p>After finally having all the pieces necessary, I was able to downgrade this morning, CID Unlock the device, upgrade the IPL/SPL, radio, and finally Faria's WM6 ROM:</p><p align="center"><img width="310" height="575" alt="" src="http://www.flobee.net/images/fariawm6.png" /></p><p align="left">Combining information and steps from a several different topics at xda-developers and elsewhere, this is what I did:</p><ol><li><a target="_blank" href="http://www.mobismart.net/forums/viewtopic.php?p=4916">Downloaded</a> and installed the custom 1.05 ROM, called CUSTOM__RUU_Wizard_1050412_WWE_101_11210_WWE.exe.</li><li><a target="_blank" href="http://forum.xda-developers.com/attachment.php?attachmentid=25702&amp;d=1135865869">Downloaded</a> and ran lokiwiz's CID Unlocker .2b.</li><li><a target="_blank" href="http://rapidshare.com/files/38880130/ruu_prodigy_226102_22610105_022511_tmous_wwe_ship.exe.html">Downloaded</a> and installed the T-Mobile 2.26 ROM.</li><li><a target="_blank" href="http://rapidshare.com/files/23952493/IPL_SPL_3.08.rar.html">Downloaded</a> and installed IPL/SPL 3.08.</li><li><a target="_blank" href="http://www.rapidshare.com/files/17020712/Radio_ROM_2.19.11.rar">Downloaded</a> and installed radio 2.19.</li><li><a target="_blank" href="http://forum.xda-developers.com/showthread.php?t=297762">Downloaded</a> and installed Faria's WM6 ROM.</li></ol><p>Woohoo!</p>]]></description>
<date>8/30/2007</date>
<time>11:23:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=151</link>
<id>151</id></item>
<item>
<title><![CDATA[[Outlook] Add attachment preview handlers for Outlook 2007 in Windows XP]]></title>
<description><![CDATA[<p class="MsoNormal">Outlook 2007 comes with attachment previewers for a few file types, such as txt, but nothing for common attachment types like zip files, pictures, videos, web pages.&nbsp; Outlook 2007 running on Vista comes with more because Vista has attachment previewing inbuilt.&nbsp; I found a tool written by <a target="_blank" href="http://www.azarfamily.org/previewhandlersforwindowsxp">Gil Azar</a>, which he in turn uses some code written by Stephen Toub in <a target="_blank" href="http://msdn.microsoft.com/msdnmag/issues/07/01/PreviewHandlers/default.aspx">MSDN Magazine</a>, that adds attachment previewing for the more common types.</p><p class="MsoNormal">This isn&rsquo;t a difficult installation, but know that it is written by one person who made it available and so there isn&rsquo;t any real support, but when I found an installation issue and emailed Gil with information of what I did to fix it, he promptly replied.</p><ol><li>Download the <a target="_blank" href="http://www.microsoft.com/downloads/details.aspx?familyid=E9D87F37-2ADC-4C32-95B3-B5E3A21BAB2C&amp;displaylang=en">J# 2.0 redistributable package</a> from MS.</li><li>Download the <a target="_blank" href="http://www.azarfamily.org/PrevHandlerPack.exe">previewer installation file</a> from <a target="_blank" href="http://www.azarfamily.org/previewhandlersforwindowsxp">Gil's website</a>.</li><li>Install the J# package.&nbsp; No reboot is necessary and you shouldn't have to exit any programs.</li><li>Exit Outlook if it is running and install the previewer.</li></ol>  <p class="MsoNormal">One bug I have found is that if you try and run a file from within a previewed zip file whose type isn&rsquo;t registered in Windows, you will get an error (such as a file with no extension).&nbsp; Outlook won&rsquo;t crash or anything, but you will have to save the zip file to disk in order to do something with the unknown file type.</p><p>These are the combined (Gil's and Stephen's) file types it will preview:</p><ul><li><strong>PDF</strong> - This handler uses Adobe Reader's ActiveX control</li><li><strong>SWF</strong> - This handler uses Adobe Shockwave Flash's<strong> </strong>ActiveX control.</li><li><strong>HTML/HTM/XML</strong> - This handler uses Internet Explorer's ActiveX control.</li><li><strong>ASF/WMV/WMA/AVI/WAV/MPG/MPEG/MP3/MIDI/AIFF/AU</strong> - The same, but with Windows Media Player's ActiveX control.</li><li><strong>ZIP/GADGET/MSI/RESX/SNK/KEYS</strong> &ndash; Not implemented natively, but only forwards interface calls to Stephen Toub's managed preview handlers.</li><li><strong>CS/VB/SQL/JS</strong> - Like the previous group, not natively implemented, but added to a wrapper.</li></ul>]]></description>
<date>8/28/2007</date>
<time>8:37:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=150</link>
<id>150</id></item>
<item>
<title><![CDATA[[Exchange] Script to format an LDAP filter for readability]]></title>
<description><![CDATA[<p>I have automated DLs that use LDAP filters for&nbsp;membership criteria.&nbsp; These filters are stored as binary data in the extensionData attribute of the group object, so they are not easily accessible by users who want to know what filter is being applied to a DL they own.</p> <p>It was easy enough to extract the LDAP filter from the attribute, convert it to a string value, and display it.&nbsp; But users don't generally know how to read LDAP filters, let alone represented as a long line of text.&nbsp; So I started looking for utilities or scripts that would take an LDAP filter, parse it, and display it with nesting.&nbsp; Uh, yeah, there aren't any.&nbsp; I was determined, and so countless hours later I have a function that do such a thing.</p> <p>The difficult part was keeping traffic of the level of nesting/indentation at any point.&nbsp; Since a filter can be written in almost any order as long as the resulting equation equals what you want, I couldn't use any kind of static detection.&nbsp; Just because an open parentheses is following by another one doesn't mean that you are, say, three levels nested.&nbsp; So the important part of the script keeps track of the indentation level as the cursor position moves through the filter.</p> <p>I replace ampersands in the filter with crosshatches while working with it because I was having weird results otherwise, most likely because the ampersand is an operator in both LDAP and VBScript.&nbsp; And because the output is to an IE window and the indentation uses non-breaking spaces instead of the traditional tab (which doesn't exist in HTML), I substitute the HTML string for a non-breaking space with a unique string of letters so the ampersand in that doesn't get in the way.</p> <p>Because this is part of a bigger script, I pulled out just the portion that formats the LDAP filter and displays it in an IE window.&nbsp; You just need to provide the &quot;raw&quot; filter, whether directly in the script or some other method.&nbsp; Copy and paste the code below or download it <a href="http://www.flobee.net/download/ParseLDAPFilter.zip" title="Parse LDAP filter for readbility">here</a>.</p> <p>Code:&nbsp;&nbsp;<a onclick="toggleField('code0808', true)" alt="Show code" style="cursor: pointer;"><font color="#008000"><u>Show</u></font></a>&nbsp;&nbsp;<a onClick="toggleField('code0808', false)" alt="Hide code" style="cursor: pointer;"><font color="#008000"><u>Hide</u></font></a></p> <div name="code0808" style="display: none;" id="code0808"><div class="code"><p>Option Explicit</p> <p>Dim strLDAPFilter, strFormattedFilter<br /> Dim objIE, objDoc<br /> strLDAPFilter = &quot;YourLDAPFilter&quot;</p> <p>&nbsp;&nbsp;Set objIE = CreateObject(&quot;InternetExplorer.Application&quot;)<br /> &nbsp;&nbsp;objIE.AddressBar = False<br /> &nbsp;&nbsp;objIE.Menubar = False<br /> &nbsp;&nbsp;objIE.Toolbar = False<br /> &nbsp;&nbsp;objIE.Resizable = True<br /> &nbsp;&nbsp;objIE.Height = 450<br /> &nbsp;&nbsp;objIE.Width = 700<br /> &nbsp;&nbsp;objIE.Visible = True<br /> &nbsp;&nbsp;objIE.Navigate(&quot;about:blank&quot;)<br /> &nbsp;&nbsp;While objIE.Busy<br /> &nbsp;&nbsp;&nbsp;&nbsp; WScript.Sleep 100<br /> &nbsp;&nbsp;Wend<br /> &nbsp;&nbsp;<br /> &nbsp;&nbsp;Set objDoc = objIE.Document<br /> &nbsp;&nbsp;objDoc.Open<br /> &nbsp;&nbsp;objDoc.Write(&quot;&lt;TITLE&gt;LDAP Filter Display&lt;/TITLE&gt;&quot;)<br /> &nbsp;&nbsp;objDoc.Write(&quot;&lt;BODY BGCOLOR=#C0C0C0&gt;&quot;)<br /> &nbsp;<br /> &nbsp;<br /> 'Parse the LDAP filter and format results for display</p> <p>'Apply nesting for readability<br /> strFormattedFilter = FormatLDAPDisplay(strLDAPFilter)</p> <p>objDoc.Write(strFormattedFilter)</p> <p>'Format single-line LDAP filter to include nesting<br /> Function FormatLDAPDisplay(strLDAPFilter)<br /> &nbsp;'Replace ampersands with crosshatches to keep them from interfering<br /> &nbsp;strLDAPFilter = Replace(strLDAPFilter, Chr(38), Chr(35))<br /> &nbsp;<br /> &nbsp;'Iterate through each character in filter and insert CRLF and nesting<br /> &nbsp;Dim intPos, intIndentCount, intWhileIndent<br /> &nbsp;Dim strIndentation, strInsert, strCharacter, strNewLDAPFilter<br /> &nbsp;Dim bolDblClose<br /> &nbsp;intPos = 1<br /> &nbsp;intIndentCount = 0<br /> &nbsp;Do While intPos &lt; Len(strLDAPFilter)<br /> &nbsp;&nbsp;strCharacter = Mid(strLDAPFilter, intPos, 1)<br /> &nbsp;&nbsp;intWhileIndent = 1<br /> &nbsp;&nbsp;strIndentation = &quot;&quot;<br /> &nbsp;&nbsp;Select Case strCharacter<br /> &nbsp;&nbsp;&nbsp;'LDAP operators to watch for to modify nesting level.<br /> &nbsp;&nbsp;&nbsp;'NOT operator ignored because only used in one-off attribute value<br /> &nbsp;&nbsp;&nbsp;Case Chr(35), Chr(124)<br /> &nbsp;&nbsp;&nbsp;&nbsp;'Operator followed by open paren means nesting increase<br /> &nbsp;&nbsp;&nbsp;&nbsp;If Mid(strLDAPFilter, intPos + 1, 1) = Chr(40) Then<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intIndentCount = intIndentCount + 1<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'Build nest based on number of indentations<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do While intWhileIndent &lt;= intIndentCount<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'Use unique string as placeholder for nesting with HTML spaces<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strIndentation = strIndentation &amp; &quot;QZNBSPQZNBSPQZNBSPQZNBSP&quot;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intWhileIndent = intWhileIndent + 1<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loop<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'Insert new string for formatting<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strNewLDAPFilter = Replace(strLDAPFilter, strCharacter, strCharacter &amp; &quot;&lt;br&gt;&quot; &amp; strIndentation, intPos, 1)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'Restore full filter including new string<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strLDAPFilter = Left(strLDAPFilter, intPos - 1) &amp; strNewLDAPFilter<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'Move current position to next character after inserted string<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intPos = intPos + Len(strIndentation) + 6<br /> &nbsp;&nbsp;&nbsp;&nbsp;Else<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intPos = intPos + 1<br /> &nbsp;&nbsp;&nbsp;&nbsp;End If<br /> &nbsp;&nbsp;&nbsp;Case Chr(40)<br /> &nbsp;&nbsp;&nbsp;&nbsp;Do While intWhileIndent &lt;= intIndentCount<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strIndentation = &quot;QZNBSPQZNBSPQZNBSPQZNBSP&quot; &amp; strIndentation<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intWhileIndent = intWhileIndent + 1<br /> &nbsp;&nbsp;&nbsp;&nbsp;Loop<br /> &nbsp;&nbsp;&nbsp;&nbsp;If Not strIndentation = &quot;&quot; Then<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'If open paren follows close paren, insert CRLF<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If Mid(strLDAPFilter, intPos - 1, 1) = Chr(41) Then<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strIndentation = strIndentation &amp; &quot;&lt;br&gt;&quot;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strNewLDAPFilter = Replace(strLDAPFilter, strCharacter, strIndentation &amp; strCharacter, intPos, 1)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strLDAPFilter = Left(strLDAPFilter, intPos - 1) &amp; strNewLDAPFilter<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intPos = intPos + Len(strIndentation) +1<br /> &nbsp;&nbsp;&nbsp;&nbsp;Else<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intPos = intPos + 1<br /> &nbsp;&nbsp;&nbsp;&nbsp;End If<br /> &nbsp;&nbsp;&nbsp;Case Chr(41)<br /> &nbsp;&nbsp;&nbsp;&nbsp;'Two consecutive close paren means nesting reduces one level<br /> &nbsp;&nbsp;&nbsp;&nbsp;If Mid(strLDAPFilter, intPos + 1, 1) = Chr(41) Then<br /> &nbsp;&nbsp;&nbsp;&nbsp;intIndentCount = intIndentCount - 1<br /> &nbsp;&nbsp;&nbsp;&nbsp;bolDblClose = True<br /> &nbsp;&nbsp;&nbsp;&nbsp;End If<br /> &nbsp;&nbsp;&nbsp;&nbsp;Do While intWhileIndent &lt;= intIndentCount<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strIndentation = strIndentation &amp; &quot;QZNBSPQZNBSPQZNBSPQZNBSP&quot;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intWhileIndent = intWhileIndent + 1<br /> &nbsp;&nbsp;&nbsp;&nbsp;Loop<br /> &nbsp;&nbsp;&nbsp;&nbsp;strNewLDAPFilter = Replace(strLDAPFilter, strCharacter, strCharacter &amp; &quot;&lt;br&gt;&quot; &amp; strIndentation, intPos, 1)<br /> &nbsp;&nbsp;&nbsp;&nbsp;strLDAPFilter = Left(strLDAPFilter, intPos - 1) &amp; strNewLDAPFilter<br /> &nbsp;&nbsp;&nbsp;&nbsp;'Adjust position to account for two close paren<br /> &nbsp;&nbsp;&nbsp;&nbsp;If bolDblClose = True Then<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intPos = intPos + Len(strIndentation) + 5<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bolDblClose = Empty<br /> &nbsp;&nbsp;&nbsp;&nbsp;Else<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intPos = intPos + Len(strIndentation) + 6<br /> &nbsp;&nbsp;&nbsp;&nbsp;End If<br /> &nbsp;&nbsp;&nbsp;Case Else<br /> &nbsp;&nbsp;&nbsp;&nbsp;'No paren or operator means move to next character<br /> &nbsp;&nbsp;&nbsp;&nbsp;intPos = intPos + 1<br /> &nbsp;&nbsp;End Select<br /> &nbsp;Loop<br /> &nbsp;&nbsp;&nbsp;<br /> 'Replace LDAP operators with words<br /> strLDAPFilter = Replace(strLDAPFilter, Chr(35), &quot;&lt;i&gt;AND&lt;/i&gt;&quot;)<br /> strLDAPFilter = Replace(strLDAPFilter, Chr(124), &quot;&lt;i&gt;OR&lt;/i&gt;&quot;)<br /> strLDAPFilter = Replace(strLDAPFilter, Chr(33), &quot;&lt;i&gt;NOT &lt;/i&gt;&quot;)</p> <p>'Replace spaceholders with HTML spaces<br /> strLDAPFilter = Replace(strLDAPFilter, &quot;QZNBSP&quot;, Chr(38) &amp; &quot;nbsp;&quot;)</p> <p>FormatLDAPDisplay = strLDAPFilter<br /> End Function</p> <p>Set objIE = Nothing</p></div></div>]]></description>
<date>8/8/2007</date>
<time>7:32:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=149</link>
<id>149</id></item>
<item>
<title><![CDATA[[Web] Add comment notification to simplebog 3.0]]></title>
<description><![CDATA[<p>Since I am using approval for comments on my site, I had no way of knowing when someone posted a comment pending approval.&nbsp; And since you can't simply look for comments to posts without going into the database directly, I needed a way to know when someone has posted a comment and to which post it belongs.</p><p>To do this, add this subroutine to the end of functions.asp, which is the CDO code to send a message.&nbsp; I didn't use variables that are assigned in config.asp, so you will have to set them in the subroutine directly for SMTP server, from address, to address, and domain name in the body.&nbsp;</p><div class="code">&lt;%'Send comment notification<br />Sub SendEmail (strBDate, strBID)<br />&nbsp;&nbsp;&nbsp; Dim objMail<br />&nbsp;&nbsp;&nbsp; Set objMail = CreateObject(&quot;CDO.Message&quot;)<br />&nbsp;&nbsp;&nbsp; objMail.Configuration.Fields.Item (&quot;http://schemas.microsoft.com/cdo/configuration/sendusing&quot;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 2<br />&nbsp;&nbsp;&nbsp; objMail.Configuration.Fields.Item (&quot;http://schemas.microsoft.com/cdo/configuration/smtpserver&quot;)&nbsp;&nbsp;&nbsp;&nbsp; = &quot;SMTP hostname&quot;<br />&nbsp;&nbsp;&nbsp; objMail.Configuration.Fields.Item (&quot;http://schemas.microsoft.com/cdo/configuration/smtpserverport&quot;) = 25<br />&nbsp;&nbsp;&nbsp; objMail.Configuration.Fields.Update<br /><br />&nbsp;&nbsp;&nbsp; objMail.From&nbsp;&nbsp;&nbsp;&nbsp; = &quot;fromaddress@yourdomain.com&quot;<br />&nbsp;&nbsp;&nbsp; objMail.To&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = &quot;toaddress@yourdomain.com&quot;<br />&nbsp;&nbsp;&nbsp; objMail.Subject&nbsp; = &quot;Comment has been submitted for approval&quot;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; objMail.HTMLBody = &quot;A comment has been submitted for approval.&nbsp; Go to http://www.yourdomain.com/admin?cmd=bloglist&amp;view=calendar&amp;blogDate=&quot; &amp; strBDate &amp; &quot;&amp;comments=&quot; &amp; strBID &amp; &quot; to approve.&quot;<br />&nbsp;&nbsp;&nbsp; objMail.Send<br />&nbsp; &nbsp;&nbsp;&nbsp; Set objMail = Nothing<br />End Sub<br />%&gt;</div><p>&nbsp;Then you need to add code to functions.asp to call this subroutine from the subroutine that inserts the comment.&nbsp; Find the subroutine labeled InsertComment(), which should be around line 475 depending on other mods of mine or your own that you may have inserted.&nbsp; Right before the existing line:&nbsp;</p><div class="code">Response.Redirect(&quot;default.asp?view=plink&amp;id=&quot; &amp; bID &amp; &quot;&amp;comments=1&quot;)</div><p>&nbsp;insert this code:&nbsp;</p><div class="code">' convert blog ID to blog Date<br />&nbsp;&nbsp;&nbsp; strSQL = &quot;SELECT * FROM&nbsp; T_WEBLOG WHERE id = &quot; &amp; bID &amp; &quot; ORDER BY id DESC&quot;<br />&nbsp;&nbsp;&nbsp; Set Rs = Server.CreateObject(&quot;ADODB.Recordset&quot;)<br />&nbsp;&nbsp;&nbsp; Rs.ActiveConnection = strConn<br />&nbsp;&nbsp;&nbsp; Rs.Source = strSQL<br />&nbsp;&nbsp;&nbsp; Rs.CursorType = 0<br />&nbsp;&nbsp;&nbsp; Rs.CursorLocation = 2<br />&nbsp;&nbsp;&nbsp; Rs.LockType = 1<br />&nbsp;&nbsp;&nbsp; Rs.Open()<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; If Not rs.EOF Then<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rs.MoveFirst<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; While Not rs.EOF<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; strBDate = rs(&quot;b_date&quot;)<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rs.MoveNext<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Wend<br />&nbsp;&nbsp;&nbsp; End If<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; SendEmail strBDate, bID</div><p>&nbsp;This is necessary because the comments are not accessed by using the blog entry ID, but the blog entry's date.&nbsp; So it is necessary to cross-reference the entry ID to the entry date, and then link to the comments for a given entry ID on that date.&nbsp; The last line calls the email function which will include a hyperlink to the comments for the blog entry that has a new comment.</p><p>Now, that is all fine and dandy.&nbsp; You will receive the email with the link, but when you follow it to your site, you probably won't have an active session so you will have to log in.&nbsp; The way the admin default and login pages work, you will lose the link to the entry you need to approve so you have to click the link in the email again.&nbsp; I work around this by implementing the use of query strings so the site remembers where you were trying to go before you had to log in.</p><p>To add this feature, edit admindefault.asp.&nbsp; At line 8, replace the Response.Redirect line with the following code:&nbsp;</p><div class="code">&nbsp;&nbsp;&nbsp; Dim sProtocol, sDomain, sPath, sQuerystring, sResult<br />&nbsp;&nbsp;&nbsp; sProtocol = &quot;http://&quot;<br />&nbsp;&nbsp;&nbsp; If UCase(Request.ServerVariables(&quot;HTTPS&quot;)) = &quot;ON&quot; Then sProtocol = &quot;https://&quot;<br />&nbsp;&nbsp;&nbsp; sDomain = LCase(Request.ServerVariables(&quot;SERVER_NAME&quot;))<br />&nbsp;&nbsp;&nbsp; sPath = LCase(Request.ServerVariables(&quot;SCRIPT_NAME&quot;))<br />&nbsp;&nbsp;&nbsp; sQuerystring = LCase(Request.Querystring)<br />&nbsp;&nbsp;&nbsp; sResult = sProtocol &amp; sDomain &amp; sPath<br />&nbsp;&nbsp;&nbsp; If Len(sQuerystring) &gt; 0 Then sResult = sResult &amp; &quot;?&quot; &amp; sQuerystring<br />&nbsp;&nbsp;&nbsp; sResult = Server.URLEncode(sResult)<br /><br />&nbsp;&nbsp;&nbsp; Response.Redirect(&quot;login.asp&quot;) &amp; &quot;?sURL=&quot; &amp; sResult</div><p>&nbsp;This builds a query string of the URL you were going to go to before you are redirected to the login page.&nbsp; Now edit adminlogin.asp.&nbsp; At line 34, before the If statement to check for a postback, insert the following line:&nbsp;</p><div class="code">strSourceURL = Request.QueryString(&quot;sURL&quot;)</div><p>&nbsp;This retrieves the query string and puts it into a variable.&nbsp; At line 39, before the SQL statement to select the users from the database, insert the following code:&nbsp;</p><div class="code">If Not Trim(Request.Form(&quot;sourceURL&quot;)) = &quot;&quot; Then<br />&nbsp;&nbsp;&nbsp; strSourceURL = Request.Form(&quot;sourceURL&quot;)<br />Else<br />&nbsp;&nbsp;&nbsp; strSourceURL = &quot;./?&quot;<br />End If</div><p>&nbsp;This extra code is added to accommodate you entering a bad password or if you are logging in without following a comment link.&nbsp; At line 74, comment out Johann's Response.Redirect line after a successful login and then insert and replace the Response.Redirect for no user found with this:&nbsp;</p><div class="code">Response.Redirect(strSourceURL)<br />else<br />response.Redirect(&quot;login.asp?error=nouser&quot;) &amp; &quot;&amp;sURL=&quot; &amp; Server.URLEncode(strSourceURL)</div><p>&nbsp;This sends you to the page you were intending to go to in the first place.&nbsp; If you entered a bad password, this also preserves the original URL after the login page reloads.</p><p>Last, but not least, you need to a hidden form field that will store the original URL when you submit the form to log in.&nbsp; Near the end of the file, insert a line before the close form tag and paste this:&nbsp;</p><div class="code">&lt;input name=&quot;sourceURL&quot; type=&quot;hidden&quot; value=&quot;&lt;%= strSourceURL %&gt;&quot; /&gt;</div><p>&nbsp;I hope that's not too complicated to follow.&nbsp; It's a little more convoluted for this modification because it is necessary to add code in multiple places in multiple files, rather than just a chunk of code in one file.&nbsp; But, now you will receive an email when a comment is posted and be easily able to approve or deny the comment just by following the link in the email.</p>]]></description>
<date>7/31/2007</date>
<time>11:52:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=148</link>
<id>148</id></item>
<item>
<title><![CDATA[[Exchange] Updated: Copy DLs from one user to another]]></title>
<description><![CDATA[<p>The first version of the script really was quick and dirty, requiring you to manually put the source and target users' DNs in the script.&nbsp; Since a coworker has been using the script, I thought it appropriate to update it to prompt for the usernames.&nbsp; In addition, I added a new feature I recently read about, which is to output the results in real-time to a GUI.&nbsp; This is done by creating an object for IE and writing the output similar to wscript.echo, but with the Write method of the object.</p> <p>Like the original script, since we use automated DLs, too, I look for an indication that a given DL is a SmartDL and skip it.&nbsp; And I now use PrimalScript to work with my scripts, so I use its packager to make an exectuable.&nbsp; This makes it easier and nicer for non-IT end-users who will be running scripts like these.</p> <p>Download it <a href="http://www.flobee.net/download/CopyDLMembership.zip">here</a>, or copy/paste below.</p> <p>Code:&nbsp;&nbsp;<a style="cursor: pointer;" alt="Show code" onclick="toggleField('code0723', true)"><font color="#000099"><u>Show</u></font></a>&nbsp;&nbsp;<a style="cursor: pointer;" alt="Hide code" onClick="toggleField('code0723', false)"><font color="#000099"><u>Hide</u></font></a></p> <p>&nbsp;</p> <div style="display: none;" name="code0723" id="code0723"><div class="code">'Version 2.0 - July 23, 2007<br /> 'Copy distribution group membership from one user to another,<br /> 'excluding automated DLs (SmartDL).<br /> <br /> 'Get source user<br /> While Not bolExit = True<br /> &nbsp;&nbsp; &nbsp;strOldSamUser = InputBox(&quot;Enter the sAMAccountName of the person to copy DLs FROM.&quot; _<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;, &quot;Enter username&quot;)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;If strOldSamUser = &quot;&quot; Then<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;WScript.Quit<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;End If<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br /> &nbsp;&nbsp; &nbsp;'Find the Global Catalog server<br /> &nbsp;&nbsp; &nbsp;Set objCont = GetObject(&quot;GC:&quot;)<br /> &nbsp;&nbsp; &nbsp;For Each objGC In objCont<br /> &nbsp;&nbsp; &nbsp;&nbsp; strADsPath = objGC.ADsPath<br /> &nbsp;&nbsp; &nbsp;Next<br /> &nbsp;&nbsp; &nbsp;<br /> &nbsp;&nbsp; &nbsp;Set objConnection = CreateObject(&quot;ADODB.Connection&quot;)<br /> &nbsp;&nbsp; &nbsp;Set objRecordset = CreateObject(&quot;ADODB.Recordset&quot;)<br /> &nbsp;&nbsp; &nbsp;objConnection.Provider = &quot;ADsDSOObject&quot;<br /> &nbsp;&nbsp; &nbsp;<br /> &nbsp;&nbsp; &nbsp;objConnection.Open &quot;ADs Provider&quot;<br /> &nbsp;&nbsp; &nbsp;strQuery = &quot;&lt;&quot; &amp; strADsPath &amp; &quot;&gt;;(&amp;(objectcategory=user)(sAMAccountName=&quot; &amp; strOldSamUser &amp; _<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &quot;));displayName,distinguishedName;subtree&quot;<br /> &nbsp;&nbsp; &nbsp;Set objRecordset = objConnection.Execute(strQuery)<br /> &nbsp;&nbsp; &nbsp;<br /> &nbsp;&nbsp; &nbsp;If Trim(objRecordset.Fields(&quot;distinguishedName&quot;)) = &quot;&quot; Then<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;strNoUser = MsgBox(&quot;Warning: User cannot be found.&nbsp; Verify sAMAccountName.&quot;, vbCritical, &quot;User not found!&quot;)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;bolExit = False<br /> &nbsp;&nbsp; &nbsp;Else<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;intCorrectUser = MsgBox(&quot;Is this the correct user?&quot; &amp; VbCrLf &amp; VbCrLf &amp; &quot;Display Name: &quot; &amp; _<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;objRecordset.Fields(&quot;displayName&quot;) &amp; VbCrLf &amp; &quot;DN: &quot; &amp; objRecordset.Fields(&quot;distinguishedName&quot;), _<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;vbYesNo, &quot;Old user?&quot;)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;If intCorrectUser &lt;&gt; 6 Then<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;bolExit = False<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Else<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;strSrcDN = objRecordset.Fields(&quot;distinguishedName&quot;)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;bolExit = True<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;End If<br /> &nbsp;&nbsp; &nbsp;End If<br /> Wend<br /> <br /> 'Open IE to display progress and results<br /> Set objIE = CreateObject(&quot;InternetExplorer.Application&quot;)<br /> objIE.AddressBar = False<br /> objIE.Menubar = False<br /> objIE.Toolbar = False<br /> objIE.Resizable = True<br /> objIE.Left = 10<br /> objIE.Height = 450<br /> objIE.Width = 800<br /> objIE.Visible = True<br /> objIE.Navigate(&quot;about:blank&quot;)<br /> While objIE.Busy<br /> &nbsp;&nbsp; WScript.Sleep 100<br /> Wend<br /> <br /> Set objDoc = objIE.Document<br /> objDoc.Open<br /> objDoc.Write(&quot;&lt;TITLE&gt;Copy DL Membership&lt;/TITLE&gt;&quot;)<br /> objDoc.Write(&quot;&lt;BODY BGCOLOR=#C0C0C0&gt;&quot;)<br /> objDoc.Write(&quot;&lt;P&gt;&lt;b&gt;Source:&lt;/b&gt; &quot; &amp; objRecordset.Fields(&quot;distinguishedName&quot;) &amp; &quot;&lt;br&gt;&quot;)<br /> <br /> 'Get target user<br /> bolExit = False<br /> While Not bolExit = True<br /> &nbsp;&nbsp; &nbsp;strNewSamUser = InputBox(&quot;Enter the sAMAccountName of the person to copy DLs TO.&quot; _<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;, &quot;Enter username&quot;)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;If strNewSamUser = &quot;&quot; Then<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;objIE.Quit<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;WScript.Quit<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;End If<br /> <br /> &nbsp;&nbsp; &nbsp;strQuery = &quot;&lt;&quot; &amp; strADsPath &amp; &quot;&gt;;(&amp;(objectcategory=user)(sAMAccountName=&quot; &amp; strNewSamUser &amp; _<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &quot;));displayName,distinguishedName;subtree&quot;<br /> &nbsp;&nbsp; &nbsp;Set objRecordset = objConnection.Execute(strQuery)<br /> &nbsp;&nbsp; &nbsp;<br /> &nbsp;&nbsp; &nbsp;If Trim(objRecordset.Fields(&quot;distinguishedName&quot;)) = &quot;&quot; Then<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;strNoUser = MsgBox(&quot;Warning: User cannot be found.&nbsp; Verify sAMAccountName.&quot;, vbCritical, &quot;User not found!&quot;)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;bolExit = False<br /> &nbsp;&nbsp; &nbsp;Else<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;intCorrectUser = MsgBox(&quot;Is this the correct user?&quot; &amp; VbCrLf &amp; VbCrLf &amp; &quot;Display Name: &quot; &amp; _<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;objRecordset.Fields(&quot;displayName&quot;) &amp; VbCrLf &amp; &quot;DN: &quot; &amp; objRecordset.Fields(&quot;distinguishedName&quot;), _<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;vbYesNo, &quot;Old user?&quot;)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;If intCorrectUser &lt;&gt; 6 Then<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;bolExit = False<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Else<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Set objTargetUser = GetObject(&quot;LDAP://&quot; &amp; objRecordset.Fields(&quot;distinguishedName&quot;))<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;bolExit = True<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;End If<br /> &nbsp;&nbsp; &nbsp;End If<br /> Wend<br /> <br /> 'Write target user to IE window<br /> objDoc.Write(&quot;&lt;b&gt;Target:&lt;/b&gt; &quot; &amp; objRecordset.Fields(&quot;distinguishedName&quot;) &amp; &quot;&lt;/P&gt;&quot;)<br /> <br /> 'Copy DLs<br /> strDomFQDN = Mid(strSrcDN, InStr(LCase(strSrcDN), &quot;,dc=&quot;) + 4)<br /> strGCFQDN = Replace(LCase(strDomFQDN), &quot;,dc=&quot;, &quot;.&quot;)<br /> Set objOldUser = GetObject(&quot;GC://&quot; &amp; strGCFQDN &amp; &quot;/&quot; &amp; strSrcDN)<br /> For Each strGroup in objOldUser.MemberOf<br /> &nbsp;&nbsp; &nbsp;On Error Resume Next&nbsp;&nbsp; &nbsp;<br /> &nbsp;&nbsp; &nbsp;Set objGroup = GetObject(&quot;LDAP://&quot; &amp; strGroup)<br /> &nbsp;&nbsp; &nbsp;If Not Trim(objGroup.mailNickname) = &quot;&quot; Then<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;If Not Instr(objGroup.info, &quot;SmartDL&quot;) &gt; 0 Then<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;objGroup.Add(objTargetUser.ADsPath)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;If Err.Number = 0 Then<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;objDoc.Write(objGroup.DisplayName &amp; &quot;: Update successful.&lt;br&gt;&quot;)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Else<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;objDoc.Write(objGroup.DisplayName &amp; &quot;: Update UNSUCCESSFUL.&lt;br&gt;&quot;)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;End If<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Else<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;objDoc.Write(objGroup.DisplayName &amp; &quot;: Skipped (SmartDL).&lt;br&gt;&quot;)<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;End If<br /> &nbsp;&nbsp; &nbsp;End If<br /> &nbsp;&nbsp; &nbsp;On Error Goto 0<br /> Next<br /> <br /> Set objOldUser = Nothing<br /> Set objTargetUser = Nothing<br /> Set objIE = Nothing<br /> Set objRecordset = Nothing<br /> Set objConnection = Nothing</div></div> <p>&nbsp;</p>]]></description>
<date>7/23/2007</date>
<time>4:01:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=147</link>
<id>147</id></item>
<item>
<title><![CDATA[[Web] How to add CAPTCHA to simpleblog 3.0]]></title>
<description><![CDATA[<p>Johann almost added CAPTCHA verification to simpleblog 3, but he notes on his <a href="http://blog.8pixel.net" target="_blank">blog</a> that he decided not to after looking at the pros and cons.&nbsp; He says that simpleblog isn't a target of comment spam because of the inability to post html or javascript code into a comment.&nbsp; I disagree, however, because you still get targeted by comment spam by the very nature that bots will still post comments.&nbsp; Even with approval enabled, I still have to delete the pending comments, and there can be A LOT of them.</p><p>Johann included a copy of Emir Tuzul's free <a href="http://www.tipstricks.org" target="_blank">ASP CAPTCHA implementation</a>, but never incorporated it into simpleblog.&nbsp; I looked at how the code works and how Johann implemented comments, and I have successfully added CAPTCHA verification to the comments system.&nbsp; Since doing so a few days ago, not a single spam comment has been left.&nbsp; If you are interested, this is how to do it.</p><p>Since Johann included version 2 of the CAPTCHA code page, you do not need to download anything, but you can opt to use<a href="http://www.tipstricks.org/aspsig/examplev3.asp" target="_blank"> version 3 beta 1</a>, which uses more character obfuscation to make it harder for bots to determine the characters in the image.</p><p>Edit functions.asp to add the following code to the end of the file, which is the verification function:</p><div class="code">&lt;%<br />Function CheckCAPTCHA(valCAPTCHA)<br />&nbsp;&nbsp; &nbsp;SessionCAPTCHA = Trim(Session(&quot;CAPTCHA&quot;))<br />&nbsp;&nbsp; &nbsp;Session(&quot;CAPTCHA&quot;) = vbNullString<br />&nbsp;&nbsp; &nbsp;if Len(SessionCAPTCHA) &lt; 1 then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CheckCAPTCHA = False<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit function<br />&nbsp;&nbsp;&nbsp; end if<br />&nbsp;&nbsp; &nbsp;if CStr(SessionCAPTCHA) = CStr(valCAPTCHA) then<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; CheckCAPTCHA = True<br />&nbsp;&nbsp; &nbsp;else<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; CheckCAPTCHA = False<br />&nbsp;&nbsp; &nbsp;end if<br />End Function<br />%&gt;</div><p><br />Add the following code to functions.asp in the CommentsGet subroutine, which for me starts at line 351.&nbsp; It may be different for you since I think I have added other code higher in the file.&nbsp; This adds the actual CAPTCHA image to the comments form.&nbsp; You will add this code after the call for GetEmoticons and the line break, which for me means inserting this at line 454:</p><p><div class="code">&lt;br /&gt;<br />Type the characters shown in the image for verification.&lt;br /&gt;<br />&lt;img src=&quot;captcha.asp&quot; alt=&quot;&quot; width=&quot;86&quot; height=&quot;21&quot; /&gt;<br />&lt;input name=&quot;strCAPTCHA&quot; type=&quot;text&quot; id=&quot;strCAPTCHA&quot; maxlength=&quot;8&quot; /&gt;&lt;/td&gt;</div><br />At line 481 (after the declaration of the str_userIP variable), insert this, which puts the characters entered into the form in a variable:</p><p><div class="code">strCAPTCHA = Trim(Request.Form(&quot;strCAPTCHA&quot;))</div></p><p>Lastly, replace the code that inserts the comment into the database with the code below, starting at line 492 (after the comment&nbsp; &quot;insert Comment.&quot;&nbsp; Instead of simply inserting the comment into the database, this will compare the entered characters to the actual ones in the image.&nbsp; If they match, the comment is inserted.&nbsp; If not, I use a JavaScript alert to present a popup box and then redirect the user back to the post:</p><p><div class="code">If CheckCAPTCHA(strCAPTCHA) = True Then<br />&nbsp;&nbsp; &nbsp;strSQL = &quot;INSERT INTO T_COMMENTS(c_content, c_name, c_email, c_url, c_bID_fk,ip) VALUES ('&quot; &amp; strComment &amp; &quot;','&quot; &amp; sanitize( strName ) &amp; &quot;','&quot; &amp; sanitize( strEmail ) &amp; &quot;','&quot; &amp;&nbsp; sanitize( strUrl )&amp; &quot;',&quot; &amp;&nbsp; sanitize( bID )&amp; &quot;,'&quot;&amp;str_userIP&amp;&quot;')&quot;<br />&nbsp;&nbsp; &nbsp;Set MyConn = Server.CreateObject(&quot;ADODB.Connection&quot;)<br />&nbsp;&nbsp; &nbsp;MyConn.Open strConn<br />&nbsp;&nbsp; &nbsp;MyConn.Execute(strSQL)<br />&nbsp;&nbsp; &nbsp;MyConn.Close<br />&nbsp;&nbsp; &nbsp;Set MyConn = Nothing<br />&nbsp;&nbsp; &nbsp;Response.Redirect(&quot;default.asp?view=plink&amp;id=&quot; &amp; bID &amp; &quot;&amp;comments=1&quot;)<br />Else<br />&nbsp;&nbsp; &nbsp;%&gt;<br />&nbsp;&nbsp; &nbsp;&lt;script language=&quot;Javascript&quot;&gt;<br />&nbsp;&nbsp; &nbsp;alert('You did not type the verification code correctly.');<br />&nbsp;&nbsp; &nbsp;location.replace('default.asp?view=plink&amp;id=&lt;%= bID %&gt;&amp;comments=1');<br />&nbsp;&nbsp; &nbsp;&lt;/script&gt;<br />&nbsp;&nbsp; &nbsp;&lt;%<br />End If</div><br />You're done!&nbsp; Save functions.asp and then go add a comment to one of your posts.&nbsp; Intentionally enter incorrect characters to confirm the popup works and that the comment did not get added.&nbsp; The only thing missing from this is that it doesn't preserve the comment in the session.&nbsp; This means that if a real person incorrectly enters the code, when returned to the post to try and enter another code, the actual comment data will have to be entered again.&nbsp; Name, email, and URL don't have to because they are stored in a cookie on the client.&nbsp; Perhaps I will add that at a later time.</p>]]></description>
<date>7/22/2007</date>
<time>9:34:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=146</link>
<id>146</id></item>
<item>
<title><![CDATA[[Web] So what is this Something?]]></title>
<description><![CDATA[<p>I haven't had any updates in awhile because I have been looking at different blogging software.&nbsp; simpleblog, while easy to implement and customize, lacks features common to other solutions that I would like.&nbsp; So several months ago I began trying different programs in a test site, but none of them ultimately worked for me.&nbsp; Among the ones I tried:</p><ul>    <li><a href="http://www.dblog.it/sito/default.asp" target="_blank">dBlog</a> - This offered some features I have been looking for, but the default locale is Italian.&nbsp; There is a translation for English which changes titles and headers, but things like the calendar remain in Italian.&nbsp; There isn't a lot of documentation in English, so I was left to doing a lot of manual code search-and-replace.</li><br />    <li><a href="http://www.dotnetnuke.com" target="_blank">DotNetNuke </a>- This is one of the primo open-source CMS solutions available.&nbsp; It is an immensely powerful application that uses modules to offer the features you want: blog, document library, file library, ecommerce, forums, feeback, etc.&nbsp; The application is geared for more commercial or multi-user sites, not a one-off blog, so the portal is a bit too much for what I am looking for.</li><br />    <li><a href="http://www.nukedit.com" target="_blank">Nukedit </a>- A solution ready to go pretty much right out of the box.&nbsp; But it lacks some of the features that even simpleblog offers.</li><br />    <li><a href="http://www.wordpress.org" target="_blank">WordPress </a>- Probably the most popular blog software out there.&nbsp; But it uses PHP and mySQL, whereas I prefer ASP and Access since I know how to write in VBScript.&nbsp; I installed PHP and mySQL and tried to get WordPress working, but ultimately could not.</li><br /></ul><p>I have been using <a href="http://www.8pixel.net/?pageID=420" target="_blank">simpleblog </a>2.3 for awhile, and 2.2 before that.&nbsp; Version 3 is available and after looking at it before all the others, I decided to look at it again.&nbsp; It has the advantage that I am already familiar with the code that Johann has used for 2.x.&nbsp; While it still lacks the features I have been looking for, I grew tired of trying all the other solutions.&nbsp; So I have upgraded sidefumbling to simpleblog 3.0.</p><p>Pros:</p><ul><li>Very simple installation using ASP with VBScript and an MSAccess database.</li><li>Built-in RSS feed.</li><li>Version 3 adds a sidebar for recent posts.</li><li>Version 3 uses FCKeditor for creating posts, which is a customizable WYSIWYG editor.</li><li>Easy to integrate it into your site by editing ASP files and including your own scripts.</li><li>Use of CSS for easy manipulation of global settings for font, layout, etc.</li></ul><p>Cons:</p><ul><li>No use of categories or the ability to group/search for posts based on keywords.</li><li>No search engine.</li><li>No notification of pending comments.</li><li>No use of CAPTCHA for comment spam-prevention.</li><li>Difficult to use code blocks for using literal code in posts, though I have figured out in FCKeditor how to do this.</li><li>Admin interface is limited to accessing previous posts by using calendar to access posts written on specific date, i.e., you cannot just browse a list of your posts for the one you one; you have to use the calendar to find the day you want and then bring up any posts for that single day only.</li><li>Cross-browser support is limited, mostly by layout issues.</li><li>No built-in way for posting from a mobile device, which is nice when traveling or making posts while at a conference, etc.</li><li>Not regularly updated.</li></ul><p>Despite the cons, I offer my thanks to Johann for creating a free solution that has obviously worked for me.</p>]]></description>
<date>7/22/2007</date>
<time>3:44:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=145</link>
<id>145</id></item>
<item>
<title><![CDATA[Something's Coming...]]></title>
<description><![CDATA[]]></description>
<date>5/9/2007</date>
<time>6:23:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=144</link>
<id>144</id></item>
<item>
<title><![CDATA[[Exchange] Quick and dirty script to copy DLs from one user to another]]></title>
<description><![CDATA[<p>It is not uncommon at my company to have to move a user from one domain to another for technical, logistical, or political reasons.  For another set of reasons, moving the user account to the other domain is not done, instead manually creating a new one and associating the mailbox with the new account.</p><p>DL membership does not automatically get updated when this is done, so I have been doing it manually.  It has been on my to-do list for awhile to write a script to copy the DL membership from the old account to the new one.  So I threw this together this morning.  It lacks some of the nice extras my other scripts have (finding the user by logon name, email results, true logging) but it does work.</p><p>You have to edit the script to give it the variables for the old and new users' dn.  It will skip security groups (any group without an alias) and also groups whose Notes (info) attribute contains the word SmartDL.  We use Imanami's SmartDL for automated DL membership when applicable.  Those will be automatically updated the next time each of their jobs run.</p><p>Download it <a title="Copy DLs from one user to another" href="http://www.flobee.net/download/CopyDLMembership.zip">here</a>, or copy/paste below.</p><p>Code:&nbsp;&nbsp;<a onclick="toggleField('code0205', true)" alt="Show code" style="cursor:pointer"><font color="green"><u>Show</u></font></a>&nbsp;&nbsp;<a onClick="toggleField('code0205', false)" alt="Hide code" style="cursor:pointer"><font color="green"><u>Hide</u></font></a></p><div id="code0205" name="code0205" style="display:none"><div class="code"><p>Option Explicit<br />Dim strOldUser, strNewUser, objOldUser, objNewUser, strGroup, objGroup<br />strOldUser = &quot;&quot; 'dn of user to copy from'<br />strNewUser = &quot;&quot; 'dn of user to copy to'</p><p>Set objOldUser = GetObject(&quot;LDAP://&quot; &amp; strOldUser)<br />Set objNewUser = GetObject(&quot;LDAP://&quot; &amp; strNewUser)<br />wscript.echo &quot;Source user: &quot; &amp; objOldUser.DisplayName<br />wscript.echo &quot;Target user: &quot; &amp; objNewUser.DisplayName<br />For Each strGroup in objOldUser.MemberOf<br />  On Error Resume Next    <br />  Set objGroup = GetObject(&quot;LDAP://&quot; &amp; strGroup)<br />      If Not Trim(objGroup.mailNickname) = &quot;&quot; Then<br />        If Not Instr(objGroup.info, &quot;SmartDL&quot;) &gt; 0 Then<br />          objGroup.Add(objNewUser.ADsPath)<br />          If Err.Num = 0 Then<br />            wscript.echo objGroup.DisplayName &amp; &quot;: Update successful.&quot;<br />          Else<br />            wscript.echo objGroup.DisplayName &amp; &quot;: Update UNSUCCESSFUL.&quot;<br />          End If<br />        Else<br />          wscript.echo objGroup.DisplayName &amp; &quot;: Skipped (SmartDL).&quot;<br />        End If<br />      End If<br />  On Error Goto 0<br />Next</p><p>Set objOldUser = Nothing<br />Set objNewUser = Nothing</p></div></div>]]></description>
<date>2/5/2007</date>
<time>4:07:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=143</link>
<id>143</id></item>
<item>
<title><![CDATA[[Exchange] Beware of the impact of the January 11, 2007, IMF update on BES Enterprise Activation messages]]></title>
<description><![CDATA[<p>A couple weeks ago, I started having a problem where BES users who were using Enterprise Activation were getting &quot;Operation timed out&quot; messages when activating.  Existing users still worked fine, as did users who activated via Desktop Manager.  Restarting BES services didn't change anything; neither did rebooting.  Event logs didn't show much, and the application logs didn't show anything except one line item for when the timeout actually occurred.</p><p>A RIM article for troubleshooting EA failures listed several things to check, one of which was that the activation message was actually arriving in the mailbox.  So I checked the Inbox's deleted items cache for one of the mailboxes...nope.  I use a third-party utility called <a href="http://www.windeveloper.com/imftune/">IMF Tune</a> to augment the functionality of the IMF, so I have detailed logs of messages processed by the IMF. (To read a case study regarding my company's use of IMF Tune, go <a title="Con-way IMF Tune Case Study" href="http://www.windeveloper.com/imftune/news/2006/0119/casestudycnf.htm" target="_blank">here</a>.)</p><p>The logs showed that the activation messages were being deleted/archived at the gateway because their SCL ratings were above the threshold.  Some even were being redirected to the Junk E-mail folder (JMF).  I was wondering why this was the case since I have never had a problem with the activation messages being flagged by the IMF.</p><p>Then I remembered that I had updated the IMF definition files on January 18 with the 01/11/07 update, which is right around when the issue started.  For whatever reason, the IMF is now being more discriminatory against the activation messages.  To resolve the issue, I white listed the subdomain the activation messages come from: <strong>*.etp.na.blackberry.net</strong>.  And when it happened again today, I discovered that that user is in Europe and EA messages from those users come from a different subdomain: <strong>*.etp.eu.blackberry.net</strong>.</p><p>So if you BES and the IMF, be careful that your gateway and store thresholds don't keep the activation messages from reaching the inbox.  And if they do, white list the sender domain.  I didn't want to just white list all of blackberry.net, so I am using the subdomain that activation messages originate from.  If there is yet another contintental subdomain out there (for Asia Pacific, perhaps), I might just chain the white list filter to be <strong>blackberry.net</strong> AND the subject begins with <strong>RIM_</strong>.</p>]]></description>
<date>2/1/2007</date>
<time>1:07:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=142</link>
<id>142</id></item>
<item>
<title><![CDATA[[Exchange] Why are my nested UDGs not being upgraded to USGs?]]></title>
<description><![CDATA[<p>Without going into too much backstory for Exchange admins who already know why UDGs need to be upgraded to USGs for ACLs on public folder and mailboxes, I was having an &quot;intermittently persistent&quot; issue where UDGs that are members of other USGs are not being automatically upgraded to USGs.  Without the automatic upgrade, access to the resources the parent USG has been assigned will not work.</p><p>I started Googling to see what I could find.  The org-level attribute to control UDG conversion was not set, nor has it ever been in my environment.  UDGs are being successfully upgraded by Exchange; it is just nested UDGs that were having a problem.  Then I found the reason, and there is actually a KB article for it: <a title="Nested UDGs are not converted to USGs" href="http://support.microsoft.com/kb/898082" target="_blank">898082</a>.</p><p>By design, for performance reasons, when a UDG is a member, whether direct or nested, and the parent group is a USG, Exchange will not convert the UDG to a USG.  Only if the parent group, the one actually being assigned to a resource, is a UDG at the time it is added to the resource, Exchange will convert the parent group and enumerate all members for other UDGs to be converted.</p><p>This makes sense so Exchange doesn't enumerate members every time a group is added to a resource to check for member conversions.  Since conversion is meant to be a one-time event, performance would be adversely affected if it had to enumerate all members every time just to check for a UDG that happened to added since the last time.  So the enumeration only happens if the parent group is a UDG, which implies that the group has never been assigned to an Exchange resource and the one-time conversion can occur.</p>]]></description>
<date>1/26/2007</date>
<time>8:07:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=141</link>
<id>141</id></item>
<item>
<title><![CDATA[[Exchange] Cannot install Exchange 2003 SP2 on an admin machine with Outlook?]]></title>
<description><![CDATA[<p>As all Exchange admins should know, Exchange (and/or ESM) and Outlook are not supported on the same system for a variety of reasons related to MAPI service providers.  However, there is a KB article (<a href="http://support.microsoft.com/kb/329136" target="_blank">here</a>) that tells you how to edit the registry to tell ESM to use mapi32.dll in the \exhsrvr\bin folder instead of the system32 directory.</p><p>I was installing ESM on a new application terminal server this morning and could not get SP2 to install.  The error was that Exchange 2003 was not installed and, therefore, you cannot apply a service pack to it.  But I had just installed ESM right before the SP install.  After some troubleshooting, I discovered that I had prematurely created the registry key as described in KB 329136.</p><p>The article clearly states to install ESM <em>and</em> the service pack(s) before creating the key.  Apparently, this is why, since the setup routine sees that registry key and it breaks something in it.  Deleting the key and rerunning the SP setup allowed it to proceed normally.</p><p>I assume you would also have to delete the key before upgrading to a future service pack, so if you use the key to allow public folder management, remember that its presence will inhibit service pack installations.</p>]]></description>
<date>12/18/2006</date>
<time>9:16:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=140</link>
<id>140</id></item>
<item>
<title><![CDATA[[Exchange] Updated Last Backup Report script]]></title>
<description><![CDATA[<p>I had previously posted (<a title="Last Exchange Backup report" href="http://www.flobee.net/?view=plink&id=112">here</a>) a script to create an email that reports the last full backup time of every database in the organization.  There wasn't too much in the way of error correcting, so the script in my environment was failing to send anything when an Exchange server went offline recently (but is still in AD).</p><p>I have updated the script, which can be downloaded <a title="Last Exchange Backup script" href="http://www.flobee.net/download/lastbackup.zip">here</a>, to not error when this happens and include if it is unable to connect to a specific server and read the last full backup time.  The HTML rendering didn't look right for the server reported with an error, and I couldn't figure out why, so also updated how the table is built.  Now the report is one big table instead of every server in its own table.</p>]]></description>
<date>12/5/2006</date>
<time>11:17:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=139</link>
<id>139</id></item>
<item>
<title><![CDATA[[Exchange] Updated Exchange ActiveSync disable script]]></title>
<description><![CDATA[<p>I previously posted (<a title="Disable Exchange ActiveSync post" href="http://www.flobee.net/?view=plink&id=131">here</a>) a script to disable Exchange ActiveSync for unauthorized users.  The script is based on using the dn of one or more groups to determine authorized users (i.e., if you are in the group, you are allowed).  This method recently failed me (twice) because some of the groups were renamed by another admin to make them more readable.  Not only were the display names changed, but the objects were renamed as well, so the cn and dn were changed.  This means my script couldn't find the groups I had hard-coded, which isn't good scripting practice anyway.</p><p>I have updated the script, which can be downloaded <a title="Exchange ActiveSync disable script" href="http://www.flobee.net/download/EASDisable.zip">here</a>, to search for the groups based on their objectGUID, which never changes no matter what you do to the object (rename, move, etc.).  Instead of hard-coding the dn of the object, I hard-code the objectGUID.  Then I bind directly to the object based on the GUID to retrieve its dn, which is used in the search filter to find the users I want to modify.</p><p>Note that ADO allows you to bind to an object given just its GUID, without having to specify other connection parameters.  You can also use the hexadecimal or binary format of the GUID in the connection string; AD will figure out which format you are using. I used the binary format in my script so that I could just copy and paste the value from <a title="SystemTools' Hyena" href="http://www.systemtools.com/hyena/index.html" target="_blank">Hyena</a> into my script without having to convert to a hex value.</p>]]></description>
<date>12/4/2006</date>
<time>12:48:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=138</link>
<id>138</id></item>
<item>
<title><![CDATA[[Humor] How does something like this make it through QA?]]></title>
<description><![CDATA[<div class="floatclear"><a href="http://www.shopwildplanet.com/prod/WPT22089.html" target="_blank"><img height="280" alt="Boots Aquapet" hspace="5" src="images/BootsAquapet.jpg" width="280" align="right" border="1" /></a><p>A coworker brought this to my attention today, wondering about the highly suggestive nature of the toy. I don't consider myself to be a crude person, but it didn't take me more than one glance to recognize the dirty overtone the product implicitly conveys. I am a fan of Boots as much as any other parent/fan of Dora the Explorer, but this is taking &quot;spank the monkey&quot; a little too far.</p><p /><p /><p /><p /><p /><p /><p /><p /><p> </p></div>]]></description>
<date>11/21/2006</date>
<time>2:03:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=136</link>
<id>136</id></item>
<item>
<title><![CDATA[[Exchange] OWA access to public folders via front end hangs on Loading...]]></title>
<description><![CDATA[<p>I just resolved an issue that started the other day where using OWA to access the public folders through a font-end server would result in a poorly-formatted toolbar and the word Loading... in the leaf pane.  Access to mailboxes was just fine, and it would work when using the Basic client; only the Premium client would exhibit the behavior.  Accessing the public folders directly via the back-end server worked just fine.</p><p>Because it wasn't a content issue (mailboxes displayed fine) I could ignore permissions being the problem.  Knowing that everything except the content comes from the front-end server (stylesheets, scripts, controls) I started focusing on file version mismatches between the front-end and back-end.  Any patch that affects the rendering of OWA needs to be applied to the front-end first, and then to the back-ends.</p><p>I checked for hotfixes on both servers and they showed the same number of patches installed (based on KB article numbers).  The cause started to show itself when looking at directory structures.  The front-end server's highest numeric directory in /exchweb was 6.5.7651.9, but the back-end server's highest directory was 6.5.7651.25.  Researching what hotfix has a build number of 7651 yielded <a href="http://support.microsoft.com/kb/911829" target="_blank">KB 911829</a>.  This hotfix was released in April, but was rereleased in May as v2.</p><p>I patched the front-end server some time ago, but the back-end servers were only patched recently with this hotfix.  I used Microsoft Update to install the patch on these systems.  So what happened is that Microsoft rereleased the hotfix with newer files and a newer build number, but kept the article number under which it is published the same.  Microsoft Update doesn't detect that a newer hotfix is available when the article number remains the same.  Downloading the v2 hotfix and running it on the front-end server created the 6.5.7651.25 directory and resolved the issue.</p><p>So this issue was caused by Microsoft not using good enough detection methods in Microsoft Update, and by me for not installing the hotfix on all the servers at the same time.  The latter is easy enough to correct, but I doubt that the former will be fixed anytime soon.</p>]]></description>
<date>8/16/2006</date>
<time>12:39:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=134</link>
<id>134</id></item>
<item>
<title><![CDATA[[Family] [Humor] Chain letter making the rounds: Things I've Learned From My Boys]]></title>
<description><![CDATA[<p>My mother sent me this chain letter in June.  Whether it was because it reminded her of what my brother and I were like as youngsters, or that she is warning me about my own sons, I don't know.  It is still humorous to read, especially if you have boys and can relate to even one item in the list.</p><ul><li>For those who have grown children - this is hysterical</li><li>For those who have children past this age, this is hilarious</li><li>For those who have children this age, this is not funny</li><li>For those who have children nearing this age, this is a warning</li><li>For those who have not yet had children, this is birth control</li></ul><blockquote><p><u>Things I've Learned From My Boys</u></p></blockquote><ol><li>A king size waterbed holds enough water to fill a 2000 sq. ft. house 4 inches deep.</li><li>If you spray hair spray on dust bunnies and run over them with roller blades, they can ignite.</li><li>A 3-year old boy's voice is louder than 200 adults in a crowded restaurant.</li><li>If you hook a dog leash over a ceiling fan, the motor is not strong enough to rotate a 42-pound boy wearing Batman underwear and a Superman cape.  It is strong enough, however, if tied to a paint can, to spread paint on all four walls of a 20x20 ft. room.</li><li>You should not throw baseballs up when the ceiling fan is on. When using a ceiling fan as a bat, you have to throw the ball up a few times before you get a hit. A ceiling fan can hit a baseball a long way.</li><li>A double-paned glass window doesn't stop a baseball hit by a ceiling fan.</li><li>When you hear the toilet flush, followed by the words &quot;uh oh,&quot; it's already too late.</li><li>Brake fluid mixed with Clorox makes smoke, and lots of it.</li><li>A six-year old boy can start a fire with a flint rock even though a 36-year old man says they can only do it in the movies.</li><li>Certain Legos will pass through the digestive tract of a 4-year old boy.</li><li>&quot;Playdough&quot; and &quot;microwave&quot; should not be used in the same sentence.</li><li>Super glue is forever.</li><li>No matter how much Jell-O you put in a swimming pool you still can't walk on water.</li><li>Pool filters do not like Jell-O.</li><li>VCRs do not eject PB&amp;J sandwiches even though TV commercials show they do.</li><li>Garbage bags do not make good parachutes.</li><li>Marbles in gas tanks make a lot of noise when driving.</li><li>You probably DO NOT want to know what that odor is.</li><li>Always look in the oven before you turn it on; plastic toys do not like ovens.</li><li>The fire department in Austin, TX, has a 5-minute response time.</li><li>The spin cycle on the washing machine does not make earthworms dizzy.</li><li>It will, however, make cats dizzy.</li><li>Cats throw up twice their body weight when dizzy.</li><li>80% of women will pass this on to almost all of their friends, with or without kids.</li><li>80% of men who read this will try mixing the Clorox and brake fluid.</li></ol><p />]]></description>
<date>8/15/2006</date>
<time>4:35:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=133</link>
<id>133</id></item>
<item>
<title><![CDATA[[Exchange] Change users' default calendar permission (and email the users and admin)]]></title>
<description><![CDATA[<p>Our IT Leadership team decided that it will promote more effective collaboration if the Default calendar permission for all IT employees is set to Reviewer (instead of the Default of None). As with many of my scripts, I started with the work <a href="http://gsexdev.blogspot.com/2005/05/changing-default-permissions-on.html" target="_blank" alt="Glen Scales' original script to set the default permission to Reviewer.">Glen Scales</a> has already done. Go there for information on the prerequisite for using this script to make the change (the need for ACL.dll).</p><p>Glen's script uses an input argument of a server name. My distributed environment doesn't allow for such a broad application, so I use the membership of a DL that contains the IT personnel. This DL actually contains other DLs, so I separately use another <a href="http://www.rlmueller.net/List%20Members%20of%20a%20Group.htm" target="_blank" alt="VBSCript to enumerate all members of a group, event nested members.">script</a> by Richard Mueller that enumerates nested groups and puts the results into a domain local group that is used for other purposes.</p><p>After getting the group members, I loop through each member for only those with a mailbox that isn't hidden. For those who haven't been touched by the script before, a function is called that uses CDO to log into the mailbox, enumerate the calendar permissions looking for the Default entry, and change it to Reviewer. The user's local FreeBusy Data folder is also updated to set the Default to Editor since that permission goes hand in hand when setting permissions on the calendar.</p><p>To keep tabs on who the script has touched, a notation is added to extensionAttribute4 (customizable). Those with that notation are skipped in the future. Then an email is sent to the user informing them of the change. I chose to do this because Exchange users may be used to the fact the the Default permission is None; this way they are aware that their calendar is open for viewing. It also helps with new employees who are not aware of this &quot;policy&quot; and can mark items as Private as necessary.</p><p>Finally, an email is sent to the admin with the results of the job run. It includes the display name, mailbox server, and whether the permission was set or the object skipped (to catch entries that slip through my filter). I have scheduled this to run weekly, and I will get an email each time so I know that the script is successfully running and which users are being modified.</p><p>All of the variables that require customization are near the top. These are for mail configuration, search filter, and the notation parameters for touched mailboxes.</p><p>Download it <a href="http://www.flobee.net/download/DefaultCalPerm.zip">here</a> or copy below.</p><p>Code:&nbsp;&nbsp;<a onclick="toggleField('code0622', true)" alt="Show code" style="cursor:pointer"><font color="green"><u>Show</u></font></a>&nbsp;&nbsp;<a onClick="toggleField('code0622', false)" alt="Hide code" style="cursor:pointer"><font color="green"><u>Hide</u></font></a></p><div id="code0622" name="code0622" style="display:none"><div class="code"><p>Option Explicit</p><p>Public Const CdoDefaultFolderCalendar = 0<br />Dim strSMTPServer, strMailFrom, strUserMailSubject, strUserMailBody<br />Dim strAdminMailRecip, strAdminMailSubject, strAdminMailBody<br />Dim strDefaultNamingContext, strQueryFilter, strAttName, strAttNote<br />Dim conn, com, iAdRootDSE, strNamingContext<br />Dim Rs, objGroup, strMember, objUser, strMsExchHomeServerName<br />Dim objSession, CdoInfoStore, CdoFolderRoot, ACLObj, CdoCalendar, FolderACEs, fldACE<br />Dim objRoot, objFreeBusyFolder </p><p>'Configuration parameters:<br />''''''''''''''''''''''''''''''''''''''''''''''<br />'Email notification configuration<br />strSMTPServer = &quot;server.company.com&quot; 'FQDN of SMTP server<br />strMailFrom = &quot;&quot;&quot;Display Name&quot;&quot; &lt;<a href="mailto:SMTPAddress@company.com">SMTPAddress@company.com</a>&gt;&quot; ' Display name and address of sender<br />strUserMailSubject = &quot;The default permission on your calendar has been updated&quot; 'Subject of message sent to users<br />strUserMailBody = &quot;In order to promote effective collaboration among the Company &quot; &amp; _<br />    &quot;employees, the Default permission on your calendar has been updated to Reviewer.  This allows anyone within the organization &quot; &amp; _<br />    &quot;to see the details of items within your calendar.  For items that are of a sensitive, confidential, or personal nature, &quot; &amp; _<br />    &quot;you can mark them as Private.  This will restrict the details of the item so that others cannot see the subject or body.  &quot; &amp; _<br />    &quot;If you have any questions about this change, please reply to this message or contact the Help Desk at XXXX.&lt;br&gt;&lt;br&gt;&quot; &amp; _<br />    &quot;Company Messaging and Collaboration Team (GAL Display Name)&lt;br&gt;Department&lt;br&gt;Company&quot; 'Body of message sent to users<br />strAdminMailRecip = &quot;<a href="mailto:SMTPAddress@company.com">SMTPAddress@company.com</a>&quot; 'Address of admin to receive status report<br />strAdminMailSubject = &quot;Default calendar permission change report&quot; 'Subject of message sent to admin</p><p>'Domain to search for object<br />strDefaultNamingContext = &quot;dc=company,dc=com&quot; 'AD FQDN of base scope to search</p><p>'Search filter for group with users<br />strQueryFilter = &quot;(&amp;(objectcategory=group)(displayName=something))&quot; 'LDAP filter to locate group with members to modify</p><p>'Attribute and notation for updated objects<br />strAttName = &quot;extensionAttribute4&quot; 'defined for a single-valued string attribute<br />strAttNote = &quot;DefaultCalSet&quot; 'Notation used to skip processed users on future script runs<br />''''''''''''''''''''''''''''''''''''''''''''''</p><p>strAdminMailBody = &quot;&quot;<br />Set conn = createobject(&quot;ADODB.Connection&quot;)<br />Set com = createobject(&quot;ADODB.Command&quot;)<br />Set iAdRootDSE = GetObject(&quot;<a href="ldap://RootDSE">LDAP://RootDSE</a>&quot;)<br />strNamingContext = iAdRootDSE.Get(&quot;configurationNamingContext&quot;)<br />Conn.Provider = &quot;ADsDSOObject&quot;<br />Conn.Open &quot;ADs Provider&quot;<br />Com.ActiveConnection = Conn<br />com.Properties(&quot;Page Size&quot;) = 1000<br />Com.CommandText = &quot;&lt;GC://&quot; &amp; strDefaultNamingContext &amp; &quot;&gt;;&quot; &amp; StrQueryFilter &amp; &quot;;distinguishedname;subtree&quot;<br />Set Rs = Com.Execute<br /> While Not Rs.EOF<br />  Set objGroup = GetObject(&quot;LDAP://&quot; &amp; Rs.fields(&quot;distinguishedname&quot;))<br />  For each strMember in objGroup.Member<br />   Set objUser = GetObject(&quot;LDAP://&quot; &amp; strMember)<br />   If InStr(objUser.Get(strAttName), strAttNote) &lt; 1 Then<br />    strAdminMailBody = strAdminMailBody &amp; objUser.displayName &amp; &quot;&lt;br&gt;&quot;<br />    If objUser.Class = &quot;user&quot; And Not IsNull(objUser.msExchHomeServerName) And Not UCase(objUser.msExchHidefromAddressLists) = &quot;TRUE&quot; Then<br />     strMsExchHomeServerName = objUser.msExchHomeServerName<br />     strMsExchHomeServerName = right(strMsExchHomeServerName,len(strMsExchHomeServerName)-instrrev(strMsExchHomeServerName,&quot;/cn=&quot;)-3)<br />     strAdminMailBody = strAdminMailBody &amp; &quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot; &amp; strMsExchHomeServerName &amp; &quot;&lt;br&gt;&quot;<br />     Call dofreebusy(strMsExchHomeServerName, objUser.mailNickname)<br />     strAdminMailbody = strAdminMailBody &amp; &quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Permission set on: &quot; &amp; objUser.mailNickname &amp; &quot;&lt;br&gt;&quot;<br />     WriteTag<br />     SendEmail objUser.mail, strUserMailSubject, strUserMailBody<br />    Else<br />     strAdminMailBody = strAdminMailBody &amp; &quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Skipping object&lt;br&gt;&quot;<br />    End If<br />   End If<br />  Next<br /> Rs.MoveNext<br /> Wend<br />Rs.Close</p><p>'Send admin email report<br />If Not strAdminMailBody = &quot;&quot; Then<br /> strAdminMailBody = strAdminMailBody &amp; &quot;&lt;br&gt;Done.&lt;br&gt;&quot;<br />Else<br /> strAdminMailBody = &quot;No mailboxes needed updating.&quot;<br />End If<br />SendEmail strAdminMailRecip, strAdminMailSubject, strAdminMailBody</p><p>Set conn = Nothing<br />Set com = Nothing</p><p>Function dofreebusy(serverName, mailboxName)</p><p> 'Set Default permission to Reviewer<br /> Set objSession = CreateObject(&quot;MAPI.Session&quot;)<br /> objSession.Logon &quot;&quot;,&quot;&quot;,false,true,0,true,servername &amp; vbLF &amp; mailboxname<br /> Set CdoInfoStore = objSession.GetInfoStore<br /> Set CdoFolderRoot = CdoInfoStore.RootFolder<br /> Set ACLObj = CreateObject(&quot;MSExchange.aclobject&quot;)<br /> Set CdoCalendar = objSession.GetDefaultFolder(CdoDefaultFolderCalendar)<br /> ACLObj.CdoItem = CdoCalendar<br /> Set FolderACEs = ACLObj.ACEs<br /> For each fldACE in FolderACEs<br />  If fldACE.ID = &quot;ID_ACL_DEFAULT&quot; Then<br />   fldACE.Rights = 1025<br />   ACLObj.Update<br />  End If<br /> Next<br /> <br /> 'Set local FreeBusy folder permission to Editor<br /> Set objRoot = objSession.GetFolder(&quot;&quot;)<br /> Set objFreeBusyFolder = objRoot.Folders.Item(&quot;FreeBusy Data&quot;)<br /> ACLObj.CdoItem = objFreeBusyFolder<br /> Set FolderACEs = ACLObj.ACEs<br /> For each fldACE in FolderACEs<br />  If fldACE.ID = &quot;ID_ACL_DEFAULT&quot; Then<br />  fldACE.Rights = 1123<br />  ACLObj.Update<br />  End If<br /> Next</p><p>End function</p><p>'Write notation tag into attribute<br />Sub WriteTag()<br /> If IsNull(objUser.Get(strAttName)) or IsEmpty(objUser.Get(strAttName)) Then<br />  objUser.Put strAttName, strAttNote &amp; &quot;;&quot;<br /> Else<br />  Dim strExistAttName<br />  strExistAttName = objUser.Get(strAttName)<br />  objUser.Put strAttName, strExistAttName &amp; strAttNote &amp; &quot;;&quot;<br /> End If<br /> objUser.SetInfo<br />End Sub</p><p>'Send change notification and report<br />Sub SendEmail (strRecipAddress, strMailSubject, strMailBody)<br /> Dim objMail<br /> Set objMail = CreateObject(&quot;CDO.Message&quot;)<br /> objMail.Configuration.Fields.Item (&quot;<a href="http://schemas.microsoft.com/cdo/configuration/sendusing">http://schemas.microsoft.com/cdo/configuration/sendusing</a>&quot;)      = 2<br /> objMail.Configuration.Fields.Item (&quot;<a href="http://schemas.microsoft.com/cdo/configuration/smtpserver">http://schemas.microsoft.com/cdo/configuration/smtpserver</a>&quot;)     = strSMTPServer<br /> objMail.Configuration.Fields.Item (&quot;<a href="http://schemas.microsoft.com/cdo/configuration/smtpserverport">http://schemas.microsoft.com/cdo/configuration/smtpserverport</a>&quot;) = 25<br /> objMail.Configuration.Fields.Update</p><p> objMail.From     = strMailFrom<br /> objMail.To       = strRecipAddress<br /> objMail.Subject  = strMailSubject<br /> objMail.HTMLBody = strMailBody<br /> objMail.Send<br />   Set objMail = Nothing<br />End Sub</p></div></div>]]></description>
<date>6/22/2006</date>
<time>4:49:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=132</link>
<id>132</id></item>
<item>
<title><![CDATA[[Exchange] Script to disable Exchange ActiveSync for unauthorized users]]></title>
<description><![CDATA[<p>By default, users have all mobile services enabled (OMA, EAS including AUTD/DP).  This is a pain in my environment because only authorized users are allowed to use EAS (to ensure only approved devices procured through proper channels are used).  OMA, being similar to OWA, is allowed for everyone.</p><p>I had written a batch file long ago to change the bitmask attribute for users whose mobile services are enabled for everything (0) and are not in the appropriate DL of authorized users to disable only EAS (5).  It was an inefficient script that required explicit permissions for each domain, called a command-line regex tool to format the ldifde export, and was prone to errors.</p><p>This updated script accomplishes the same thing, but more efficiently.  It processes all users at one time (inside a for loop) and uses implicit permissions.  It even emails the results of the number of users modified.  The script is customized for my environment, but you can tweak it as necessary.  </p><p>I have five user domains, but the DLs for authorization are in one domain.  I wanted it to be as dynamic as possible, but balancing that with all the extra code necessary to make every piece not rely on hard-coded information.  So you need to provide mail config information, the NetBIOS domain names you want to loop through, and the dn of the groups for each user domain.  The GC to search and the DC to make the change to will be determined automatically.</p><p>Download it <a href="http://www.flobee.net/download/EASDisable.zip">here</a> or copy below.</p><p>Code:&nbsp;&nbsp;<a onclick="toggleField('code0602', true)" alt="Show code" style="cursor:pointer"><font color="green"><u>Show</u></font></a>&nbsp;&nbsp;<a onClick="toggleField('code0602', false)" alt="Hide code" style="cursor:pointer"><font color="green"><u>Hide</u></font></a></p><div id="code0602" name="code0602" style="display:none"><div class="code"><p>Option Explicit<br /><br />Dim mailFrom, mailTo, mailSubject, mailBody, mailServer<br />Dim objConnection, objCommand, objRecordSet, objUser, objGC, objDomain<br />Dim strGCPath, strNBDomain, strdomain, arrDomains, strCount<br />dim strSearchFilter, strEASDL, strDomainPath<br />strCount = ""<br /><br />'Mail config<br />mailFrom = Wscript.ScriptName & "@company.com"<br />mailTo = "user@company.com"<br />mailSubject = "EAS Disable Results" <br />mailBody = ""<br />mailServer = "server.company.com"<br /><br />'AD connection parameters<br />Set objConnection = CreateObject("ADODB.Connection")<br />objConnection.Open "Provider=ADsDSOObject;"<br />Set objCommand = CreateObject("ADODB.Command")<br />objCommand.ActiveConnection = objConnection<br /><br />'Get FQDN of a GC<br />Set objGC = GetObject("GC://RootDSE")<br />strGCPath = objGC.Get("dnsHostName")<br /><br />'Query each domain and call disable subroutine<br />arrDomains = array("domainA", "domainB", "domainC", "domainD", "domainE")<br />For each strDomain in arrDomains<br />	subOMADisable strdomain<br />Next<br /><br />'Email results<br />Call subSendMail(mailFrom, mailTo, mailSubject, strCount, mailServer)<br /><br />'Sub to change attribute value<br />Sub subOMADisable(strNBDomain)<br />	'Get base DN of domain<br />	Set objDomain = GetObject("LDAP://" & strNBDomain & "/RootDSE")<br />	strDomainPath = objDomain.Get("DefaultNamingContext")<br />	Set objDomain = Nothing<br /><br />	Select Case strNBDomain<br />		Case "domainA"<br />			strEASDL = "dn of groupA"<br />		Case "domainB"<br />			strEASDL = "dn of groupB"<br />		Case "domainC"<br />			strEASDL = "dn of groupC"<br />		Case "domainD"<br />			strEASDL = "dn of groupD"<br />		Case "domainE"<br />			strEASDL = "dn of groupE"<br />	End Select<br />	strSearchFilter = "(&(objectcategory=user)(mailnickname=*)(homeMDB=*)(!memberof=" & strEASDL & ")(!msExchOMAAdminWirelessEnable=5))"<br />	objCommand.CommandText = "<GC://" & strGCPath & "/" & strDomainPath & ">;" & strSearchFilter & ";distinguishedname;subtree"<br />	Set objRecordSet = objCommand.Execute<br />	If objRecordSet.RecordCount > 0 Then<br />		While Not objRecordSet.EOF<br />			Set objUser = GetObject("LDAP://" & objRecordSet.Fields("distinguishedname"))<br />'			wscript.echo objUser.DisplayName<br />			objUser.Put "msExchOMAAdminWirelessEnable", "5"<br />			objUser.SetInfo<br />			objRecordSet.MoveNext<br />		Wend<br />	End If<br />	strCount = strCount & vbTAB & strNBDomain & ": " & objRecordSet.RecordCount & vbCRLF<br />End Sub<br /><br />'Sub to send email with results<br />Sub subSendMail (mFrom, mTo, mSubject, mBody, mServer)<br />	Dim objEmail<br />	Set objEmail = CreateObject("CDO.Message")<br />	objEmail.From = mFrom<br />	objEmail.To = mTo<br />	objEmail.Subject = mSubject<br />	objEmail.Textbody = "Objects modified in each domain:" & vbCRLF &vbCRLF & mBody<br />	objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2<br />	objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = mServer <br />	objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25<br />	objEmail.Configuration.Fields.Update<br />	objEmail.Send<br />End Sub<br /><br />'Cleanup<br />Set objUser = Nothing<br />Set objCommand = Nothing<br />Set objGC = Nothing<br />Set objConnection = Nothing<br /></p></div></div>]]></description>
<date>6/2/2006</date>
<time>9:09:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=131</link>
<id>131</id></item>
<item>
<title><![CDATA[[Faith] The difference between faith and political agenda]]></title>
<description><![CDATA[<p><font style="BACKGROUND-COLOR: #f5f5f5">The May 15, 2006, issue of Time magazine has an essay by Andrew Sullivan (<a title="My Problem with Christianism" href="http://www.time.com/time/magazine/article/0,9171,1191826-1,00.html" target="_blank">here</a>) that rings true for me.  Perhaps for you, too, but at a minimum it should make you think.</font></p><blockquote dir="ltr" style="MARGIN-RIGHT: 0px"><p><strong><span class="headline">My Problem with Christianism</span><br /></strong><span class="subhead">A believer spells out the difference between faith and a political agenda</span><br /><span class="byline">By</span> <span class="byline">ANDREW SULLIVAN</span></p><p /><p>Are you a Christian who doesn't feel represented byÂ the religious right? I know the feeling. When the discourse about faith is dominated by political fundamentalists and social conservatives, many others begin to feel as if their religion has been taken away from them.</p><p>The number of Christians misrepresented by the Christian right is many. There are evangelical Protestants who believe strongly that Christianity should not get too close to the corrupting allure of government power. There are lay Catholics who, while personally devout, are socially liberal on issues like contraception, gay rights, women's equality and a multi-faith society. There are very orthodox believers who nonetheless respect the freedom and conscience of others as part of their core understanding of what being a Christian is. They have no problem living next to an atheist or a gay couple or a single mother or people whose views on the meaning of life are utterly alien to them--and respecting their neighbors' choices. That doesn't threaten their faith. Sometimes the contrast helps them understand their own faith better.</p><p>And there are those who simply believe that, by definition, God is unknowable to our limited, fallible human minds and souls. If God is ultimately unknowable, then how can we be so certain of what God's real position is on, say, the fate of Terri Schiavo? Or the morality of contraception? Or the role of women? Or the love of a gay couple? Also, faith for many of us is interwoven with doubt, a doubt that can strengthen faith and give it perspective and shadow. That doubt means having great humility in the face of God and an enormous reluctance to impose one's beliefs, through civil law, on anyone else.</p><p>I would say a clear majority of Christians in the U.S. fall into one or many of those camps. Yet the term &quot;people of faith&quot; has been co-opted almost entirely in our discourse by those who see Christianity as compatible with only one political party, the Republicans, and believe that their religious doctrines should determine public policy for everyone. &quot;Sides are being chosen,&quot; Tom DeLay recently told his supporters, &quot;and the future of man hangs in the balance! The enemies of virtue may be on the march, but they have not won, and if we put our trust in Christ, they never will.&quot; So Christ is a conservative Republican?</p><p>Rush Limbaugh recently called the Democrats the &quot;party of death&quot; because of many Democrats' view that some moral decisions, like the choice to have a first-trimester abortion, should be left to the individual, not the cops. Ann Coulter, with her usual subtlety, simply calls her political opponents &quot;godless,&quot; the title of her new book. And the largely nonreligious media have taken the bait. The &quot;Christian&quot; vote has become shorthand in journalism for the Republican base.</p><p>What to do about it? The worst response, I think, would be to construct something called the religious left. Many of us who are Christians and not supportive of the religious right are not on the left either. In fact, we are opposed to any politicization of the Gospels by any party, Democratic or Republican, by partisan black churches or partisan white ones. &quot;My kingdom is not of this world,&quot; Jesus insisted. What part of that do we not understand?</p><!--pagebreak--><p>So let me suggest that we take back the word Christian while giving the religious right a new adjective: Christianist. Christianity, in this view, is simply a faith. Christianism is an ideology, politics, an ism. The distinction between Christian and Christianist echoes the distinction we make between Muslim and Islamist. Muslims are those who follow Islam. Islamists are those who want to wield Islam as a political force and conflate state and mosque. Not all Islamists are violent. Only a tiny few are terrorists. And I should underline that the term Christianist is in no way designed to label people on the religious right as favoring any violence at all. I mean merely by the term Christianist the view that religious faith is so important that it must also have a precise political agenda. It is the belief that religion dictates politics and that politics should dictate the laws for everyone, Christian and non-Christian alike.</p><p>That's what I dissent from, and I dissent from it as a Christian. I dissent from the political pollution of sincere, personal faith. I dissent most strongly from the attempt to argue that one party represents God and that the other doesn't. I dissent from having my faith co-opted and wielded by people whose politics I do not share and whose intolerance I abhor. The word Christian belongs to no political party. It's time the quiet majority of believers took it back.</p></blockquote>]]></description>
<date>5/9/2006</date>
<time>9:42:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=130</link>
<id>130</id></item>
<item>
<title><![CDATA[[Exchange] Company name change and email addresses]]></title>
<description><![CDATA[<p>My company changed its name a couple weeks ago and so I needed to add a new primary address for those who had the old domain as a primary, and move the old primary to a secondary. I was surprised that I couldn't hardly find any existing scripts to accommodate such an endeavor so I had to resort to doing it myself.</p><p>This script goes through all accounts in a given AD domain and whose primary email address is the &quot;old&quot; SMTP domain name, makes the primary a secondary, takes the username portion of the address and appends the new domain and makes it the new primary. I log all of the old address and new addresses to the screen, so redirect the output to a file to capture that. It doesn't check for preexisting addresses so conflicts can occur. I had previously done my own extract to look for those, so dealing with them manually was easier and faster than coding for that.</p><p>I modified the script each time I ran it to change the AD domain I wanted to search (though I could have just defined an array of domain names and looped through each of them), and ran it against DLs and public folders, too, adjusting the filter to return the different object types. You will need to do the same.</p><p>Download the code <a href="http://www.flobee.net/download/UpdateProxy.zip" alt="Download script">here</a>, or copy below.</p><p>Code:&nbsp;&nbsp;<a onclick="toggleField('code0502', true)" alt="Show code" style="cursor:pointer"><font color="green"><u>Show</u></font></a>&nbsp;&nbsp;<a onClick="toggleField('code0502', false)" alt="Hide code" style="cursor:pointer"><font color="green"><u>Hide</u></font></a></p><div id="code0502" name="code0502" style="display:none"><div class="code">Option Explicit<br /><br />'Set value for domain to run against and LDAP filter to use<br />'Also set the old and new SMTP domain names on line 33<br />'If you need to update the display name to remove a company designation, that is line 80<br />dim strDomain, strSearchFilter<br />strdomain = "nbdomain" 'Put the NetBIOS domain name here<br />strSearchFilter = "(&(objectcategory=publicfolder)(mailnickname=*)(mail=*@olddomain.com))" 'Update filter to return the object types you want, e.g., users, groups, publicfolders<br /><br />'Connect to AD<br />Dim objConnection, objCommand, objRecordSet, objUser<br />Set objConnection = CreateObject("ADODB.Connection")<br />objConnection.Open "Provider=ADsDSOObject;"<br />Set objCommand = CreateObject("ADODB.Command")<br />objCommand.ActiveConnection = objConnection<br />objCommand.Properties("Page Size") = 10000<br /><br />'Retrieve user objects<br />Const ADS_PROPERTY_UPDATE = 2<br />objCommand.CommandText = "<LDAP://" & strDomain & ">; " & strSearchFilter & "; distinguishedname"<br />Set objRecordSet = objCommand.Execute<br />wscript.echo "Count:" & objRecordSet.RecordCount<br />While not objRecordSet.EOF<br />	Set objUser = GetObject("LDAP://" & Replace(objRecordSet.Fields("distinguishedname"),"/", "\/"))<br />	wscript.echo objUser.displayName & "; " & strDomain & "\" & objUser.sAMAccountName<br />	<br />	'Set values for new email addresses<br />	Dim blnExists, strNewMail, i, strOldProxy, strAddress, arrProxyAddresses, intProxyAddresses, strNewProxy, intProxyForLoop<br />	arrProxyAddresses = objUser.proxyAddresses<br />	intProxyAddresses = UBound(arrProxyAddresses)<br />	intProxyForLoop = intProxyAddresses	<br />	<br />	'Set value for mail<br />	strNewMail = Replace(objUser.mail, "@olddomain.com", "@newdomain.com")<br />	wscript.echo vbTab & "Old mail: " & objUser.mail<br />	wscript.echo vbTab & "New mail: " & strNewMail<br />	wscript.echo ""<br /><br />	'Log old SMTP proxies<br />	For each strOldProxy in arrProxyAddresses<br />		If UCase(Left(strOldProxy,5)) = "SMTP:" Then<br />			wscript.echo vbTab & "Old proxies: " & strOldProxy<br />		End If<br />	Next<br /><br />	'Change primary to secondary and add new primary<br />	blnExists = False<br />	For i = 0 to intProxyForLoop<br />		dim strAddressType, strAddressBody <br />		strAddressType = Left(arrProxyAddresses(i),5)<br />		strAddressBody = Mid(arrProxyAddresses(i),6)<br />		If UCase(strAddressType) = "SMTP:" Then<br />			If strAddressType = "SMTP:" Then <br />	    		arrProxyAddresses(i) = Replace(arrProxyAddresses(i), "SMTP:", "smtp:")<br />	    	Else <br />	    		If LCase(strAddressBody) = LCase(strNewMail) Then<br />					blnExists = True<br />					arrProxyAddresses(i) = Replace(arrProxyAddresses(i), "smtp:", "SMTP:")<br />				End If<br />			End If <br />		End If<br />		If i = intProxyForLoop Then<br />				If Not blnExists Then<br />					ReDim Preserve arrProxyAddresses(intProxyAddresses + 1)<br />					arrProxyAddresses(intProxyAddresses + 1) = "SMTP:" & strNewMail<br />				End If<br />		End If<br />	Next<br /><br />	'Log new SMTP proxies<br />	For each strNewProxy in arrProxyAddresses<br />		If UCase(Left(strNewProxy,5)) = "SMTP:" Then<br />			wscript.echo vbTab & "New proxies: " & strNewProxy<br />		End If<br />	Next<br />	wscript.echo ""<br />	<br />	'Remove component designation from display name<br />	Dim strDisplayName<br />	strDisplayName = Replace(objUser.displayName, " - COMPANY", "")<br />	wscript.echo vbTab & "New display: " & strDisplayName<br />	<br />	'Commit changes<br />	objUser.Put "mail", strNewMail<br />	objUser.PutEx ADS_PROPERTY_UPDATE, "proxyAddresses", arrProxyAddresses<br />	objUser.Put "displayName", strDisplayName<br />	On Error Resume Next<br />	objUser.SetInfo<br />	If Err.Number <> 0 Then<br />		wscript.echo "Update unsuccessful!"<br />	Else<br />		wscript.echo "Update successful"<br />	End If<br />	wscript.echo vbCRLF<br />	On Error Goto 0<br />	objRecordSet.MoveNext<br />Wend<br /><br />Set objRecordSet = Nothing<br />Set objUser = Nothing<br />Set objCommand = Nothing<br />Set objConnection = Nothing</p></div></div>]]></description>
<date>5/2/2006</date>
<time>1:14:00 PM</time>
<link>http://www.flobee.net/?view=plink&amp;id=129</link>
<id>129</id></item>
<item>
<title><![CDATA[[Humor] This is what my coworkers think of me]]></title>
<description><![CDATA[<p>I am not sure if I am supposed to take this as an insult or a compliment.  All I know is I dance way better than this guy.  For those that don't know, the comparison is because I ride a 1983 Honda Nighthawk 550.</p><p align="center"><br /><embed id="VideoPlayback" style="WIDTH: 400px; HEIGHT: 326px" src="http://video.google.com/googleplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DowAAAOZw8BOv1IwqKmq-ladwOn0Hepl5zsY6F3U0jq3h4Ex3e8mx1bFv4ceuSQxEVa9hl_QeV9DqGMR17xc0O9tIK4h58SSfUSpbzr427H3Ivz8rsPWq8aks5nfJXjpPsbT0E9QraZ-mVZfvVm0agk433TwnyT30ly3XE4cgmDa5_C81ufu7hegc4kL4xg4sgGZ7j8DviD2krDlIGPaEanQLZKb7HguHpNueUECxx6zaDStC%26sigh%3DKextxaaV_jMJbKdvGpeCelbn074%26begin%3D0%26len%3D219560%26docid%3D2949508997989707181&thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer%3Fcontentid%3Dda9ff4564151fc83%26second%3D5%26itag%3Dw320%26urlcreated%3D1142277027%26sigh%3Djfx-jjPfzkOz2Mk4_Oc13M2OEXk&playerId=2949508997989707181" type="application/x-shockwave-flash" flashvars="playerMode=embedded" salign="TL" wmode="window" scale="noScale" bgcolor="#ffffff" quality="best" allowscriptaccess="sameDomain" /> </embed /></p>]]></description>
<date>3/13/2006</date>
<time>11:25:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=126</link>
<id>126</id></item>
<item>
<title><![CDATA[[Exchange] SMTP protocol logs are a pain to sift through]]></title>
<description><![CDATA[<p>Whenever I have to resort to parsing SMTP protocol logs I am reminded of how inefficient MS made the logging.  There are no conversation/queue/message IDs logged for each line.  So if there are five connections happening at once there is no obvious distinction between each connection.  You have the commands and responses of all them intertwined with one another, forcing you to narrow down the exact time a message is sent/received and then look through each line deducing which ones are for the message you are interested in.  Ugh.</p><p>The UNIX guys here like to give me grief about it because their Postfix logs contain the conversation/message ID on each line.  So they just do a quick grep for it and get each line that applies only to the message in question.  Figures.</p>]]></description>
<date>2/28/2006</date>
<time>8:31:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=125</link>
<id>125</id></item>
<item>
<title><![CDATA[[Exchange] Use rules to delete public folder conflict messages]]></title>
<description><![CDATA[<p>I am in a DL that has explicit ownership permissions on all public folders in my org (all 22,881 of them).  And since Exchange sends public folder conflict messages to the owner(s) of a folder, I get quite a few of them.  At one time I thought I had a rule to move or delete them, but I couldn't get it to work when I tried to set it up again.  Because the message class is different (IPM.Conflict.Folder) you don't get to see the same fields as a regular message.  Rules to delete them based on words in the sender's address, etc., had no effect, partly because the sender is the name of the folder that has the conflict, so it is a dynamic value.</p><p>Using MFCMapi to look at the properties of a conflict message, there are several properties that you'd think you could use, but when setting up a rule to use properties of the conflict message form, none of he properties are available.  And if you manually type in property name it gives you an error.</p><p>In the end, I tried setting the rule again to fire on subject contains &quot;Conflict Message:&quot; and it worked.  Huh.  So who knows what I was doing wrong before?  You can also have the rule fire if the message form is &quot;Conflict Message.&quot;</p>]]></description>
<date>2/28/2006</date>
<time>8:03:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=124</link>
<id>124</id></item>
<item>
<title><![CDATA[[Humor] Those under 30 have it so easy.]]></title>
<description><![CDATA[<p>This was forwarded to me by a coworker. And since I can relate being old at the ripe age of 32, I found this to be quite funny.</p><blockquote dir="ltr"><p>When I was a kid, adults used to bore me to tears with their tedious diatribes about how hard things were when they were growing up; what with walking twenty-five miles to school every morning, uphill BOTH ways..yadda, yadda, yadda.  And I remember promising myself that when I grew up, there was no way in heck I was going to lay a bunch of crap like that on kids about how hard I had it and how easy they've got it!<br /><br />But now...I'm over the ripe old age of thirty, I can't help but look around and notice the youth of today. You've got it so easy!  I mean, compared to my childhood, you live in a utopia! And I hate to say it, but you kids today don't know how good you've got it!<br /><br />I mean, when I was a kid we didn't have The Internet. If we wanted to know something, we had to go to the darn library and look it up ourselves, in the card catalog!!<br /><br />There was no email. We had to actually write somebody a letter - with a pen! Then you had to walk all the way across the street and put it in the mailbox and it would take like a week to get there!<br /><br />There were no MP3's or Napsters. You wanted to steal music, you had to hitchhike to the darn record store and shoplift it yourself.  Or you had to wait around all day to tape it off the radio and the DJ would usually talk over the beginning and mess it all up!<br /><br />We didn't have fancy crap like call waiting. If you were on the phone and somebody else called, they got a busy signal...that's it.<br /><br />And we didn't have fancy Caller ID boxes either. When the phone rang, you had no idea who it was!  It could be your school, your mom, your boss, your bookie, your drug dealer, a collections agent, you just didn't know. You had to pick it up and take your chances, mister!<br /><br />We didn't have any fancy Sony Playstation video games with high-resolution 3-D graphics. We had the Atari 2600, with games like &quot;Space Invaders&quot; and &quot;Asteroids,&quot; and the graphics sucked! Your guy was a little square. You actually had to use your imagination. And there were no multiple levels or screens, it was just one screen forever. And you could never win.  The game just kept getting harder and harder and faster and faster until you died...just like LIFE!<br /><br />When you went to the movie theater there no was such thing as stadium seating.  All the seats were the same height!  If a tall guy or somebody with a big hat sat in front of you and you couldn't see, you were just screwed!</p><p>Sure, we had cable television, but back then that was only like 15 channels and there was no on-screen menu. You had to use a little book called a TV Guide to find out what was on.  There was no Cartoon Network either. You could only get cartoons on Saturday morning.  Do you hear what I'm saying? We had to wait all week for cartoons, you spoiled little rats!<br /><br />And we didn't have microwaves.  If we wanted to heat something up we had to use the stove or an oven.  If we wanted popcorn, we had to use that stupid JiffyPop thing and shake it over the stove forever like an idiot.<br /><br />That's exactly what I'm talking about. You kids today have got it too easy. You're spoiled.<br />You guys wouldn't have lasted five minutes back in 1980!<br /></p></blockquote>]]></description>
<date>2/10/2006</date>
<time>10:20:00 AM</time>
<link>http://www.flobee.net/?view=plink&amp;id=123</link>
<id>123</id></item>
<item>
<title><![CDATA[[Misc] Return to your youth with a little Information Society]]></title>
<description><![CDATA[<p>As a youth of the 80s, New Wave music was all the rage (wel