Tuesday, November 11, 2008

Powershell Progress Bar with Time Countdown

I needed to add a 15 minute pause in a script that we were using to create exchange mailboxes and this little Powershell progress bar with a countdown timer worked really nice.

###===========================
### Pause Program for 15 min
### - Matt Brown, 2008
###===========================
$x = 15*60
$length = $x / 100
while($x -gt 0) {
$min = [int](([string]($x/60)).split('.')[0])
$text = " " + $min + " minutes " + ($x % 60) + " seconds left"
Write-Progress "Pausing Script" -status $text -perc ($x/$length)
start-sleep -s 1
$x--
}

Thursday, November 6, 2008

Powershell: Monitor IIS Application Pool or Site

We have an exchange IIS Application Pool stopping every so often because of some Entourage client problems. It would cause the Application Pool to stop and therefore break owa access, which was a problem.

So while we are working with Microsoft on a permanent solution I quickly put together a powershell script to run every 30 seconds and check the state of the application pool. If the MSExchangeOWAAppPool is stopped, then the script starts it. It uses the IIS Provider Tools snapin for powershell.

### -----------------------------------------------
### Written by Matt Brown - 12:46 PM 11/3/2008
### Powershell script to check MSExchangeOWAAppPool
### Requires IIS Administration Provider Tools
### -----------------------------------------------

### Make sure Snapin is loaded
$add = 1
get-PSSnapin * | foreach {
if($_.Name -match 'IIsProviderSnapIn') {
$add = 0
}
}
if($add) {
add-PSSnapin IIsProviderSnapIn
}

#######################################
######## Check AppPool State ##########
#######################################
Write-Host "`n"
Write-Host "#####################################"
Write-Host "Running check on MSExchangeOWAAppPool"
Write-Host "#####################################"
while($true) {

$state = Get-WebItemState IIS:\AppPools\MSExchangeOWAAppPool
if($state -eq "Stopped") {
Start-WebItem IIS:\AppPools\MSExchangeOWAAppPool
$now = Get-Date –f "yyyy-MM-dd HH:mm:ss"
$MsgBody = "CAS01 AppPool needed a restart " + $now
Write-Host $MsgBody
}
Start-Sleep -s 30
}

Wednesday, November 5, 2008

Powershell: New Active Directory Objects Report

Here's a quick Powershell script to send you a report of the most recent additions to Active Directory.

### --------------------------------------------
### Written by Matt Brown - 12:13 PM 10/22/2008
###
### AD Report on new objects created in the
### last 24 hours
### Requires Quest Powershell extenstions for AD
### --------------------------------------------

#######################################
####### Load Required Snapin's ########
#######################################
## Add Quest AD Snapin Tool
$addAD = 1
get-PSSnapin * | foreach {
if($_.Name -match 'quest.activeroles.admanagement') {
$addAD = 0
}
}
if($addAD) { add-PSSnapin quest.activeroles.admanagement }

#######################################
########### Setup Log File ############
#######################################
$Today=get-date
$filename="NewADObjects_"+($Today.year).ToString()+"_"
$filename+=($Today.month).ToString()+"_"+($Today.day).ToString()+".txt"

#######################################
### Get AD Formated Date 24 hrs ago ###
#######################################
$currentDate = [System.DateTime]::Now
$currentDateUtc = $currentDate.ToUniversalTime()
$creationDate = $currentDateUtc.AddHours(- 24)
$YYYY = $creationDate.Year.ToString()
$MM = $creationDate.Month.ToString();
if ($MM.Length -eq 1) {$MM="0" + $MM};
$DD = $creationDate.Day.ToString();
if ($DD.Length -eq 1) {$DD="0" + $DD};
$creationDateStr = $YYYY + $MM + $DD + '000000.0Z'

$MsgBody = "###################`n"
$MsgBody += " New AD Objects`n"
$MsgBody += "###################`n`n"

write-host $creationDateStr
$newobjects = Get-QADObject -ldapfilter "(whenCreated>=$creationDateStr)"
-SizeLimit 30000 | sort type

if($newobjects) {
$newobjects | out-file $filename
$type = ""
$newobjects | foreach {
if($_.Type -eq $type) {
$MsgBody += " " + $_.Name + "`n"
} else {
$type = $_.Type
$MsgBody += "`nNew " + $_.Type + "(s)`n"
$MsgBody += "===================================`n"
$MsgBody += " " + $_.Name + "`n"
}
}
}

#######################################
############ Email Report #############
#######################################

