Wednesday, September 10, 2014

Apple Keynote Podcast Feeds

I wanted the direct links to the downloads to throw the latest keynote on a network share. I didn't find the direct links to Apple's feeds anywhere with a quick search, so I extracted them from iTunes. Here they are for you.

Friday, September 5, 2014

Uninstall Dropbox Script

The script simply searches for DropboxUninstaller.exe and if found, runs is with the /S switch. Time consuming script as it searches the hard drive. This could be done better...but meh.


' Search computer for Dropbox installation and uninstall Dropbox if found.
' Created by Andrew Zbikowski  
' Version: 2013-06-10_01
' Tested against Dropbox version 2.0.23 
Option Explicit

' Objects
Dim objShell, objWMI, objFile
' Collections
Dim colFiles
' Strings
Dim strFileQuery, strComputer, strUninstallCmd

Set objShell = WScript.CreateObject("WScript.Shell") 

strComputer = "."
Set objWMI = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")

strFileQuery = "SELECT Name FROM CIM_DataFile WHERE filename = 'DropboxUninstaller' AND extension = 'exe'"

Set colFiles = objWMI.ExecQuery(strFileQuery)

if colFiles.Count > 0 Then
For Each objFile in colFiles
On Error Resume Next
strUninstallCmd = Chr(34) & objFile.Name & Chr(34) & " /S"
objShell.Run strUninstallCmd,0,True ' Run uninstaller, wait for it to finish. 
End If


Tuesday, October 30, 2012

Managing Your Photo Collection

A few months ago I decided to rework my workflow for importing, managing, and sorting my photo collection. Since our daughter was born the number of pictures taken we take with digital cameras and iPhones has exploded. Previously my workflow consisted of tag all the faces when the photos are imported and flag the good ones and create smart albums in iPhoto that included a date range for every month.

Unfortunately that just wasn't sufficient with the number of photos being added to my iPhoto library. Friends and family did want to see pictures, but hundreds of new photos showed up with no real sorting between quality and crap is too much, but when you have a new born baby in the house this simple workflow might be all you can manage.

Fast forward three years and I'm still using the I'm getting no sleep with a newborn workflow. Now that I'm better rested, it might be time to improve things.  My first rule of tagging faces immediately after importing photos into iPhoto was a good one, and that part of the workflow remains. I abandoned the flagged photo idea entirely and cleared all flags from my photos.

My new workflow starts the same as my old workflow. Import photos and tag all faces in those photos. To improve photo management from this point, I decided to use iPhoto's star rating system and give all my photos a rating. I made up a number of rules for defining what makes a 3 star vs. a 5 star photo. The goal of rating every photo was to have a way to sort out the good from the bad. iPhoto can use photo ratings in Smart Albums (Saved Searches), so I could keep the strategy of creating smart albums that matched faces and date ranges, but also include the photo ratings so that only good photos appear in the albums that get shared.

To start, I decided I needed to decide what each star rating would mean. I came up with this:
  • 1 Star Rating: This is a bad photo. 
  • 2 Star Rating: Not horrible, but not worth sharing. 
  • 3 Star Rating: Average Photo. It can show up on screen savers, but it won't be shared. 
  • 4 Star Rating: Above Average and worth sharing with family and friends. 
  • 5 Star Rating: Sharing this is a no brainer. This should be in a museum.
Photo Rating Rules
  1. Start with a 2 star rating. 
  2. Add one star for a known face (of someone you like) in the photo. No extra star for people you know but don't like, and no stars for complete strangers. Add two stars if there are two or more likable people in the photo. This rule adds a maximum of two stars, so no additional stars for three or more faces. 
  3. Add one star for artistic, sentimental, or other positive photo attributes. For example, a photo of my Grandfather who passed away a few years ago usually get an extra star. 
  4. If the photo has something extra special in it, add a star.
