Showing posts with label CDO. Show all posts
Showing posts with label CDO. Show all posts

Wednesday, June 4, 2008

MSUagageReport.vbs: User report of network storage

Author: Robert Lawson
Environment: Windows Server, Microsoft SQL Server
Description: This script report is run weekly and gives each network user a recap and detail of their personal network share usage. This report is run after the process 'x' has gotten the network detail into an MS SQL database, which simplifies access and reporting. Any errors are written to the application event log to help trouble shooting.
Sample Report:






Code:
'=========================================================================

' FILE: MSUagageReport.vbs

' AUTHOR: Robert Lawson

' COMPANY: Soka University of America

' DATE: 6/04/2008 Robert Lawson, Creation Date



' COMMENT:

' - Reports on information summared in SQL database by OneCard: MSrefresh

' - Server run on has to be allow SMTP relay on Exchange



'=========================================================================

option explicit

On Error Resume Next

const conScriptName = "MSUagageReport.vbs"

const conSendMail = FALSE ' TRUE = will send email, FALSE=will not

strCSSfile = "C:\data\vbscript\MSUagageReportCSS.html" ' Figure out to get from same dir as this script

' strCSSfile = "D:\Tech\MSUagageReportCSS.html" ' Figure out to get from same dir as this script

const conDEBUG = TRUE ' TRUE = SQL and displays, FALSE= full SQL and no displays

const conUDriveKey = 0 ' Key value for UDrive



Dim objShell, strMsg, intLoc

Dim strCSSfile, strHTML, strHTMLCSS, strTempFile

Dim objFile, fso, objFileTemp

Dim objConn, objRS, objRS2, objRS3, strSQL, strConn



' Data

Dim strSource, strType, strAsOf, strName, strEmail

Dim strID, strNETUser, strNameFirst, strNameLast, strNETEmail

Dim strDtlFile, strDtlFolder, strDtlDateCreate, strDtlLastAccess

Dim strTypelist, strTotCount, strTotSize

Dim numTotCount, numTotSize, numCutOffSize

Dim numPctUsed, numSize, numCount, numDtlSize, numQuota

Dim strPctUsed, strSize, strCount, strDtlSize, strQuota, strCutOffSize

Dim numSourceK, numUserK

Dim datAsOf, datDtlDateCreate, datDtlLastAccess

Dim datStartDate



' SMTP email

Dim strTo, strBCC, strCC, strFrom, strSubject, strTextBody

Const conMaxDetailLines = " Top 30 "

Const conDtlFolderMax = 34

Const conDtlFileMax = 23

Const conUdriveSource = 0 ' This is agreed upon (with myself) #



Const conFromUser = "MSNotification@campus.edu" ' valid email if you want user to reply

Const conEmailAdminUser = "robert.lawson@campus.edu" ' comma seperated

Const ForReading = 1 ' FSO



' ============================================================

' Setup

' ============================================================

Set objShell = CreateObject( "WScript.Shell" )



' Write event log that you started

strMsg = "BEGIN: " & conScriptName

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg



' DB stuff

Set objConn = CreateObject("ADODB.Connection")

Set objRS = CreateObject("ADODB.Recordset")

Set objRS2 = CreateObject("ADODB.Recordset")

Set objRS3 = CreateObject("ADODB.Recordset")

strConn = "Provider=SQLOLEDB; SERVER=ServerName; DATABASE=DBname;Integrated Security = SSPI"

objConn.Open strConn



' ============================================================

' Load initial XHTML: CSS

' ============================================================

Set fso = CreateObject("Scripting.FileSystemObject")

Set objFile = fso.OpenTextFile(strCSSfile, ForReading)

if objFile > 0 then

strHTMLCSS = objFile.ReadAll

'if conDEBUG then Wscript.Echo "+objFile = " & strHTML

else

Wscript.Echo conScriptName & ". ERROR: Unable to open CSS file: " & strCSSfile

wscript.quit

end if



strTempFile = "C:\temp\MSUagageReport.html"

Set objFileTemp = fso.CreateTextFile(strTempFile, 2,TRUE)



' ============================================================

' Find out about the source

' ============================================================

strSQL = "SELECT * FROM MSsource WHERE SourceK = " & conUDriveSource

if conDEBUG then Wscript.Echo "strSQL = " & strSQL



objRS.Open strSQL, objConn, 2

if (objRS.BOF or objRS.EOF) then

strMsg = conScriptName & ": Unable to get source info: " & conUDriveSource

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg

WScript.Quit

end if



numCutOffSize = objRS("CutOffSize")

objRS.Close



Select Case numCutOffSize

Case 1024 : strCutOffSize = "1KB"

Case 1048576 : strCutOffSize = "1MB"

Case 1073741824 : strCutOffSize = "1GB"

Case Else strCutOffSize = "?"

End Select



' ============================================================

' Get all users for a source, then detail and email'em

' ============================================================

strSQL = "SELECT * FROM MSuser WHERE SourceK = " & conUDriveSource

'strSQL = strSQL & " AND NETUser IN ('sleepy','dopey','sneezy')" '******** DEBUG ************

if conDEBUG then strSQL = strSQL & " AND NETUser IN ('sleepingb')"

if conDEBUG then strSQL = "SELECT * FROM MSuser WHERE SourceK = 3"

if conDEBUG then Wscript.Echo "strSQL = " & strSQL



objRS.Open strSQL, objConn, 2

if (objRS.BOF or objRS.EOF) then

strMsg = conScriptName & ": No MS users to process for source " & conUDriveSource

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg

WScript.Quit

end if



strDateTime = Date & " " & Time

numUsers = 0



do while not objRS.EOF

strNETUser = objRS("NETUser")

strID = objRS("ID")

strSource = objRS("Source")

datStartDate = objRS("StartDate")

numSourceK = objRS("SourceK")

