Monday, November 2, 2009

Live @ Edu hotmail active mailboxes

I run a live@edu hotmail system at our school and I needed a way to find out which mailboxes were not longer active (I.E. student hasn't logged in for 365 days). So I put together this little python script to make an SMTP connection on each address load the status into a mysql database.


#######################################
## Written by Matt Brown
## - check hotmail mailbox status active / inactive
## - for live @ edu hotmail accounts
########################################

import smtplib
import fsdb
import time

##-------------------------------------------
def ConnectMySQL(name,debug=0):
fsdb.register_connection(name, 'mydb_ip', 'mydb', 'mydbuser', 'mydbpass')
fsdb.set_debug(debug)
return fsdb
#----------------------------------------------------
def CloseMySQL(name):
fsdb.unregister_connection(name)
#----------------------------------------------------
def RunMySQLQuery(fsdb,query):
return fsdb.query(query,None)
#----------------------------------------------------

count = 0
try:
name ="email"
fsdb = ConnectMySQL(name)
email_accounts = RunMySQLQuery(fsdb,"select id,email from addresses_table WHERE active_mailbox='0'")

s = smtplib.SMTP('pamx1.hotmail.com','25','localhost')
s.ehlo('verify')
s.mail('admin@mydomain.com')

for user in email_accounts:
mbstatus = s.rcpt(user[1])
if mbstatus[0] == 550:
print user, "inactive"
RunMySQLQuery(fsdb,"update addresses_table set active_mailbox=0,mailbox_check=NOW() WHERE id="+str(user[0]))
elif mbstatus[0] == 250:
print user, "active"
RunMySQLQuery(fsdb,"update addresses_table set mailbox_check=NOW() WHERE id="+str(user[0]))
count = count + 1
else:
print mbstatus[0], mbstatus

# hotmail only allows 10 recipiants
if count == 9:
count = 0
time.sleep(2) # pause so we don't get black listed
s.rset
s = smtplib.SMTP('pamx1.hotmail.com','25','localhost')
s.ehlo('verify')
s.mail('admin@mydomain.com')

CloseMySQL(name)

except Exception,e:
CloseMySQL(name)
print e

mysql random password

I needed a quick way to create a random password for a large number of users in mysql.


SELECT SUBSTRING( MD5( RAND() ) FROM 1 FOR 8 ) AS PASSWORD;

Monday, October 12, 2009

Powershell - Terminate Employee in Active Directory

Here's a quick little script to terminate an employee in Active Directory. I'm using the quest AD Powershell command-lets in this script. This uses powershell to disable the AD Account, Change the AD password to a random password, set the description of the account and remove all the group membership from the account.

Input text file looks like this:
empID
08791
08792


Powershell Script:

# ---------------------------
# Add Quest AD Snapin
# ---------------------------
if(-not (Get-PSSnapin | where { $_.Name -match 'quest.activeroles.admanagement' })) {
add-PSSnapin quest.activeroles.admanagement
}
# Load Assembly so we can easily generate a random password.[Reflection.Assembly]::LoadWithPartialName(”System.Web”)

$s = get-credential
connect-qadservice -credential $s -Service "mydomain.com"

Import-Csv "employeeIDList.txt" | foreach {
$user = get-QADObject -SearchRoot 'mydomain.com/People' -Type User -ldapFilter "(employeeID=$_.empID)"
if($user) {
write-host "Disabling " $user.samAccountName
# generate random password
$ranpassword = [System.Web.Security.Membership]::GeneratePassword(10,2)
# Disable User Account
$user | Disable-QADUser
# Set User's Description to Terminated and set a random password
$user | set-QADUser -Description "Terminated" -UserPassword $ranpassword
# Remove User from all Groups (does not include domain users)
$user.memberof | Get-QADGroup | Remove-QADGroupMember -member $user
# Move user to Terminated OU
$user | Move-QADUser -NewParentContainer 'mydomain.com/Terminated'
} else {
write-host $_.empID "not found in Active Directory"
}
$user = $False
}

Saturday, October 10, 2009

SMTP Relay with Exchange 2007 - part 2

Problem: I needed to add new applications / servers to the SMTP Relay Connector and document the additions.

Solution: Powershell script that reads a csv file with needed server / application / admin info. It then adds the IP address to the connector and logs the info to another CSV file.

CSV Files looks like this:
IP,Server,Admin,Application,fromaddr
10.0.0.1,SQL01,John Doe,SQL Mailer,jdoe@mydomain.com

Powershell script

----------------------------------

# Grab all our current connectors - should be 1 per hub server
$Connectors = Get-ReceiveConnector | where { $_.Name -eq "SMTP-Relay" }

# set value to current IP listed in first connector found
$ip = $connectors[0].RemoteIpRanges

# Open the File of IPs to add
$import = Import-Csv "1-NewSMTPRelayAddress.txt"
$updateConnector = $false

# Loop through CSV File
$import | Foreach {
# Set Vars
$newip = $_.ip

# Update Documentation (IP, Server, Admin, Application, Date Access Granted)
$thedate2 = Get-Date -f "yyyy-MM-dd HH:mm"
$out = $newip + "," + $_.Server + "," + $_.Admin + ","
$out += $_.Application + "," + $_.fromaddr + "," + $thedate2 + "`n"
$out | out-file SMTP_Relay_Access.csv -append

# add new ip to the list
$ip += $newip

# set a var so we know we need to update the connectors
$updateConnector = $true
}


if($updateConnector) {
# add those to all the connectors
$Connectors | Set-ReceiveConnector -RemoteIPRanges $ip
Write-host "The Following IPs are in the Connector" $ip

# Log run and clear file
$newname = $thedate + "_IPsAdded.txt"
copy-item -path "1-NewSMTPRelayAddress.txt" -destination "Log\$newname"
"IP,Server,Admin,Application,fromaddr" | out-file 1-NewSMTPRelayAddress.txt
} else {
write-host "No addresses found in the file"
}

Friday, October 9, 2009

SMTP Relay with Exchange 2007 - Part 1

Problem: We needed to allow specific servers / applications to send through our Exchange servers without first authenticating.

Solution: In order to do this we setup a send connector on our Exchange HUB servers that allowed any of the specified IP's to send without authentication.

Powershell to setup the Exchange Connector:

$remoteserver = '10.0.0.1'
$emaildomain = 'mydomain.com'
$HubServers = get-exchangeserver | where { $_.ServerRole -match "HubTransport" }
$HubServers | new-ReceiveConnector -Name 'SMTP-Relay' -Usage 'Custom' -Bindings '0.0.0.0:25' -Fqdn 'mydomain.com' -RemoteIPRanges '10.0.0.1' -AuthMechanism Tls,ExternalAuthoritative -PermissionGroups ExchangeServers

Tuesday, September 29, 2009

Powershell MySQL (insert)

Here's a quick script to write (insert) data into a mysql database using powershell.

function ConnectMySQL([string]$user,[string]$pass,[string]$MySQLHost,[string]$database) {

# Load MySQL .NET Connector Objects
[void][system.reflection.Assembly]::LoadWithPartialName("MySql.Data")

# Open Connection
$connStr = "server=" + $MySQLHost + ";port=3306;uid=" + $user + ";pwd=" + $pass + ";database="+$database+";Pooling=FALSE"
$conn = New-Object MySql.Data.MySqlClient.MySqlConnection($connStr)
$conn.Open()
$cmd = New-Object MySql.Data.MySqlClient.MySqlCommand("USE $database", $conn)
return $conn

}

function WriteMySQLQuery($conn, [string]$query) {

$command = $conn.CreateCommand()
$command.CommandText = $query
$RowsInserted = $command.ExecuteNonQuery()
$command.Dispose()
if ($RowsInserted) {
return $RowInserted
} else {
return $false
}
}

# setup vars
$user = 'myuser'
$pass = 'mypass'
$database = 'mydatabase'
$MySQLHost = 'database.server.com'

# Connect to MySQL Database
$conn = ConnectMySQL $user $pass $MySQLHost $database

# Read all the records from table
$query = 'INSERT INTO test (id,name,age) VALUES ("1","Joe","33")'
$Rows = WriteMySQLQuery $conn $query
Write-Host $Rows " inserted into database"

This code requires the MySQL ADO Connector. (http://dev.mysql.com/)

Sunday, May 31, 2009

Exchange 2007 Public Folder Setup - powershell

In this example I'm setting up a Public Folder structure for departmental Absence or Leave Calendars, Giving departments an shared calendar that can be used to track vacation, sick leave, holiday's, etc. What I do first is create the top level Public Folder called Absence Calendars. I then grant my username owner rights on that new Public Folder. Now I can do the rest of the setup (create calendar and setup permissions) directly from my outlook client. Note: I could optionally create a department Public Folder under the Absence Calendars folder if needed and then create the calendar under that.


New-PublicFolder -Name 'Absence Calendars' -Path '\' -Server 'mbx01.company.com'
New-PublicFolder -Name 'Accounts Payable' -Path '\Absence Calendars' -Server 'mbx01.company.com'
Add-PublicFolderClientPermission -User username -AccessRights owner -Identity "\Absence Calendars\Accounts Payable"

Once in Outlook open up the Folder List (Go -> Folder List) to see the public Folders (it's at the bottom). You should see the new folder created (in our case Absence Calendars). Right click on the Absence Calendars public folder and go to Create New Folder. In the Create New Folder dialog Choose Calendar Items and a name (I chose AP - Leave).


Now, right click on the new Calendar you just created and select "Change Sharing Permissions...". I usually set the department manager as the Editor and set everybody else to Author. This gives employees the ability to add items to the Calendar and allows the Manager to add / delete all the items. You may want to lock this down further by only allowing the employee's the ability to see the calendar and have the manager add all items once approved. In this case you should set the Default to Reviewer, Anonymous to None, and Manager(s) to Editor.






Monday, April 6, 2009

Removing Other Users Folder from Outlook on Exchange

Question:
How do I remove another user's data folder or inbox that I have showing up in my outlook profile? When I right click and go to close folder it tells me to go to account settings and when I go to account settings it only show's my account.

Answer:
1. Select your Main Outlook Profile (Mailbox - )
2. Right click and go to Properties for "Mailbox - "
3. Under General Tab click on the Advanced Button
4. Click on the Advanced Tab
5. Under Mailboxes, find the mailbox you want to remove and click remove.
6. Click ok and the mailbox should be gone.

Saturday, March 14, 2009

VMWare vMotion not working on ESX VDI (VMWare View)

After clean installs of my 2 ESX VDI systems (now VMWare View) I was unable to get a successful vMotion from one host to the next. I was also having issues getting HA properly configure although after a bit of moving it around, creating a new cluster with a new name and moving the host into that it finally configured. All that said, vMotion still did not work.

After a bit of googling, I found that removing the Virtual Center Agent from the ESX Host and re-installing it might solve the problem. It worked.

I first removed both of my Hosts from virtual center, then logged into the console of the hosts to find the agent version:
rpm -qa | grep -i vmware-vpxa

Then, to remove the agent (replacing the x's with version from above):
rpm -e VMware-vpxa-2.0.x.xxxxx

I repeated this for my second host and then rebooted them both. I had the luxuray of being able to shut off my virtual machines for this process. Once both ESX Hosts were back up I simply went through the process of adding them to Virtual Center, Creating a Cluster and adding them to the cluster.

Thursday, February 12, 2009

NetApp 3040a Clustered Link Aggregation - vif

I've got (2) NetApp 3040a clustered systems both running LACP Aggregated vifs (nics) for my NFS VMWare Connections. One cluster is running on Cisco Catlyist 3750's and the other is running on a Cisco Catlyist 4507. Both switches are setup redundantly. The fail over / load balance is excellent. Here's how I set it up:

My switches are set to IP Load Balance (global switch setting)

Commands I used to setup the nics on the NetApp. This puts onboard nic c and d and add on card port c and d in an aggregated LACP vif called SANAprivate. I use this for private NFS traffic for my VMWare ESX Hosts. The next command sets the IP Address info and adds the partner vif for cluster failovers / non-disruptive SAN upgrades.
> vif create lacp SANAprivate -b ip e0c e0d e4c e4d

> ifconfig SANAprivate 192.168.217.11 up netmask 255.255.255.0 broadcast 192.168.217.255 -wins mediatype auto trusted partner SANBprivate


> vif status SANAprivate
default: transmit 'IP Load balancing', VIF Type 'multi_mode', fail 'log'
private: 4 links, transmit 'IP Load balancing', VIF Type 'lacp' fail 'default'
VIF Status Up Addr_set
up:
e4d: state up, since 30Jan2009 07:47:56 (7+08:17:02)
mediatype: auto-1000t-fd-up
flags: enabled
active aggr, aggr port: e0d
input packets 8106183, input bytes 9157734620
input lacp packets 22869, output lacp packets 21163
output packets 502026, output bytes 229370476
up indications 2, broken indications 0
drops (if) 0, drops (link) 0
indication: up at 30Jan2009 07:47:56
consecutive 0, transitions 2
e4c: state up, since 30Jan2009 07:47:54 (7+08:17:04)
mediatype: auto-1000t-fd-up
flags: enabled
active aggr, aggr port: e0d
input packets 912352, input bytes 82064164
input lacp packets 22874, output lacp packets 21162
output packets 4173173, output bytes 1334844804
up indications 2, broken indications 0
drops (if) 0, drops (link) 0
indication: up at 30Jan2009 07:47:54
consecutive 0, transitions 2
e0c: state up, since 30Jan2009 07:47:53 (7+08:17:05)
mediatype: auto-1000t-fd-up
flags: enabled
active aggr, aggr port: e0d
input packets 2356250, input bytes 569112124
input lacp packets 22857, output lacp packets 21160
output packets 873913, output bytes 121767134
up indications 2, broken indications 0
drops (if) 0, drops (link) 0
indication: up at 30Jan2009 07:47:53
consecutive 0, transitions 2
e0d: state up, since 30Jan2009 07:47:53 (7+08:17:05)
mediatype: auto-1000t-fd-up
flags: enabled
active aggr, aggr port: e0d
input packets 3886952, input bytes 2231755682
input lacp packets 22877, output lacp packets 21160
output packets 1772975, output bytes 1653703494
up indications 2, broken indications 0
drops (if) 0, drops (link) 0
indication: up at 30Jan2009 07:47:53
consecutive 0, transitions 2

Cisco Switch Config
We tested this by pulling Cables from each of the 4 nics up to 3 at a time, so each nic would be by itself and with other nics while pulling data from the link aggregation. We setup multiple connections so we were pulling more than 1 nics worth of bandwidth. I have had very good results with this configuration and have not seen any issues with teaming the onboard nics and the addon nics.

interface Port-channel10
description NetApp Filer Public Links
switchport
switchport access vlan 463
switchport mode access
!
interface GigabitEthernet1/1
description stfSan-e0a
switchport access vlan 463
switchport mode access
channel-group 10 mode active
!
interface GigabitEthernet1/2
description stfSan-e4a
switchport access vlan 463
switchport mode access
channel-group 10 mode active
!
interface GigabitEthernet2/1
description stfSan-e0b
switchport access vlan 463
switchport mode access
channel-group 10 mode active
!
interface GigabitEthernet2/2
description stfSan-e4b
switchport access vlan 463
switchport mode access
channel-group 10 mode active
!

Monday, January 19, 2009

Exchange 2007 - Blackberry Enterprise Server (BES) Setup

Here are a couple things I had to do to get the Blackberry Enterprise Server (BES) running with Exchange 2007. This stuff wasn't clear in the install guide. Especially number 1 below.

1. Give the BESAdmin account permission on my exchange databases. I had to do it on all of our databases. Here's the command for Database07

add-adpermission -user BESAdmin –identity “Database07” -accessrights GenericRead, GenericWrite -extendedrights Send-As, Receive-As, ms-Exch-Store-Admin

2. Give the BESAdmin account extended rights

Add-ADPermission -Identity "BESAdmin" -User "BESAdmin" -AccessRights GenericRead,GenericWrite,ExtendedRight -extendedrights Send-As,Receive-As,Receive-As,ms-Exch-Store-Admin

3. Add the BESAdmin to the Exchange View Only Administrators Group in Active Directory.

Sunday, January 18, 2009

Powershell: Exchange 2007 - BES - Blackberry Enterprise Server

Here a quick little snippet from a script I run when setting up users for our BES (Blackberry Enterprise Server) environment with Exchange 2007. Essentially, the script is just giving the BESAdmin account Send-As permission on the AD Account. You could do this on your entire User OU in the domain, but for security purposes we've decided to only set the permission for the Blackberry users.

# Open the File of User Names and Put it in the Pipeline
$import = Import-Csv "NewBlackBerryAccounts.txt"
$domain = "mydomain.com"

# Loop Through the CSV File, creating accounts
$import | Foreach {
# Set Vars
$StrUserName = $_.Username

$user = get-qaduser $StrUserName@$domain
if($user) {
$dn = $user.DN
Add-ADPermission -Identity $dn -User 'mydomain\BESAdmin' -ExtendedRights 'Send-as'
} else {
write-host Username $_.Username not found
}
}