Now each photo should have a rating of three stars or higher. Time for deductions.
  1. Remove a star for out of focus photos unless this is intentional or adds to the artistic value of the photo.
  2. Remove a star for motion blur unless this is intentional or adds to the artistic value of the photo. 
  3. Remove a star for figure covering the camera lens or other items that detract from a photo and can't be cropped or edited out of the photo. 
  4. Remove a star for other things that can't be digitally corrected such as uncorrectable red eye, digital artifacts, random stranger photo bombs, a dogs butt in the photo, etc. 
  5. Remove a star if if you only see the back of the main subject's head. This is optional, but I've found in most cases it's a good idea. 
The ToDo Albums
In addition to rating photos, I also have a number of "ToDo" albums created in iPhoto. When I'm importing photos I may not have time to do the retouching, cropping, etc. Instead of worrying about these tasks as I'm rating my photos, I add these photos to one of my "ToDo albums." When I have time and the inclination to work on photo fixes, all I have to do is look at the ToDo albums to find photos that need some work.

Example ToDo Albums:
  • TODO: Retouch
  • TODO: Crop
  • TODO: Incorrect Date
Dealing With No Rating Photos
My iPhoto library has thousands of photos in in, and because I'm implementing a new system those photos will not have star ratings. I could create a smart album to simply show me all my photos with a rating less than one star, but that would have shown me my entire photo collection. That would be a daunting task.

To get past what would otherwise appear to be an impossible task, I used smart albums to break up this task and create obtainable milestones. I started with early years before having a child. There were fewer photos taken in these years so doing an entire year was an obtainable milestone. For the years after my daughter was born I went with my month by month strategy for rating photos. Bit by bit my photos are getting rated and the new system is working out quite well. As I knock out a month, I simply update my Unrated Photos Smart Album and work on the next milestone.

Example Criteria for Unrated Photos Smart Album:
  • Rating is less than one star
  • Date is in the range 10/1/2010 to 10/31/2010
So far my new workflow is working out quite well, and sharing the new four and five star photos with friends and family has gone over well. No more dumps of hundreds of photos into an online photo gallery, only the best photos in my collection get seen.

Wednesday, September 5, 2012

Enable AirDrop on any Mac

AirDrop is a feature in Mac OSX Lion for transferring files between two Macs, great feature my my wife's Mac is on the list of Macs that do not support AirDrop. Yesterday while working on an unrelated issue, I discovered that the Deeper tool has an option to activate AirDrop on any Mac running Lion or higher. So I gave it a try, and sure enough my wife's plastic MacBook was able to see my own Mac via AirDrop. My Mac however was not able to see my wife's Mac. As it was after midnight I didn't spend any time figuring out why.

This can also be enabled via the command line, so installing an extra tool isn't required: 

defaults write BrowseAllInterfaces 1

Tuesday, June 12, 2012

UltraViolet Follow Up

My order arrived today. Another DVD/Blu-Ray combo pack with UltraViolet digital copy. Since my last experience with UltraViolet was less than stellar, I took some notes on my second experience to see if things had improved. This time around my UltraViolet and Flixter accounts have been setup, and those accounts are configured on my iPad, iPhone, and on my Mac. All that mess of setting up accounts, linking accounts, and logging in has been taken care of. UltraViolet streaming should be no problem now, right? (TL;DR version: Nope, still a horrible experience.)

Redemption code from the DVD box in hand, I log into Fkixter and click the "Redeem Now" button at the top of Flixter's page. Instead of being presented with a form to enter my redemption code, I'm presented with a list of movies available on UltraViolet. No option to search and filter, no genre grouping. The only option is to scroll through the list and find your movie. This should be easy right? With no option to sort and filter, it would make sense to sort movies alphabetically. 