numUserK = objRS("UserK")

if conDEBUG then Wscript.Echo "--Working on NETUser = " & strNETUser

numUsers = numUsers + 1



strSQL = "SELECT * FROM OneCardMaster WHERE ID = '" & strID & "'"

if conDEBUG then Wscript.Echo strSQL

objRS2.Open strSQL, objConn, 2

if (objRS2.BOF or objRS2.EOF) then

strMsg = conScriptName & ": Unable to open OneCardMaster for ID " & strID

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg

WScript.Quit

end if

strNameFirst = TRIM(objRS2("NameFirst"))

strNameLast = TRIM(objRS2("NameLast"))

strNETEmail = objRS2("NETEmail")

strNETUser = objRS2("NETuser")

objRS2.Close

' ============================================================

' Build header

' ============================================================

numSize = objRS("FileSpace")

numCount = objRS("FileCount")

numQuota = objRS("FileQuota")



' Quota and Pct Used

if numQuota = -1 then

strQuota = "Unlimited"

strPctUsed = "_"

elseif numQuota = -2 then

strQuota = "Not Set"

strPctUsed = "_"

Else

strQuota = pad(FormatNumber(numQuota,0,false,false,true),"r",10)

if numSize <> -1 then

numPctUsed = (numSize/numQuota)

strPctUsed = FormatPercent(numPctUsed,0,false,false,true)

end if

end if



if numSize <> -1 then

strSize = pad(FormatNumber(numSize,0,true,false,true),"r",10)

else

strSize = "???/Error"

end if



' Create header

strName = strNameFirst & " " & strNameLast

strEmail = strNETEmail

'strEmail = "robert.lawson@uni.edu" ' ***** DEBUG



strCount = pad(FormatNumber(numCount,0,true,false,true),"r",10)

strAsOf = FormatDateTime(datStartDate, vbShortDate)



strHTML = strHTMLCSS ' Initialize

strHTML = strHTML & "

strHTML = strHTML & "

strHTML = strHTML & "

"

strHTML = strHTML & "strHTML = strHTML & ""

strHTML = strHTML & "strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & "
strHTML = strHTML & "strHTML = strHTML & "strHTML = strHTML & "strHTML = strHTML & "strHTML = strHTML & "strHTML = strHTML & "
" & strPctUsed & "" & strSize & "" & strQuota & "" & strCount & "" & strSource & "" & strAsOf & "
"



' ============================================================

' Build detail lines

' ============================================================

strSQL = "SELECT " & conMaxDetailLines & _

" * FROM MSUserFile WHERE SourceK = " & numSourceK & " AND UserK = " & numUserK & _

" ORDER BY Size DESC"



if conDEBUG then Wscript.Echo "strSQL = " & strSQL

objRS3.Open strSQL, objConn, 2



strHTML = strHTML & "

strHTML = strHTML & "

"

strHTML = strHTML & "strHTML = strHTML & ""

numCount = 0
do while not objRS3.EOF
numCount = numCount + 1

numDtlSize = objRS3("Size")
if numDtlSize > 0 then numDtlSize = (numDtlSize / 1024) ' KB to MB
strDtlFile = objRS3("FileName") ' conDtlFileMax
if LEN(strDtlFile) > conDtlFileMax THEN
' strDtlFile = LEFT(strDtlFile,10) & "..." & RIGHT(strDtlFile,(conDtlFileMax - 13)) ***************
End if
strDtlFolder = objRS3("Folder") ' conDtlFolderMax
strDtlFolder = REPLACE(strDtlFolder, strSource,"")
if LEN(strDtlFolder) > conDtlFolderMax THEN
' strDtlFolder = "..." & RIGHT(strDtlFolder,(conDtlFolderMax - 3)) *****************
End if
datDtlDateCreate = objRS3("CreateDate")
datDtlLastAccess = objRS3("LastAccess")
strDtlSize = pad(FormatNumber(numDtlSize,0,false,false,true),"r",7)

strDtlLastAccess = FormatDateTime(datDtlLastAccess, vbShortDate)
strDtlDateCreate = FormatDateTime(datDtlDateCreate, vbShortDate)
'strDtlFolder = pad(strDtlFolder, "l", conDtlFolderMax) **********************
'strDtlFile = pad(strDtlFile, "l", conDtlFileMax) ********************

strHTML = strHTML & "strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""



objRS3.movenext

Loop ' Detail lines

strHTML = strHTML & "
strHTML = strHTML & "strHTML = strHTML & "strHTML = strHTML & "strHTML = strHTML & "strHTML = strHTML & "
" & strDtlSize & "" & strDtlFile & "" & strDtlFolder & "" & strDtlDateCreate & "" & strDtlLastAccess & "
"

objRS3.Close



' ============================================================

' File Extension Recep

' ============================================================

strSQL = "SELECT * FROM MSUserFileExtSum " & _

" WHERE SourceK = " & numSourceK & " AND UserK = " & numUserK & _

" ORDER BY TotSize DESC"



if conDEBUG then Wscript.Echo "strSQL = " & strSQL

objRS3.Open strSQL, objConn, 2



strHTML = strHTML & "

strHTML = strHTML & "

"

strHTML = strHTML & "strHTML = strHTML & ""

numCount = 0
' Type,Typelist,TotCount,TotSize
do while not objRS3.EOF
numCount = numCount + 1

strType = objRS3("Type")
strTypelist = objRS3("Typelist")
numTotCount = objRS3("TotCount")
numTotSize = objRS3("TotSize")

strTotCount = pad(FormatNumber(numTotCount,0,false,false,true),"r",7)
strTotSize = pad(FormatNumber(numTotSize,0,false,false,true),"r",7)

strHTML = strHTML & "strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""

strHTML = strHTML & ""



objRS3.movenext

Loop ' File type

