Woo hoo, my first PowerShell script!

This PowerShell script replicates the basic functionality of my Exchange Mailbox export HTA script. Rather quickly, it exports the following values (for all accounts with an email address) :

  • First name (givenname)
  • Last name (sn)
  • Distinguished name
  • Primary SMTP Address (mail)
  • User Logon name (userprincipalname)
  • User Logon name "Pre-Windows 2000" (sAMAccountName)
  • All secondary email addresses (proxyaddresses)

get-qaduser -dontusedefaultincludedproperties -ObjectAttributes @{mail='*'} -includedproperties sAMAccountName,employeeid,distinguishedname,mail,userprincipalname,givenname,sn,proxyaddresses -searchroot 'corp.ent/SBSUsers/_A - G' -serializevalues -sizelimit 0 | export-csv 'c:\Accounts_mail_A-G.csv'

To run this script, you will need to download and install the latest Quest tools. If you would like to include or change the fields (GivenName, employeeID, etc.) it pulls, don't expect to pull all the user properties as defined by:

Get-QADUser -IncludeAllProperties -ReturnPropertyNamesOnly

I kept trying, but getting only a few fields. Looked like I would get up to the first field that it could not query, then would drop the rest in the request. It appears to want the LDAP equivalents. Maybe I was just phrasing my query wrong, but I still can't pull the 'initials' value for anyone (and I know it is populated.)

I have recently revised this script that exports a few more fields from specific OUs.

PowerShell - Find all enabled AD users

A friend is working on a script to pull active LCS accounts from his AD. One last bit of information that he that was troubling him was enabled/disabled AD accounts.

Reading the Scripting Guys article, I found a switch that will tell all disabled AD accounts. Perfect, but just the opposite of what he wanted. Reading deeper, they state that when the bit is set to 2, it shows disabled accounts, so I implied that when it's set to (something else??) 0 (or 1) it must be enabled. Tested 1, nope. Then I found this article that shown that using a NOT statement will return what I was looking for.

This tiny script will query your current AD environment and return all ENABLED accounts in the environment.

get-qaduser -includeallproperties -ldapfilter "(!(userAccountControl:1.2.840.113556.1.4.803:=2))"

The "-includeallproperties" switch is required, otherwise you will get all accounts, and not those that apply to the LDAP filter.

Note, if you haven't already done so, you'll need to download and configure the Quest ActiveRoles Management Shell to run this query. This article helped me setup my environment and includes links to the various tools I use.

Powershell - Enumerate Delegate Rights for a mailbox

Troubleshooting Outlook delegate permissions is a pain. I found the easiest way to get a user's delegates is to create a profile, open their mailbox and check each person.

That's why I created this script. Using the Quest Powershell addons for AD, it reads the delegate permissions for a specified mailbox, then looks up the display name for each delegate or mailbox they are a delegate for.

I'd like to clean up the results a little more, but for now this works nicely.

$entry = Read-Host "Display name of mailbox"
if ($entry -ne $null) {
        $a= Get-QADUser $entry -ldapfilter '(mail=*)' -IncludedProperties displayname, publicdelegates, publicdelegatesbl
        foreach ($user in $a) {
                $user.displayname
                "================================="
                if ($user.publicdelegates -eq $null) {
                        Write-host "Has no delegates"
                } else
                {      
                        Write-host "Delegates:"
                    $b = $user.publicdelegates;
                        foreach ($del in $b) {Get-QADUser $del | select-object displayname| sort-object displayname};
                        "    "
                }
               
                if ($user.publicdelegatesbl -eq $null) {
                        Write-host "Is not a delegate"
                } else
                {
                                Write-Host 'Is a delegate for:'
                            $b = $user.publicdelegatesbl;
                                foreach ($del in $b) {Get-QADUser $del |select-object displayname| sort-object displayname};
                                "    "
                        }
                "    "
        }
}

AttachmentSize
EnumerateDelegates.ps1848 bytes

Powershell Script #2 - Getting last logon date for Exchange mailboxes

I have been attempting to do some cleanup of the Active Directory environment. My latest endeavor is to capture the last logon time from AD and correlate it to active accounts. If they're not logging on, maybe they don't know how, or don't need a mailbox??

My script here, will query all the Exchange servers for user display name and last logon time (LastLogonTime). Since the last logon is a 64-bit integer, you need to do some special handling of it. I found a number of tricks that used bit-level handling to convert the value to a date-time format, but after some pointing and nudging, I realized the simplicity of simply pulling it apart as a string value.

Last bit, I wanted a single CSV file for all my Exchange servers. There is no way I wanted to have 8 CSV files to sort through for all the mailbox information. Even more so, I didn't want to have to merge them all back together, this is a computer I am spending my life in front of.

Finally, I have to thank Microsoft for a great resource for converting my VBScript experience into Powershell. This site is an easy to understand reference for experienced VB scriptter who want to quickly learn PS.

Update (May 2008): In the BETA version of the Quest Active Roles Management shell includes a lastlogon field. This means you can quickly export the data without special formatting (like below).

Get-QADUser -SearchRoot 'your.domain.local/' -IncludeAllProperties | Format-List name, lastlogon*, accountis*

For each account on your domain, this script returns.
Name: guest
LastLogonTimeStamp: May 1, 2008
LastLogon: May 7, 2008
AccountIsDisabled: False
AccountIsLocked: False
...

Re-route this to a CSV file, and you have something to share with the whole family!

Thanks Quest, Nice addition to this tool!

[end update]

#        Name:  get-lastlogon.ps1
#      Author:  Eric Woodford - <a href="http://www.ericwoodford.com
#" title="www.ericwoodford.com
#">www.ericwoodford.com
#</a>        Date:  09/26/2007
#        Description:  Mailbox last logon information to single CSV file.
#              Display Name, Last Logon Time
#

#create header for CSV file.
$CSVFilePath = 'c:\mail_LastLogon.csv'
$strDate = get-date -uformat "%Y/%m/%d"
$strDate | out-file -filepath $CSVFilePath -encoding ascii
$strOutputString = "Display Name,LastLogonTime"
$strOutputString | out-file -filepath $CSVFilePath -encoding ascii -append

#set this to match your environment.
$Computers = get-qadComputer -searchRoot 'corp.ent/Member Servers/Exchange Servers'
foreach ($computer in $computers) {
        $users = Get-Wmiobject -namespace root\MicrosoftExchangeV2 -class Exchange_Mailbox -computer $computer.name | Select-Object MailBoxDisplayName, LastLogonTime
        # Get-Wmiobject -namespace root\MicrosoftExchangeV2 -class Exchange_Mailbox -computer $computer.name | Select-Object MailBoxDisplayName, LastLogonTime
        foreach ($user in $users) {
                   $date= [string] $user.LastLogonTime
                   if ($date.length -eq 0) {
                        $strOutputString = """"+ $user.MailBoxDisplayName + """, N/A"                          
                }
                else {
                        $strOutputString = """"+ $user.MailBoxDisplayName + """," + $date.substring(4,2)+"/"+$date.substring(6,2) +"/"+ $date.substring(0,4)
                }
           $strOutputString | out-file -filepath $CSVFilePath -encoding ascii -append
        }
}