Here is the exact order of the movies listed:
  1. Horrible Bosses
  2. Green Lantern
  3. Crazy, Stupid, Love
  4. Harry Potter and the Deathly Hallows - Part 1
  5. Harry Potter and the Deathly Hallows - Part 2
  6. The Hangover Part II
  7. The Smurfs
  8. Cowboys & Aliens
  9. Friends With Benefits
  10. Dolphin Tale
  11. One Tree Hill: The Complete Eighth Season
  12. Underworld Trilogy
  13. Colombiana (Unrated)
  14. Final Destination 5
  15. Shameless Season One
  16. Contagion
  17. Don't Be Afraid of the Dark
  18. The Scorpion King 3: Battle for Redemption
  19. Killer Elite
  20. Moneyball
  21. The Ides of March
  22. Courageous
  23. The Thing
  24. Dream House
  25. Drive
  26. A Very Harold & Kumar Christmas
  27. The Loras
  28. J. Edgar
  29. Honey 2
  30. Tower Heist
  31. Johnny Englis Reborn
  32. Justice League Doom
  33. The Town
  34. Monty Python And The Holy Grail
  35. Jack and Jill
  36. Happy Feet Two
  37. Scooby-Doo! Music of the VAmpire
  38. The Girl with the Dragon Tattoo
  39. Tinker, Taylor, Soldier, Spy
  40. Hop
  41. Extremely Loud & Incredibly Close
  42. One Tree Hill: The Complete Ninth Season
  43. IMAX: BornTo Be Wild
  44. Contraband
  45. New Years Eve
  46. Joyful Noise
  47. Men In Black
  48. Suits, Season 1
  49. Men In Black II
  50. The Dark Knight
  51. Batman Begins
  52. Cold War: The Complete Series
  53. Chuck Season 5
  54. Underworld: The Legacy Collection
  55. The Vow
  56. Spider-Man
  57. Spider-Man 2
  58. Spider-Man 3
  59. The Grey
  60. The Woman in Black
  61. Rizzoli & Isles Season 2
  62. True Blood Season 1
  63. True Blood Season 2
  64. True Blood Season 3
  65. True Blood Season 4 
  66. Journey 2: The Mysterious Island
  67. Save House
  68. Pretty Little Liars Season 2
  69. Falling Skies Season 1
  70. Superman Vs. the Elite
  71. Too Big to Fail
  72. Sherlock Holmes: A Game of Shadows
OK, so we have TV and Movies mixed together. As best I can tell, they are sorted by the date they were made availabe on UltraViolet's distribution system with the newest releases at the end of the list. Don't you typically put your newest products on the top of the list, at the front of the store, or on a marble pedestal so that everyone can easily see (and buy) what's new? So far UltraViolet Digital Distribution continues to defy logic.

And another comparison, redeeming a code in iTunes is simple. You click the "Redeem" link on the front page of the iTunes store, enter your code, and iTunes brings you to the product that code is for. It doesn't matter if the code is for an iTunes gift card, a digital copy of a movie, an iTunes pre-order card purchased in a store, whatever. Click redeem, enter code, get product. Why can't UltraViolet do the same? I have a code that uniquely identifies my purchase. Presumably they know what movie the code is for, but first I have to find my movie and click on it in order to redeem my code. 

OK, so I've clicked the redeem button, I've found and clicked on my movie. And now I'm presented with a larger picture of my movie. The exact same picture on the Blu-Ray box, and a description of UltraViolet:UltraViolet makes it possible for you to watch the digital movies you own anytime, anywhere, any way you want. Thanks guys, I needed to know that. Why else would I be here in the first place? The printed instructions told me to go here! Next up, instructions for the redemption process:

What You'll Need
Redemption code found inside your Blu-ray or DVD package. Offer valid only in US.

News flash: I have the box, I have my code, you should have given me a field to enter my redeem code immediately after clicking the redeem button on the main page Flixter.

So, one more click on the Get Started Button (three so far) and yes, here it is, the Redeem Code field and button! Enter code, and please wait. And please wait. And Please wait. OK now I'm redirected to this is a slow Web site...yes I had enough time to type "wow this is a slow Web site" into the notes I'm keeping as I'm going through the redemption process. It truly is a slow site. Patience prevails, and my movie has been added to my collection.

UltraViolet may be the first out of the gate, but Apple and Disney are working on Keychest, or some competitior to UltraViolet. They aren't even on the market with their system, but with Apple involved it would be a safe bet that the Apple/Disney venture will blow UltraViolet out of the water experience wise when they do come to market.

The audio issues (distortion, peaking, whatever an audio engineer would call it) I mentioned in my previous write up are still there in the UltraViolet digital edition (download and streaming.) Again the audio issues persist across multiple devices, headphones, and speakers. Something is very wrong with the encoding process.