strHTML = strHTML & "
strHTML = strHTML & "strHTML = strHTML & "strHTML = strHTML & "strHTML = strHTML & "
" & strType & "" & strTotSize & "" & numTotCount & "" & strTypelist & "
"

objRS3.Close



' Disclaimer stuff

strHTML = strHTML & "

strHTML = strHTML & "This report is a recap of your Soka Udrive account, intended for your personal use and review. The detail of your largest files, sorted by size, is to help you keep tabs on 'the big ones'. Note that only files larger than " & strCutOffSize & " are considered in count and detail report. Files and folders too large to display will be abbreviated with a set of periods. If you have any questions or concerens, please call the IT Help Desk at 949.480.6666 or send an email to helpdesk@uni.edu."

strHTML = strHTML & "



" & strDateTime & "; " & conScriptName & "

"



strHTML = strHTML & "" ' *** END



' ============================================================

' Create email

' ============================================================

if numCount > 0 then

strTo = strEmail

if conDEBUG then strBCC = conEmailAdminUser

strCC = ""

strFrom = conFromUser

strSubject = "U Drive Summary" & conMaxDetailLines & "" & strNETUser

else ' You had summary record with no supporting detail

strTo = conEmailAdminUser

strBCC = ""

strCC = ""

strFrom = conFromUser

strSubject = "Failure to Email User:" & strNETUser & ", No supporting detal"

end if

if conDEBUG then Wscript.Echo strHTML



' Set the message properties.

if conSendMail then

Call SendMail(strFrom,strTo,strCC,strBCC,strSubject,strHTML,TRUE)

strMsg = conScriptName & ": Mailed: " & strName & " @ " & strSubject & _

"; Size: " & strSize & "; Limit: " & strLimit & "; Count: " & strCount

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg

end if



objRS.movenext

Loop ' All users



strMsg = conScriptName & ": end execution. Total emails sent = " & numUsers

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg



' ============================================================

' The End

' ============================================================

strMsg = "END: " & conScriptName

if conDEBUG then

Wscript.Echo strMsg

objFileTemp.Write(strHTML)

End if

objShell.LogEvent 0,strMsg



objRS.Close

objConn.Close

Set objFile = nothing

Set objFile = nothing



' ======================================================

Function DoError(strErrMsg)

On Error Resume Next

Dim objShell



if conDEBUG then wscript.Echo strErrMsg



Set objShell=CreateObject("wscript.shell")

objShell.LogEvent 1,strErrMsg

End Function



' ======================================================

Function pad(strString, strWay, numLen)

' Padd out a passed string

' strWay "r" right, "l" left pad

' numLen overall size you want

Dim numLenVar, numDelta



numLenVar = LEN(strString)

if numLenVar > numLen then

pad = LEFT(strString,numLen)

Exit Function

elseif numLenVar = numLen then

pad = strString

Exit Function

end if



numDelta = numLen - numLenVar

if strWay = "l" then

pad = strString & String(numDelta, " ")

else ' "r"

pad = string(numDelta," ") & strString

end if



End Function



' ==================================================

' SUB: SendMail

' ===================================================

Sub SendMail(sFromAddress, sToAddress, sCcAddress, sBccAddress, sSubject, sBody, bolHTML)

' FILE: SampleEmail.vbs

' PURPOSE: Send SMTP email, html or text, supporting Asian Languages (UTF-8)

' AUTHOR: Robert Lawson

' COMPANY: Soka University of America

' DATE: 08-May-2008 Robert Lawson, Creation Date

' From http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=45670'

on error resume next



Const cdoDispositionNotificationTo = "urn:schemas:mailheader:disposition-notification-to"

Const cdoReturnReceiptTo = "urn:schemas:mailheader:return-receipt-to"

dim cdoMessage, cdoConfiguration



Set cdoConfiguration = CreateObject ("CDO.Configuration")

With cdoConfiguration

.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.uni.edu"