function SendEmail($body) {
$message = New-Object System.Net.Mail.MailMessage
$message.From = "myemail@domain.com"
$message.To.Add("myeamail@domain.com")
$message.Subject = "Active Directory - new object report"
$message.Body = $body

$smtp = New-Object System.net.Mail.SmtpClient
$smtp.Host = "smtp.mailserver.com"
$smtp.UseDefaultCredentials = $true
$smtp.Send($message)
}

SendEmail($MsgBody)

Tuesday, November 4, 2008

Update GAL Display Name - powershell

We recently decided to change on how our Global Address list is displayed from using the format to the , format.

Powershell made quick work of this task and took about 10 minutes with 2500 users. Here's the script.

###=====================================
### Update Exchange Global Address List Display
### - Matt Brown, 2008
###=====================================
$Users = Get-User -ResultSize unlimited |
where {
($_.RecipientTypeDetails -eq "MailUser")
-or ($_.RecipientTypeDetails -eq "UserMailbox")
}

ForEach ($Person in $Users) {
$NewName = $User.LastName + ", "
$NewName += $User.FirstName + " "
$NewName += $user.Initials

# get rid of trailing spaces caused by blank initials
$NewName = $NewName.Trim()
Set-User $User -Name $NewName -DisplayName $NewName
$NewName = $Null
}


Don't forget to update the OAB after this is done so your outlook clients will update.

Monday, November 3, 2008

Active Directory - Removing SID History

I use a couple of great tools from joeware.net to remove a SID from a users SID History. I had a problem where the wrong user was mapped over during a migration when we were colasping multiple domains into one.

The 2 tools I used from joeware were adfind and admod, both free.

adfind -h IT-DC01 -default -f sAMAccountName=jackuser sidhistory

dn:CN=Jack User,OU=Employees,OU=People,DC=mydomain,DC=edu
>sIDHistory: S-1-5-23-4189335451-1674751469-1023141700-3124
>sIDHistory: S-1-5-23-4217985222-169311000002009-1212232504-146495


This listed the current SID's in the history of the users account. After deciding which one I wanted to removie I used admod to remove it.

admod -b "CN=Jack User,OU=Employees,OU=People,DC=mydomain,DC=edu"
sidhistory:-:S-1-5-23-4217985222-1000002009-1212232504-146495


Sid Removed and now where ready to take that SID and add it to the correct user account.

admod -b "CN=Jackie User,OU=Employees,OU=People,DC=mydomain,DC=edu"
sidhistory:+:S-1-5-23-4217985222-1000002009-1212232504-146495

Note: I found out after this post that this option does not work with SIDHistory. You will need to use the VB Script or ADMT to migrate the sid from the source domain.

Sunday, November 2, 2008

VMWare over NFS on a NetApp - ASIS (deduplication) WOW

I have a NetApp 3040c cluster that I'm using for NFS, iSCSI and FC connectivity to my VMWare ESX Servers. NFS has proven to be fast and reliable. I'm running the following system on NFS without any problems:
  • Active Directory Domain Controller (Server 2008) - (16,000 users)
  • Exchange 2007 (CAS) Client Access Server on Server 2008
  • Exchange 2007 HUB on Server 2008
  • ILM / MIIS on Server 2003
  • IIS on Server 2003 with over 800 websites
  • IIS on Server 2008
  • Full Exchange 2007 Test enviorment (3 servers Mailbox, HUB, CAS and 1 DC)
  • Blackberry Access Server
  • Wireless Raidus Server
These Virtual Machines take up 462 GB of disk space... but the really cool part is that because I'm running these all on my NetApps over NFS with DeDuplication turned on I'm seeing a 77% storage savings... so they are only taking up 105 GB of disk space on the storage system.

sanb> df -s -g /vol/esxNFS
Filesystem used saved %saved
/vol/esxNFS/ 105GB 357GB 77%


I'll I can say is wow.

ADMT Migrating Computers from 2003 to 2008

In order to migrate computers from a 2000 or 2003 Active Directory Domain to a 2008 Active Directory Domain you need to set a group policy in your 2008 domain that allows cryptography algorithms compatible with Windows NT 4.0. Otherwise, the migration will bring the computer account over but will not change the domain the computer is in.

You can find this Group Policy setting here:
In the Group Policy Management Editor console, expand Computer Configuration, expand Policies, expand Administrative Templates, expand System, click Net Logon, and then double-click Allow cryptography algorithms compatible with Windows NT 4.0. Based on (http://support.microsoft.com/kb/942564)

Another thing I found was that that Target Domain Account you are using to transfer the computers over need to have local admin privileges on the systems you are migrating from the source domain and the ADMT System needs to have access to the computer. (IE: Firewall opened for at least that machine).