Monday, June 11, 2012

Active Directory Password Expiration Email Notification

This is a PowerShell script that will send an email notification to Active Directory users when their password will expire in 14, 7, 3, 1, and Zero days. Administrators/helpdesk also get a daily report of passwords that are expired and the users who got an email reminder, a great heads up for your helpdesk.

The script generates a different message when there are zero days remaining (password is expired and must be changed today) and won't continue to notify users when there are less than zero days remaining. Negitive dedlines are used for some account options such as the passwords must be changed at next logon account flag, and you don't want to fill up a user's mailbox when they can't access their mail before changing their password anyway.

To setup the script, search for the "# CONFIG:" strings and edit the following line as documented, then set it up on a server as a daily scheduled task.

Active Directory Password Expiration Email Notification Script
Import-Module ActiveDirectory

$summarybody="Name `t ExpireDate `t DaysToExpire `n"

(Get-ADUser -filter {(mail -like "*") -and (Enabled -eq "True") -and (PasswordNeverExpires -eq "False")} -properties *) | Sort-Object pwdLastSet |
foreach-object {

    $daystoexpire=[math]::round((New-TimeSpan -Start $(Get-Date) -End $expires).TotalDays)
    if (($daystoexpire -eq 14) -or ($daystoexpire -eq 7) -or ($daystoexpire -eq 3) -or ($daystoexpire -eq 1) -or ($daystoexpire -eq 0)) {
    #if ($daystoexpire -le 14) {
         # CONFIG: Enter from email address.
        $emailFrom = ""
        # CONFIG: Replace domain with your email domain. Do not change $samname.
        $emailTo = "$"
        if ($daystoexpire -eq 0) {
        # CONFIG: Enter text for subject and body of email notification for zero days remaining.
            $subject = "$firstname, your password has expried!"
            $body = "$firstname,
Your password has expired and you must change it immediately. No further email notifications will be sent.

Contact support at extension XXXX for assistance."
        Else {
        # CONFIG: Enter text for subject and body of email notification for 14, 7, 3, and 1 days remaining. 
            $subject = "$firstname, your password expires in $daystoexpire day(s)!"
            $body = "$firstname,
Your password expires in $daystoexpire day(s).

If you are using a Windows computer, press Ctrl + Alt + Del the click Change password.

If you are using a Mac computer follow the instructions at http://sharepoint/Documentation to change your password.
        # CONFIG: Enter your smtp server here.
        $smtpServer = ""
        $smtp = new-object Net.Mail.SmtpClient($smtpServer)
        $smtp.Send($emailFrom, $emailTo, $subject, $body)   
        $summarybody += "$samname `t $expires `t $daystoexpire `n"
    elseif ($daystoexpire -lt 0) {
        # Add a note to the report email, but don't notify user.
        $summarybody += "$samname `t $expires `t $daystoexpire `n"
if ($ThereAreExpiring) {
    # CONFIG: From address for report to Helpdesk/IT Admin staff.
    $emailFrom = ""
    # CONFIG: Address to send report email to (for Helpdesk/IT Admin staff.
    $emailTo = ""
    # CONFIG: Subject for report email.
    $subject = "Expiring passwords"
    $body = $summarybody
    # CONFIG: SMTP Server.
    $smtpServer = ""
    $smtp = new-object Net.Mail.SmtpClient($smtpServer)
    $smtp.Send($emailFrom, $emailTo, $subject, $body)

Thursday, May 31, 2012

Active Directory Account Lockout Notifications using PowerShell

I've found it's often helpful to get an email notification when an Active Directory account is locked out. In a previous job we used Account Lockout Examiner from NetWrix for this functionality. A few years and a job or two later and I've found a way to do this with the Windows Task Scheduler and PowerShell. You also need to have a Windows Server 2008 Domain Controller. Your Active Directory domain does not need to be in 2008 Native Mode.

Before going on, I should mention that the following scripts were originally created by Joe0126 and shared in this post on the SpiceWorks Community site. I simply took what Joe0126 created and updated the output to meet my needs. The email notification will look like this:

Subject: Account Locked Out: ADDOMAIN\username
Email Body:
Account Name: ADDOMAIN\username
Time: 05/28/2012 17:45:43

In the case of an account lock event, the workstation will tell you what computer or server the account was locked out on. Usually this will be the user's workstation or one of your Exchange CAS servers. If the lockout happened on a computer that isn't joined to the domain workstation will be blank.

The account unlock notification is slightly different. The workstation will be the workstation AD Users and Computers is running on, and who is responsible for unlocking the account will be in the notification as well.

Subject: Account Unlocked: ADDOMAIN\username
Email Body:
Account Name: ADDOMAIN\username
Time: 05/29/2012 11:03:31

Unlocked By:

To start, grab the code for the scripts below. One will generate an email notification for an account lock event, the other will generate an email notification for an account unlock event. Update the script with the SMTP server and email addresses for your domain (update lines with and save them to your Domain Controller.

On your domain controller, open Task Scheduler and create a new task (Not create basic task). Your trigger should be "On an Event." Select the Security Log and enter 4740 for the EventID. EventID 4740 is an Account Lock. For your action run your PowerShell Script. For the unlock notification, do the same for EventID 4767 and use the Unlock Notification Script.

Notifications won't be instantaneous as PowerShell's get-eventlog commandlet isn't very fast when it comes to finding events in the Windows log, but it has been fast enough for our environment. In most cases we get the account lockout notification before the user calls the helpdesk to report a problem.

Account Lock Notification Script:
$SMTPServer = ""
$MailFrom = ""
$MailTo = ""

Import-Module activedirectory

$Event=Get-EventLog -LogName "Security" -InstanceId "4740" -Newest 1000

$User = $Event.ReplacementStrings[0]

$Computer = $Event.ReplacementStrings[1]

$Domain = $Event.ReplacementStrings[5]

$MailSubject= "Account Locked Out: " + $Domain + "\" + $User

$MailBody = "Account Name: " + $Domain + "\" + $User + "`r`n" + "Workstation: " + $Computer + "`r`n" + "Time: " + $Event.TimeGenerated + "`r`n"

$lockedAccounts = Search-ADAccount -LockedOut | Select -Property SamAccountName | Out-String

$MailBody = $MailBody + "`r`nThe following accounts are currently locked out:`r`n" +  $lockedAccounts

Send-MailMessage -To $MailTo -From $MailFrom -Subject $MailSubject -SmtpServer $SMTPServer -Body $MailBody

Account Unlock Notification Script:
$SMTPServer = ""
$MailFrom = ""
$MailTo = ""

Import-Module activedirectory

$Event=Get-EventLog -LogName "Security" -InstanceId "4767" -Newest 1000

$User = $Event.ReplacementStrings[0]

$Domain = $Event.ReplacementStrings[1]

$UnlockBy =  $Event.ReplacementStrings[4]

$UnlockByDomain = $Event.ReplacementStrings[5]

$Computer = $Event.MachineName

$MailSubject= "Account Unlocked: " + $Domain + "\" + $User

$MailBody = "Account Name: " + $Domain + "\" + $User + "`r`n" + "Workstation: " + $Computer + "`r`n" + "Time: " + $Event.TimeGenerated + "`r`n`r`n Unlocked By: " + $UnlockByDomain + "\" + $UnlockBy

Send-MailMessage -To $MailTo -From $MailFrom -Subject $MailSubject -SmtpServer $SMTPServer -Body $MailBody

For the extra lazy, unlock everyone:
Import-Module activedirectory
Search-ADAccount -LockedOut | Unlock-ADAccount

Update 1, 2012-06-18: I added the Unlock notification to all our Server 2008 R2 domain controllers. We were only getting notifications when an account was unlocked on the domain controller running the script. I don't think this is a similar issue with the lock notification script.

Update 2, 2014-12-29: Checked this post and found I've made a few more improvements since my last posting. Configuration for mail server is now at the top, and I added a line to get all locked accounts to the lock notification, just in case your IT Service Desk missed a few accounts. Also added PowerShell to unlock all locked accounts. Use with caution obviously.