.Fields("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25

.Fields("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2

.Fields("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60

.Fields.Update

End With



Set cdoMessage = CreateObject("CDO.Message")

With cdoMessage

' Update the CDOSYS Configuration (don't make 1 line!!!)

SET .Configuration = cdoConfiguration

.BodyPart.charset = "unicode-1-1-utf-8"

.Fields.Update

.From = sFromAddress

.ReplyTo = sFromAddress

.To = sToAddress

.Cc = sCcAddress

.Bcc = sBccAddress

.Subject = sSubject

if bolHTML then

.HTMLBody = sBody

else

.Textbody = sBody

end if

.Send

End With



Set cdoMessage = Nothing

Set cdoConfiguration = Nothing

End Sub

Friday, May 25, 2007

UpdSeniors2007.vbs: Student exit account shutdown

Author: Robert Lawson
Environment: Windows Server, Active Directory, Exchange, vb-script
Description: This script’s function is to do all Active Directory and Exchange steps for graduating students. The student accounts have been manually moved to a single Active Directory OU, from an approved list published by the Registrar. The Active Directory account and Exchange mailbox are logically removed from the system, eg removed from GAL, all group memberships removed, email address scrambled. This script can take several hours and can be run at off-hours.
Features:
- Results written to disk log file
- Trial no-update option
Code:
'=========================================================================
' FILE: UpdSeniors2007.vbs
' AUTHOR: Robert Lawson
' COMPANY: Soka University
' DATE: 25-May-2007
' COMMENT: Update/shutdown 2007 senior AD users
' Assumpitons
' 1. Run as Domain Admin
' 2. You have setup OU and moved seniors to this OU
' 4. Set to target Exchange mailbox
' 5. Must have installed "Exchange System Management Tools"on computer this script executes on. To
' do this you 1) Use Exchange CD, 2) Do Exchange installation
'=========================================================================
Option Explicit
' Variables
Dim fso, objFile, strRec, answer, logUpdate, objNetwork
Dim strOU, strFilter, strQuery, rs, objCommand, UserADsPath, objUser, objConnection
Dim strTargetHomeMDB_DN, strOriginalHomeMDB, objTargetHomeMDB, logSkipMoveMailBox
Dim proxyAddresses, proxyAddressesCount, i, email, emailOld, emailNew, objGroup, groupADsPath, objUserGroup
Dim dacl, ace, oSecurityDescriptor, sTrustee

' Constants
Const ADS_SCOPE_SUBTREE = 2
Const ADS_PROPERTY_DELETE = 4
Const ADS_PROPERTY_UPDATE = 2
Const ADS_PROPERTY_APPEND = 3
Const ADS_PROPERTY_CLEAR = 1

' Exchange AD Security
CONST ADS_ACETYPE_ACCESS_ALLOWED = 0
CONST ADS_ACEFLAG_INHERIT_ACE = 2

Const ForReading = 1
Const ForWriting = 2
Const consDisableAccount = 66050 ' AD user setting
Const consLogFile = "c:\temp\UpdSeniros2007.txt" ' File name to write data to
Const conScriptName = "UpdSeniors2007.vbs"
Const conADSelf = "NT AUTHORITY\SELF"

' ============================================================
' Log file setup
' ============================================================
Set fso = CreateObject("Scripting.FileSystemObject")
Set objFile = fso.OpenTextFile(consLogFile, ForWriting, True)
Set objNetwork = Wscript.CreateObject("Wscript.Network")
strRec = "Date = " & Date & " " & Time & _
", Script= " & conScriptName & _
", Computer = " & objNetwork.ComputerName & _
", User = " & objNetwork.UserName & "/" & objNetwork.UserDomain
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr

' ============================================================
' Verify target mailbox exists
' ============================================================
strTargetHomeMDB_DN = "CN=ClassOf2007,CN=Students,CN=InformationStore,CN=server,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=uni,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=uni,DC=edu"
Set objTargetHomeMDB = CreateObject("CDOEXM.MailBoxStoreDB")
objTargetHomeMDB.DataSource.Open (strTargetHomeMDB_DN)
If Err.Number Then ErrorHandler (Err)
If objTargetHomeMDB.Status Then
strRec = "***ERROR: Target Store " & objTargetHomeMDB.Name & " is not mounted."
Wscript.Echo strRec
WScript.Quit (1)
else
strRec = "Target store verified: " & objTargetHomeMDB.Name
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr
End If

' ============================================================
' Get users
' ============================================================
set objConnection=Createobject("ADODB.Connection")
set objCommand=CreateObject("ADODB.Command")
objConnection.Provider="ADSDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

strOU = "OU=UG Graduates 2007,OU=Students,OU=Location,DC=uni,DC=edu"
strFilter = "objectcategory='person' AND objectclass='user'"

strQuery = "SELECT ADsPath from 'LDAP://" & strOU & "' WHERE " & strFilter
Wscript.Echo strQuery
objFile.WriteLine strQuery & vbCr

objCommand.CommandText= strQuery
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
' ============================================================
' Proceed?
' ============================================================
strRec = "OU = " & strOU & vbCrLF & _
"FILTER = " & strFilter & vbCrLF & _
"TARGETMB = " & strTargetHomeMDB_DN
answer=MsgBox(strRec,vbYesNoCancel + vbInformation + vbDefaultButton2,"Update?")
if answer = vbOK or answer = vbYes then
logUpdate = TRUE
else
logUpdate = FALSE
end if
strRec = "UPDATE = " & logUpdate
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr

' ============================================================
' Do Updates
' ============================================================
Set rs = objCommand.Execute
do while not rs.EOF
UserADsPath = rs.fields("ADsPath").value
Wscript.Echo UserADsPath
Set objUser = GetObject(UserADsPath)

strRec = "--Working on: " & objUser.sAMAccountname
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr

' ------------------------------------------------------------
' Move Exchange mailbox
strOriginalHomeMDB = objUser.homeMDB
logSkipMoveMailBox = ((LCase(strOriginalHomeMDB) = LCase(strTargetHomeMDB_DN)) or _
Isnull(strOriginalHomeMDB))
Wscript.Echo "logSkipMoveMailBox = " & logSkipMoveMailBox
if logUpdate and NOT logSkipMoveMailBox then
On Error Resume Next
objUser.MoveMailbox "LDAP://" & strTargetHomeMDB_DN
If err.Number Then
strRec = "***ERROR: Unable to move from homeMDB " & strOriginalHomeMDB
Wscript.Echo "strOriginalHomeMDB = " & strOriginalHomeMDB
Wscript.Echo "strTargetHomeMDB_DN = " & strTargetHomeMDB_DN
strRec = "err = " & err.number & " " & err.Description
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr
WScript.Quit (1)
else
strRec = "Moved mailbox from " & strOriginalHomeMDB & " to " & objUser.homeMDB
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr
End If
end if

' ------------------------------------------------------------
' Hide from Exchange GAL
if logUpdate and not objUser.msExchHideFromAddressLists then
strRec = "Setting msExchHideFromAddressLists = TRUE"
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr
objUser.Put "msExchHideFromAddressLists",TRUE
objUser.SetInfo
end if

' ------------------------------------------------------------
' Disable receiving email from outside
proxyAddresses = objUser.proxyAddresses
emailNew = ""
If Not IsNull(proxyAddresses) Then
proxyAddressesCount = UBound(proxyAddresses)
For i = 0 To proxyAddressesCount
email = proxyAddresses(i)
If Left(email,5) = "SMTP:" and instr(email,"XXX@") = 0 then
emailNew = email
emailOld = email
emailNew = replace(emailNew,"@","XXX@")
Wscript.Echo "Delete : " & email
Wscript.Echo "Adding: " & emailNew
proxyAddresses(i) = emailNew
end if
Next
if logUpdate and len(emailNew) > 0 then
strRec = "Changing " & emailOld & " to " & emailNew
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr
objUser.putex ADS_PROPERTY_UPDATE, "proxyAddresses",array(emailNew)
objUser.SetInfo
end if
End if

' ------------------------------------------------------------
' Remove group memberships
For Each objGroup In objUser.Groups
groupADsPath = objGroup.ADsPath
Wscript.Echo groupADsPath

if logUpdate then
Set objUserGroup = GetObject(groupADsPath)
strRec = "Removing membership to : " & objUserGroup.sAMAccountname
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr

objUserGroup.Remove(UserADsPath)
objUserGroup.Setinfo
end if
Next

' ------------------------------------------------------------
' Set MB rights (fixes problem in KB 555410)
Set oSecurityDescriptor = objUser.MailboxRights ' Get the Mailbox security descriptor (SD).
Set dacl = oSecurityDescriptor.DiscretionaryAcl 'Discretionary Access Control List (DACL)
Set Ace = CreateObject("AccessControlEntry")

if logUpdate then
strRec = "Fixing MB rights : " & objUser.sAMAccountname
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr

Ace.AccessMask = 131079 ' SELF
Ace.AceType = ADS_ACETYPE_ACCESS_ALLOWED
Ace.AceFlags = ADS_ACEFLAG_INHERIT_ACE
Ace.Flags = 0 '
Ace.Trustee = conADSelf
dacl.AddAce Ace

oSecurityDescriptor.DiscretionaryAcl = dacl
objUser.MailboxRights = oSecurityDescriptor
objUser.SetInfo
end if

' ------------------------------------------------------------
' Set account to inactive
if logUpdate and objUser.userAccountControl <> consDisableAccount then
strRec = "Setting userAccountControl = " & consDisableAccount & "(disabled)"
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr
objUser.Put "userAccountControl", consDisableAccount
objUser.SetInfo
end if

rs.movenext
Loop ' All users
' ============================================================
' The End
' ============================================================
strRec = "Date = " & Date & " " & Time & _
", Script= " & conScriptName & _
", Computer = " & objNetwork.ComputerName & _
", User = " & objNetwork.UserName & "/" & objNetwork.UserDomain
Wscript.Echo strRec
objFile.WriteLine strRec & vbCr

rs.Close
objFile.Close
objConnection.Close

Monday, August 7, 2006

EASUsageAudit.vbs: User weekly mailbox recap

Author: Robert Lawson
Environment: Windows Server, Exchange, EAS, vb-script
Description: This script runs weekly and recaps a users email EAS detail. It is meant to give them a quick snap-shot of their account and show them their largest email attachments. This report is meant to help make mailbox's self-managed, and works in conjunction with nightly quota notification: EASnearquotaemail.vbs.
Features:

- Cascading Style Sheet
- HTML constructed
- DEBUG feature
- Errors write to application event log
- Database driven using ADO

Sample Report:





Code Listing

'=========================================================================
' FILE: EASUsageAudit.vbs
' AUTHOR: Robert Lawson
' COMPANY: Soka University of America
' DATE: 6/01/2006 Robert Lawson, Creation Date
' 11/29/2006 Robert Lawson General update ready for production
' 12/13/2006 Robert Lawson Added email send/receive size
' 12/21/2006 Robert Lawson Converted to XHTML
' 11/12/2007 Robert Lawson Added VIEW_STORAGE_BY_USER_REF2 for # and usage,
' this is what is used to enforce quota.
' 04/09/2008 Robert Lawson Skip if error 438 for send mail
' COMMENT: Audit EAS Usage and notification
' - Relies heavily t-sql views: VWEASUserQuotaUsage and VWEASUserTopMsgs
' - Server run on has to be allow SMTP relay on Exchange

'=========================================================================
option explicit
On Error Resume Next
const conScriptName = "EASUsageAudit.vbs"
const conSendMail = FALSE ' TRUE = will send email, FALSE=will not
strCSSfile = "C:\data\vbscript\EASUsageAuditCSS.html"
const conDEBUG = TRUE ' TRUE = SQL and displays, FALSE= full SQL and no displays

Dim objShell, strMsg, intLoc
Dim strCSSfile, strHTML, strHTMLCSS
Dim objFile, fso
Dim objConn, objRS, objRS2, objRS3, strSQL, strConn
Dim numQuota, numMsgSize, numCount, numUsers, numPctUsed, numSendSize, numReceiveSize
Dim numREF_COUNT, numUNCOMPRESSEDSIZESUM, numCOMPRESSEDSIZESUM
Dim strName, strEmail, strSize, strLimit, strCount
Dim strDateTime, strMailDate, strMailSize, strMailFrom, strMailSubject, strMailFolder
Dim strMailBody, strUSERID, strDetail, strQuotaDesc, strPctUsed, strSendSize, strReceiveSize
Dim iMsg, iConf, Flds
Dim strTo, strBCC, strCC, strFrom, strSubject, strTextBody

Const conEASQuotaUnlimited = -1
Const conMaxExchangeAttachment = 10 ' MB
Const conMaxEmailDetail = " Top 20 "
' Do not set your smtp server information here.
Const cdoSendUsingMethod = "http://schemas.microsoft.com/cdo/configuration/sendusing", _
cdoSendUsingPort = 2, _
cdoSMTPServer = "http://schemas.microsoft.com/cdo/configuration/smtpserver"
Const conSMTPserver = "smtp.campus.edu"
Const conFromUser = "EmailNotification@campus.edu" ' valid email if you want user to reply
Const conEmailAdminUser = "robert.lawson@campus.edu" ' comma seperated
Const ForReading = 1 ' FSO

numSendSize = 20 ' MB, ****** get from Exchange, when time
numReceiveSize = 20 ' MB, ****** get from Exchange, when time
' ============================================================
' Setup
' ============================================================
Set objShell = CreateObject( "WScript.Shell" )

' Write event log that you started
strMsg = "BEGIN: " & conScriptName
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

' DB stuff
Set objConn = CreateObject("ADODB.Connection")
Set objRS = CreateObject("ADODB.Recordset")
Set objRS2 = CreateObject("ADODB.Recordset")
Set objRS3 = CreateObject("ADODB.Recordset")
strConn = "Provider=SQLOLEDB; SERVER=ServerName; DATABASE=dbName;Integrated Security = SSPI"
objConn.Open strConn

' Email stuff (SMTP)
Set iMsg = CreateObject("CDO.Message")
Set iConf = CreateObject("CDO.Configuration")
iConf.Fields.Item(cdoSendUsingMethod) = cdoSendUsingPort
iConf.Fields.Item(cdoSMTPServer) = conSMTPserver
iConf.Fields.Update

' ============================================================
' Load initial XHTML: CSS
' ============================================================
Set fso = CreateObject("Scripting.FileSystemObject")
Set objFile = fso.OpenTextFile(strCSSfile, ForReading)
if objFile > 0 then
strHTMLCSS = objFile.ReadAll
'if conDEBUG then Wscript.Echo "+objFile = " & strHTML
else
Wscript.Echo conScriptName & ". ERROR: Unable to open CSS file: " & strCSSfile
wscript.quit
end if

' ============================================================
' Get user's, then detail and email'em
' ============================================================
strSQL = "SELECT USERID, UserName, QuotaSize, QuotaType, Email, MsgCount, MsgSize " & _
"FROM VWEASUserQuotaUsage"
if conDEBUG then strSQL = strSQL & " WHERE USERID = 7" ' ******** DEBUG ************
if conDEBUG then Wscript.Echo "strSQL = " & strSQL

objRS.Open strSQL, objConn, 2
if (objRS.BOF or objRS.EOF) then
strMsg = conScriptName & ": No EAS records to process"
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
WScript.Quit
end if

strDateTime = Date & " " & Time
numUsers = 0
do while not objRS.EOF
strUSERID = objRS("USERID")
if conDEBUG then Wscript.Echo "--Working on USERID = " & strUSERID
numUsers = numUsers + 1
' Get EAS standard information
strSQL = "SELECT USERID, REF_COUNT, UNCOMPRESSEDSIZESUM, COMPRESSEDSIZESUM " & _
"FROM VIEW_STORAGE_BY_USER_REF2 WHERE USERID = '" & strUSERID & "'"
if conDEBUG then Wscript.Echo "strSQL = " & strSQL
objRS2.Open strSQL, objConn, 2
if (objRS2.BOF or objRS2.EOF) then
strMsg = conScriptName & ": Unable to open VIEW_STORAGE_BY_USER_REF2 for user " & strUSERID
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
WScript.Quit '******????
end if
numREF_COUNT = cDbl(objRS2("REF_COUNT")) ' EAS Total email count
numUNCOMPRESSEDSIZESUM = cDbl(objRS2("UNCOMPRESSEDSIZESUM")) ' EAS MB size un-compressed
numCOMPRESSEDSIZESUM = cDbl(objRS2("COMPRESSEDSIZESUM")) ' EAS MB size compressed
objRS2.Close

' ============================================================
' Build header
' ============================================================
numQuota = clng(objRS("QuotaSize"))
'numMsgSize = clng(objRS("MsgSize")) Use numUNCOMPRESSEDSIZESUM
if numQuota = -1 then
strQuotaDesc = " (Unlimited)"
strPctUsed = " "
else
strQuotaDesc = " "
numPctUsed = (numUNCOMPRESSEDSIZESUM/numQuota)
strPctUsed = FormatPercent(numPctUsed,0,false,false,true)
end if

' Create header
strName = objRS("UserName")
strEmail = objRS("Email")
strSize = pad(FormatNumber(numUNCOMPRESSEDSIZESUM,0,false,false,true),"r",10)
strLimit = pad(FormatNumber(numQuota,0,false,false,true),"r",10)
strCount = pad(FormatNumber(numREF_COUNT,0,false,false,true),"r",10)
strSendSize = pad(FormatNumber(numSendSize,0,false,false,true),"r",4)
strReceiveSize = pad(FormatNumber(numReceiveSize,0,false,false,true),"r",4)

strHTML = strHTMLCSS ' Initialize
strHTML = strHTML ... author note: code with html construction available on request.
' ============================================================
' Build detail lines
' ============================================================
strSQL = "SELECT " & conMaxEmailDetail & _
"SUBJECT, FROMFLD, MSGDATE, MsgSize, FOLDERNAME FROM VWEASUserTopMsgs WHERE USERID = " & strUSERID & _
" ORDER BY MsgSize DESC"
if conDEBUG then Wscript.Echo "strSQL = " & strSQL
objRS3.Open strSQL, objConn, 2

strHTML = strHTML & ... author note: code with html construction available on request.

numCount = 0
do while not objRS3.EOF
numCount = numCount + 1
strMailDate = pad(datevalue(objRS3("MSGDATE")), "r", 10)
strMailSize = pad(CStr(objRS3("MsgSize")),"r", 5) & " MB"
strMailFrom = pad(objRS3("FROMFLD"), "l", 26)
strMailSubject = pad(objRS3("SUBJECT"), "l",31)
strMailFolder = pad(objRS3("FOLDERNAME"), "l",70)

strHTML = strHTML ... author note: code with html construction available on request.
objRS3.movenext
Loop ' All users
strHTML = strHTML & ... author note: code with html construction available on request.

objRS3.Close

' Disclaimer stuff
strHTML = strHTML & ... author note: code with html construction available on request.
' *** END

' ============================================================
' Create email
' ============================================================
if numCount > 0 then
strTo = strEmail
if conDEBUG then strBCC = conEmailAdminUser
strCC = ""
strFrom = conFromUser
strSubject = "Email Account Summary" & conMaxEmailDetail & "" & RTRIM(objRS("UserName"))
else ' You had summary record with no supporting detail
strTo = conEmailAdminUser
strBCC = ""
strCC = ""
strFrom = conFromUser
strSubject = "Failure to Email User:" & RTRIM(objRS("UserName")) & ", No supporting detal"
end if
if conDEBUG then Wscript.Echo strHTML

' Set the message properties.
if conSendMail then
With iMsg
Set .Configuration = iConf
.To = strTo
if len(strBCC) > 0 then .BCC = strBCC
if len(strCC) then .CC = strCC
.From = strFrom
.Subject = strSubject
.HTMLBody = strHTML
End With
iMsg.Send ' send the message.
if err.number = 438 then
if conDEBUG then Wscript.Echo "Skipping error 438 " & err.Description
elseif err.number <> 0 then
intLoc = 5
strMsg = conScriptName & ": Error @ " & intLoc & ". err = " & err.number & " smtp mail send failed for USERID=" & strUSERID
DoError(strMsg)
else ' at some point write to db log
strMsg = conScriptName & ": Mailed: " & strName & " @ " & strSubject & _
"; Size: " & strSize & "; Limit: " & strLimit & "; Count: " & strCount
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
end if ' ierr
end if ' conSendMail

objRS.movenext
Loop ' All users

strMsg = conScriptName & ": end execution. Total emails sent = " & numUsers
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

' ============================================================
' The End
' ============================================================
strMsg = "END: " & conScriptName
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

objRS.Close
objConn.Close
Set objFile = nothing
Set objFile = nothing


' ======================================================
Function DoError(strErrMsg)
On Error Resume Next
Dim objShell

if conDEBUG then wscript.Echo strErrMsg

Set objShell=CreateObject("wscript.shell")
objShell.LogEvent 1,strErrMsg
End Function

' ======================================================
Function pad(strString, strWay, numLen)
' Padd out a passed string
' strWay "r" right, "l" left pad
' numLen overall size you want
Dim numLenVar, numDelta

numLenVar = LEN(strString)
if numLenVar > numLen then
pad = LEFT(strString,numLen)
Exit Function
elseif numLenVar = numLen then
pad = strString
Exit Function
end if

numDelta = numLen - numLenVar
if strWay = "l" then
pad = strString & String(numDelta, " ")
else ' "r"
pad = string(numDelta," ") & strString
end if

End Function

Thursday, June 1, 2006

EASNearQuotaEmail.vbs: Email over quota notice

Author: Robert Lawson
Environment: SQL Server, Windows Server, vb-script, EAS, Exchange
Description: This script is run as nightly job to notify users if their email EAS mailbox storage is nearing quota. The assumption is that the EAS storage for email attachments will fill up first and that the users have been getting a weekly report of the usage: EASUsageAudit.vbs
Features:
- Configurable quota to begin sending notification
- Custom wording to send in email
- bcc notification to administrator(s) of email sent
- Write to application event log for easy trouble-shooting
Sample:





Code Listing:

'=========================================================================

' FILE: EASNearQuotaEmail.vbs

' AUTHOR: Robert Lawson

' COMPANY: Soka University of America

' DATE: 6/01/2006 Robert Lawson, Creation Date

' 11/12/2006 Added EAS VIEW_STORAGE_BY_USER_REF2, not "as" correct,

' but is used for enforcing quota.

' COMMENT: Audit EAS Usage and notification

' - Set value of "conSendMail" if you send mail or not, also conDEBUG

' - Relies heavily on t-sql view VWEASUserQuotaUsage

' - Server run on has to be allow SMTP relay on Exchange

' - VWEASUserQuotaUsage can not calc percent, must be done in program



'=========================================================================

option explicit

On Error Resume Next

const conScriptName = "EASNearQuotaEmail.vbs"

const conDEBUG = TRUE

const conSendMail = FALSE ' TRUE = will send email, FALSE=will not



Dim objShell, strMsg, intLoc

Dim objConn, objRS, objRS2, strSQL, strConn

Dim numQuotaSize, numMsgSize, numEASPct, numMsgCount

Dim numREF_COUNT, numUNCOMPRESSEDSIZESUM, numCOMPRESSEDSIZESUM

Dim strQuotaSize, strMsgSize, strEASPct, strUserName

Dim strMailBody, numCount, numUsers, strUSERID, strDetail, strQuotaDesc

Dim iMsg, iConf, Flds

Dim strTo, strBCC, strCC, strFrom, strSubject, strTextBody



Const conEASQuotaUnlimited = -1

Const conMaxEASNotificationPct = .95 ' EAS percent to warn at (1=100%)

' Do not set your smtp server information here.

Const cdoSendUsingMethod = "http://schemas.microsoft.com/cdo/configuration/sendusing", _

cdoSendUsingPort = 2, _

cdoSMTPServer = "http://schemas.microsoft.com/cdo/configuration/smtpserver"

Const conSMTPserver = "smtp.campus.edu"

Const conFromUser = "E-Admini@campus.edu"

Const conEmailAdminUser = "robert.lawson@campus.edu" ' comma seperated



' Setup

Set objShell = CreateObject( "WScript.Shell" )



' Write event log that you started

strMsg = conScriptName & ": Begin execution"

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg



' Email stuff (SMTP)

Set iMsg = CreateObject("CDO.Message")

Set iConf = CreateObject("CDO.Configuration")

iConf.Fields.Item(cdoSendUsingMethod) = cdoSendUsingPort

iConf.Fields.Item(cdoSMTPServer) = conSMTPserver

iConf.Fields.Update



' DB stuff

Set objConn = CreateObject("ADODB.Connection")

Set objRS = CreateObject("ADODB.Recordset")

Set objRS2 = CreateObject("ADODB.Recordset")

strConn = "Provider=SQLOLEDB; SERVER=YourServer; DATABASE=DBname;Integrated Security = SSPI"

objConn.Open strConn



' Get summary for active EAS users with space used

strSQL = "SELECT USERID, UserName, QuotaSize, QuotaType, Email, MsgCount, MsgSize " & _

"FROM VWEASUserQuotaUsage"

strSQL = strSQL & " WHERE QuotaSize > 0" ' Not unlimited

' strSQL = strSQL & " AND USERID = 497" ' **** DEBUG ****

if conDEBUG then Wscript.Echo "strSQL = " & strSQL

objRS.Open strSQL, objConn, 2

if (objRS.BOF or objRS.EOF) then

strMsg = conScriptName & ": No EAS records to process"

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg

WScript.Quit

end if



numUsers = 0

do while not objRS.EOF

strUSERID = objRS("USERID")



strSQL = "SELECT USERID, REF_COUNT, UNCOMPRESSEDSIZESUM, COMPRESSEDSIZESUM " & _

"FROM VIEW_STORAGE_BY_USER_REF2 WHERE USERID = '" & strUSERID & "'"

if conDEBUG then Wscript.Echo "strSQL = " & strSQL

objRS2.Open strSQL, objConn, 2

if (objRS2.BOF or objRS2.EOF) then

strMsg = conScriptName & ": Unable to open VIEW_STORAGE_BY_USER_REF2 for user " & strUSERID

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg

WScript.Quit '******????

end if

numREF_COUNT = cDbl(objRS2("REF_COUNT")) ' EAS Total email count

numUNCOMPRESSEDSIZESUM = cDbl(objRS2("UNCOMPRESSEDSIZESUM")) ' EAS MB size un-compressed

numCOMPRESSEDSIZESUM = cDbl(objRS2("COMPRESSEDSIZESUM")) ' EAS MB size compressed



strUserName = RTRIM(objRS("UserName"))

numQuotaSize = cDbl(objRS("QuotaSize"))

' numMsgCount = cDbl(objRS("MsgCount")) Use numREF_COUNT

' numMsgSize = cDbl(objRS("MsgSize")) Use numUNCOMPRESSEDSIZESUM

if numQuotaSize <= 0 then numEASPct = 1.0 else numEASPct = numUNCOMPRESSEDSIZESUM / numQuotaSize end if if numEASPct > conMaxEASNotificationPct then

numUsers = numUsers + 1

if conDEBUG then Wscript.Echo "--USERID/Name = " & strUSERID & "/" & strUserName & " pct: " & numEASPct



if numQuotaSize = conEASQuotaUnlimited then

strQuotaDesc = " (Unlimited)"

strEASPct = " "

else

strQuotaDesc = " "

strEASPct = FormatPercent(numEASPct,0,false,false,true)

end if

strMsgSize = FormatNumber(numUNCOMPRESSEDSIZESUM,0,false,false,true)

strQuotaSize = FormatNumber(numQuotaSize,0,false,false,true)

strMsgCount = FormatNumber(numREF_COUNT,0,false,false,true)



' Create header FormatNumber(objRS("QuotaSize"),0,false,false,true)

strMailBody = ""

strMailBody = _

"You have received this message because your mailbox is approaching its size limit." & vbCrLF & _

"Your mailbox size is currently " & strEASPct & " full (size (MB): " & strMsgSize & "; limit (MB): " & strQuotaSize & "). " & _

"When your mailbox fills up you will not be able to send nor receive any more email. " & _

"Please do the following to reduce mailbox volume:" & vbCrLF & _

"1. Delete items in the Sent-Items folder" & vbCrLF & _

"2. Empty the Deleted-Items folder" & vbCrLF & _

"3. Sort messages by the attachment icon and delete messages with large attachments" & vbCrLF & _

"Mailbox space can be freed up most efficiently by focusing on deleting emails with attachments. In most cases a large portion of a mailbox’s volume is occupied by a collection of emails with attachments like photos, music, videos and scans. This also includes emails you sent to others and remain in your “Sent Items” folder. Note the mailbox size and limits refer to the EAS system." & vbCrLF & _

"Thank you" & vbCrLF & "SUA-Email-Administrators" & vbCrLF & vbCrLF & _

"source: " & conScriptName & vbCrLF



' Prep email

strTo = objRS("Email")

strBCC = conEmailAdminUser

strCC = ""

strFrom = conFromUser

strSubject = "Your Mailbox is Approaching its Size Limit" & strUserName

strTextBody = strMailBody

if conDEBUG then Wscript.Echo strMailBody



' Send thu sucku

if conSendMail then

With iMsg

Set .Configuration = iConf

.To = strTo

if len(strBCC) > 0 then .BCC = strBCC

if len(strCC) then .CC = strCC

.From = strFrom

.Subject = strSubject

.TextBody = strTextBody

End With

iMsg.Send ' send the message.

if err.number <> 0 then

intLoc = 5

strMsg = conScriptName & ": Error @ " & intLoc & ". smtp mail send failed for " & strUSERID

DoError(strMsg)

else ' at some point write to db log

strMsg = conScriptName & ": email sent to " & strTo & ", subject: " & strSubject

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg

end if ' ierr

end if ' conSendMail

end if ' numEASPct

objRS.movenext

objRS2.Close

Loop ' All users



strMsg = conScriptName & ": end execution. Total emails sent = " & numUsers

if conDEBUG then Wscript.Echo strMsg

objShell.LogEvent 0,strMsg



objRS.Close

objConn.Close



' ======================================================

Function DoError(strErrMsg)

On Error Resume Next

Dim objShell



' wscript.Echo strErrMsg



Set objShell=CreateObject("wscript.shell")

objShell.LogEvent 1,strErrMsg

End Function