Showing posts with label Windows Server. Show all posts
Showing posts with label Windows Server. 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, April 11, 2008

Camp9PT849DBrefresh.sql: PS CS database refresh

Author: Robert Lawson
Environment: Windows Server, MS SQL Server, PeopleSoft
Description: This script updates PeopleSoft Campus Solution's v9 database all the steps to make it operational, point to 'test' instances, update security and clean out working tables.

Code:
/*
File: Camp9PT849DBrefresh.sql
Update : 11-Apr-2008/Robert Lawson
Purpose: Post db updates for Campus Solutions 9/PT 8.49

*/
-- Fix database users
exec sp_change_users_login 'update_one','folks','folks'
exec sp_change_users_login 'update_one','Angel_Access','Angel_Access'
exec sp_change_users_login 'update_one','db-user','db-user'

-- \scripts\grant.sql
GRANT SELECT ON PSSTATUS TO folks
GRANT SELECT ON PSACCESSPRFL TO folks
GRANT SELECT ON PSOPRDEFN TO folks


-- Disable student accounts
UPDATE PSOPRDEFN SET ACCTLOCK = 1
WHERE OPRCLASS = 'STUDENT'

-- Clear references to reports
DELETE FROM PS_CDM_LIST WHERE DISTNODENAME <> 'LSTEST'

-- QA: App Messaging
DELETE FROM PSAPMSGDOMSTAT
DELETE FROM PSAPMSGDSPSTAT

-- IB: Local Gateway
UPDATE PSGATEWAY SET
CONNURL = 'http://cc1np.campus.edu:11/PSIGW/PeopleSoftListeningConnector'
WHERE CONNGATEWAYID = 'LOCAL'

-- IB: Nodes
UPDATE PSNODECONPROP SET
PROPVALUE = 'http://ff1np.campus.edu:11/PSIGW/PeopleSoftListeningConnector'
WHERE MSGNODENAME = 'PSFT_EP'

UPDATE PSNODECONPROP SET
PROPVALUE = 'http://cc1np.campus.edu:11/PSIGW/PeopleSoftListeningConnector'
WHERE MSGNODENAME = 'PSFT_LS'

-- IB: Connectors
UPDATE PSCONNPROP SET
PROPVALUE = 'http://ff1np.campus.edu:11/PSIGW/PeopleSoftListeningConnector'
WHERE PROPID = 'FINANCIAL'

UPDATE PSCONNPROP SET
PROPVALUE = 'http://cc1np.campus.edu:11/PSIGW/PeopleSoftListeningConnector'
WHERE PROPID = 'CAMPUS'

-- Report Distribution
UPDATE PS_SERVERDEFN SET DISTNODENAME = 'LSTEST ' WHERE SERVERNAME = 'PSNT '

-- Business Interlink (Credit Card Processing)
UPDATE PSIOSETTINGS SET
IOVALUE = REPLACE(IOVALUE,'LSPROD','LSTEST')
WHERE IONAME = 'CREDITCARD_TRANSACTION' AND
IOSETTINGNAME = 'properties_file'

-- REN server (rebuilt by App Server)
DELETE FROM PSMCFRENURLID
DELETE FROM PSREN

-- Change Assistant
UPDATE PSOPTIONS SET
SHORTNAME = 'LSTEST',
LONGNAME = 'LSTEST',
GUID = '',
SYSTEMTYPE = 'STS'

-- Security
INSERT INTO PSROLEUSER
(ROLEUSER, ROLENAME,DYNAMIC_SW) VALUES
('cgreen', 'UPG_STDN_REC','N')
INSERT INTO PSROLEUSER
(ROLEUSER, ROLENAME,DYNAMIC_SW) VALUES
('cgreen', 'UPG_STDTNFIN','N')

-- appmsgpurgeall.dms (remove log statement; clears app messages)
-- core tables:
DELETE FROM PSAPMSGPUBHDR;
DELETE FROM PSAPMSGPUBDATA;
DELETE FROM PSAPMSGPUBCON;
DELETE FROM PSAPMSGSUBCON;
DELETE FROM PSAPMSGPUBERR;
DELETE FROM PSAPMSGPUBERRP;
DELETE FROM PSAPMSGPUBCERR;
DELETE FROM PSAPMSGPUBCERRP;
DELETE FROM PSAPMSGSUBCERR;
DELETE FROM PSAPMSGSUBCERRP;
DELETE FROM PSAPMSGPCONDATA;
DELETE FROM PSAPMSGSCONDATA;
DELETE FROM PSIBERR;
DELETE FROM PSIBERRP;

-- synchronous core tables:
DELETE FROM PSIBLOGHDR;
DELETE FROM PSIBLOGDATA;
DELETE FROM PSIBLOGERR;
DELETE FROM PSIBLOGERRP;
DELETE FROM PSIBLOGIBINFO;

-- archive tables:
DELETE FROM PSAPMSGARCHPH;
DELETE FROM PSAPMSGARCHPD;
DELETE FROM PSAPMSGARCHPC;
DELETE FROM PSAPMSGARCHSC;
DELETE FROM PSAPMSGARCHPT;
DELETE FROM PSAPMSGARCHST;
DELETE FROM PSIBLOGHDRARCH;
DELETE FROM PSIBLOGDATAARCH;
DELETE FROM PSIBLOGIBINFOAR;

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

Tuesday, February 27, 2007

MailboxCalendarDSTAudit.vbs: Audit Calendar for DST

Author: Robert Lawson
Environment: Windows Server, Exchange, Active Directory, vb-script
Description: This script was used to determine the number of users and extent of Exchange calendar events scheduled during the two 2007 extended Day Light Savings periods. This was handy as we were able to advise only those users with very specific corrective directions.

Code:

'=========================================================================
' FILE : MailboxCalendarDSTAudit.vbs
' AUTHOR : Robert Lawson
' COMPANY: Soka University of America
' DATE : 2/27/2007
' COMMENT: Daylight Savings Time audit of calendar
' KB 930879: Exchange Calendar Update Tool, daylight saving time
'=========================================================================
option explicit
On Error Resume Next
const conScriptName = "MailboxCalendarDSTAudit.vbs"
const conDEBUG = FALSE

Dim strMsg, strDateTime
Dim objShell, objFile, fso, fsoTemp, strScriptDir, strScriptName
Dim objNetwork, strUserName, strUserDomain, strComputerName
Dim objConnection, objCommand, rs, objRootDSE
Dim strQuery, UserADsPath, strDNSDomain
Dim strTempFile, objFileTemp, strTempDir
Dim strUserID, strdisplayName
Dim bolMailboxRights, bolFirst, bolDSTappoint, bolSender

Dim objSession, strProfileInfo
Dim objMessage, objMessages, objFolder
Dim datStart, datEnd
Dim strServer, strUser, strDate, y
Dim numUserCount, numUserWithAppointCount, numAppointSingle, numAppointRecur
Dim numApptointSender

' Extended DST period: 11-Mar to 31-Mar; and 28-Oct to 03-Nov
Const conBeginDate = #3/11/2007#
Const conEndDate = #3/31/2007#

Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000 ' ADSI
Const ADS_SCOPE_SUBTREE = 2 ' ADSI

' ============================================================
' Get User Active Directory information
' ============================================================
set objConnection=Createobject("ADODB.Connection")
set objCommand=CreateObject("ADODB.Command")
objConnection.Provider="ADSDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
if err.number <> 0 then
strMsg = conScriptName & ": ERROR. Unable to establish AD connection"
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
Wscript.QUIT
End if

Set objCommand.ActiveConnection = objConnection
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
if conDEBUG then Wscript.Echo "strDNSDomain = " & strDNSDomain

strQuery = "SELECT sAMAccountName, mail, displayName, ADsPath FROM 'LDAP://" & strDNSDomain & "' WHERE " & _
"objectCategory='Person' AND objectClass='User' AND homeMDB='*'"
if conDEBUG then strQuery = strQuery & " AND (sAMAccountName = 'sleepy' or sAMAccountName = 'sneezy' or sAMAccountName = 'weepy')"
if conDEBUG then Wscript.Echo "strQuery = " & strQuery

objCommand.CommandText= strQuery
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set rs = objCommand.Execute
if err.number <> 0 then
strMsg = conScriptName & ": ERROR. Unable to query Active Directory"
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
Wscript.QUIT
end if
if (rs.BOF or rs.EOF) then
strMsg = conScriptName & ": ERROR. No entries found in Active Directory"
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
Wscript.QUIT
End if

numUserCount = 0
numUserWithAppointCount = 0
' header
wscript.Echo "User;Name;Recurruing;Single;Sender"
do while not rs.EOF
numUserCount = numUserCount + 1
'strUserADsPath = rs.fields("ADsPath").value
'strsAMAccountName = rs.fields("sAMAccountName").value
strServer = "server1.uni.edu" ' get later
strUser = rs.fields("mail").value
strdisplayName = rs.Fields("displayName").value

' WScript.Echo "Working on " & strUser

'Create Session object.
err.clear ' Unsure why this is needed here??
Set objSession = CreateObject("MAPI.Session")
if Err.Number <> 0 Then
WScript.Echo "1Err = " & Err.Number & " " & Err.Description
Wscript.Quit
End If

strProfileInfo = strServer & vbLf & strUser

objSession.Logon , , False, True, , True, strProfileInfo
if Err.Number <> 0 Then
if not(Err.number = -2147221231 or err.number=-2147221219) then WScript.Echo strUser & " 2Err = " & Err.Number & " " & Err.Description
bolMailboxRights = FALSE
else
bolMailboxRights = TRUE
End If


if bolMailboxRights then
' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdo/html/ad419f23-4215-49c8-a9b6-ae9ba49d2707.asp
' 13 = Pacific time zone (North America)

Set objFolder = objSession.GetDefaultFolder(0)
if Err.Number <> 0 Then
WScript.Echo "3Err = " & Err.Number & " " & Err.Description
Wscript.Quit
end if
Set objMessages = objFolder.Messages
if Err.Number <> 0 Then
WScript.Echo "4Err = " & Err.Number & " " & Err.Description
Wscript.Quit
end if

bolFirst = true
numAppointSingle = 0
numAppointRecur = 0
numApptointSender = 0
For Each objMessage in objMessages
strDate = objMessage.StartTime
y = Instr(strDate, " ") - 1
datStart = cDate(Left(strDate,y))

strDate = objMessage.EndTime
y = Instr(strDate, " ") - 1
datEnd = cDate(Left(strDate,y))

bolDSTappoint = ((datStart >= conBeginDate AND datStart <= conEndDate) _
OR (datEnd >= conBeginDate and datEnd <= conEndDate)) _
AND NOT objMessage.AllDayEvent
bolSender = (objMessage.Sender = strdisplayName)
if conDEBUG then Wscript.Echo ".Sender = " & objMessage.Sender
if conDEBUG then Wscript.Echo "strdisplayName " & strdisplayName
if conDEBUG then Wscript.Echo "bolSender = " & bolSender
if bolDSTappoint then
if objMessage.IsRecurring then
numAppointRecur = numAppointRecur + 1
else
numAppointSingle = numAppointSingle + 1
end if
if bolSender then numApptointSender = numApptointSender + 1
end if
Next
Set objSession = Nothing
end if ' bolMailboxRights
if (numAppointRecur + numAppointSingle) > 0 then
wscript.Echo strUser & ";" & strdisplayName & ";" & numAppointRecur & ";" & numAppointSingle & ";" & numApptointSender
numUserWithAppointCount = numUserWithAppointCount + 1
end if

rs.MoveNext

Loop

Wscript.Echo "numUserCount = " & numUserCount
Wscript.Echo "numUserWithAppointCount = " & numUserWithAppointCount

Monday, January 29, 2007

RestartComputer.bat: Restart server

Author: Robert Lawson
Environment: Windows Server, Active Directory
Description: This script will restart a windows server. This is handy to schedule a restart "after hours", after updates have been applied.
Code:
rem file   : RestartComputer.bat
rem purpose: restart computer
rem author : Robert Lawson, 29-Jan-2007
rem /l = logs current user off immediately!
rem /r = restart after shutdown
SHUTDOWN /r /d p:0:0 /c "Monthly restart to fix haning EAS client" /l

Monday, December 25, 2006

dsq1.bat: common AD queries

Author: Robert Lawson
Environment: Windows Server, Active Directory
Description: These are the most common queries I use to gather information from Active Directory, and usually import results into Excel for auditing and/or reporting. I do save most common OU's to simply cut-and-paste, else I'll use ADSI-edit to get the OU. I simply remove the REM from query I want to use, then execute as such:

dsq1.bat>dsq1.txt
Uses:
- Stale passwords: report users who password is due to expire, call and educate before it expires. I did this for 1 year… no longer an issue
- Inactive computers: monitored for a year, removed manually. Then on negotiating with User Services, agreed to 9month and automatically remove.
- Mailbox store: audit that conventions were being followed: students, employees, non-named accounts, inactive…
- Group membership: quick way to get e-list of members
- Security: members of Domain Admin, Enterprise Admin..
- Ad hoc queries: total number of active students, employees….
Code:

rem file   : dsq1.bat
rem purpose: AD Query's
rem create : 25-dec-2006/r lawson
rem
rem notes
rem - un-REM query you want to use
rem - execute to verify no syntax error
rem - dsq1.cmd>dsq1.txt
rem - Import dsq1.txt into Excel for reporting

rem computers, in AV, inactive for 1 year
rem dsquery computer "DC=school,DC=edu" -inactive 52 -limit 0 dsget computer -samid -dn

rem all computer names
rem
rem dsquery computer "OU=AvServers,OU=location,DC=school,DC=edu" -limit 0 dsget computer -samid

rem computers, inactive for x weeks
rem dsquery computer "OU=Computer Accounts,DC=school,DC=edu" -limit 0 dsget computer -samid -sid -desc -loc
rem dsquery computer "OU=Computer Accounts,DC=school,DC=edu" -o rdn -limit 0 -inactive 12
rem dsquery * "OU=Computers,OU=Calabasas,DC=school,DC=edu" -attr cn operatingSystem operatingSystemServicePack lastlogonTimeStamp -limit 0


rem users, in Calabasas campus, with disabled accounts
rem dsquery user "OU=Calabasas,DC=school,DC=edu" -disabled -limit 0

rem all users, inactive for 1 year
rem dsquery user "DC=school,DC=edu" -inactive 26 -limit 0 dsget user -samid -display -disabled -dn

rem all users, who have not changed pw for 60 days
rem dsquery user "DC=school,DC=edu" -stalepwd 60 -limit 0
rem users who's password will expire in 5 days (90-85)
rem dsquery user "OU=Staff,OU=Users,OU=location,DC=school,DC=edu" -stalepwd 83 -limit 0 dsget user -samid -email -empid -display -title -dept -tel -office -disabled -canchpwd -pwdneverexpires -acctexpires -mustchpwd

rem all email enabled users
rem dsquery * "DC=school,DC=edu" -filter "(&(objectCategory=Person)(objectClass=User)(homeMDB=*)) " -attr sAMAccountName displayName distinguishedName homeMDB userAccountControl -limit 0


rem all Users in an OU
dsquery * "OU=Students,DC=school,DC=edu" -filter "(&(objectCategory=Person)(objectClass=User))" -attr sAMAccountName displayName givenName description sn employeeID employeeNumber department homeMDB userAccountControl -limit 0

rem another form of users in an OU
rem dsquery user "OU=janitors,OU=location,DC=school,DC=edu" -limit 0 dsget user -samid -display -disabled -canchpwd -pwdneverexpires -acctexpires

rem single user, display info
rem dsquery user "CN=edummy,OU=Consultants And Temporary Users,OU=All AV Employees,OU=location,DC=school,DC=edu" dsget user -samid -display -disabled -canchpwd -pwdneverexpires -acctexpires

rem get members of a group
rem dsquery group "OU=ADgroups,OU=location,DC=school,DC=edu" -name "grpUGClassOf2012"dsget group -members -expanddsget user -samid -fn -ln -title -dept -disabled -mustchpwd -pwdneverexpires

rem groups
rem dsquery * "OU=ADgroups,OU=location,DC=school,DC=edu" -filter "(&(objectCategory=Group)(objectClass=Group))" -limit 0 -attr sAMAccountName displayName name description mail member

rem users 1: AD attributes, LDAP filter
rem dsquery * "DC=school,DC=edu" -filter "(&(objectCategory=Person)(objectClass=User))" -limit 0 -attr sAMAccountName displayName employeeID employeeNumber userAccountControl delivContLength submissionContLength mdbUseDefaults mDBStorageQuota mDBOverHardQuotaLimit msExchHideFromAddressLists memberOf

rem Users 2: AD attributes
rem dsquery * "OU=Students,OU=location,DC=school,DC=edu" -limit 0 -attr sAMAccountName displayName employeeID employeeNumber telephoneNumber ciscoEcsbuDtmfId physicalDeliveryOfficeName createTimeStamp whenCreated department title userAccountControl msExchHideFromAddressLists mail protocolSettings homeMDB memberOf

rem Users 3: Query elements
rem dsquery user "OU=NewStudents,OU=Users,DC=school,DC=edu" -limit 0 dsget user -samid -email -empid -display -title -dept -tel -office -disabled -pwdneverexpires -acctexpires -mustchpwd


rem Users 3: Query elements, brief
rem dsquery user "OU=NewStudents,DC=school,DC=edu" -limit 0 dsget user -samid -fn -ln

rem computers with bogus container setting

rem dsquery * "OU=Computer Accounts,DC=school,DC=edu" -limit 0 -attr sAMAccountName CN msDS-Approx-Immed-Subordinates memberOf

rem find oddities with T/S (doesn't seem to work May 2006)
rem dsquery * "OU=Users,DC=school,DC=edu" -limit 0 -attr sAMAccountName displayName department title scriptPath TerminalServicesProfilePath TerminalServicesHomeDirectory TerminalServicesHomeDrive TerminalServicesWorkDirectory TerminalServicesInitialProgram

Saturday, December 2, 2006

UserOutlookRemovePSTref.vbs: Remove Outlook pst features

Author: Robert Lawson
Environment: Windows XP, Outlook, vb-script
Description: This script is run from Active Directory Group Policy log on script to disable Outlook personal mailbox files, pst files. The script includes a built-in method to deploy to pilot group. To make trouble shooting easier, all steps are written to application event log
Code:
'=========================================================================
' FILE : UserOutlookRemovePSTref.vbs
' AUTHOR : Robert Lawson
' COMPANY: Soka University of America
' DATE : 12/02/2006 Robert Lawson Creation Date
' COMMENT: Remove PST file references in Outlook profile
' Note, after this is run, the only repair to the Outlook profile is to delete it
' Office 2003 only (Office Versions: 11.0 = 2003; 10.0 = XP)
' Assume: 1) Outlook installed, 2) Outlook has been opened
' ' http://www.codecomments.com/message383229.html primary source of info
'=========================================================================
option explicit
On Error Resume Next ' Required
const conScriptName = "UserOutlookRemovePSTref.vbs"
const conDEBUG = FALSE
const conUpdateRegKeys = TRUE ' TRUE = will update Outlook reg keys
const conPilot = TRUE ' TRUE = script for pilot group of users, FALSE= all users considered

Dim strMsg, intLoc, objShell
Dim objNetwork, strUserName, strUserDomain, strGroupName, strComputerName
DIM Result, objReg, Return, strComputer, junk, count
Dim arrEntrynames(),Profile, arrProfiles(), ProfileSubkey, arrProfileSubKeys(), arrValueTypes(), arrValue
Dim strPSTFileName, strPSTRefence, strPSTKey, strRemoveKey, strKey
Const conOutlookProfileKey = "Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\"
Const HKCR=&H80000000 'HKEY_CLASSES_ROOT
Const HKCU=&H80000001 'HKEY_CURRENT_USER
Const HKLM=&H80000002 'HKEY_LOCAL_MACHINE
Const HKU=&H80000003 'HKEY_USERS
Const HKCC=&H80000005 'HKEY_CURRENT_CONFIG

' ============================================================
' Setup
' ============================================================
Set objShell = CreateObject( "WScript.Shell" )
Set objNetwork = Wscript.CreateObject("Wscript.Network")
strComputer = "."
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
strMsg = "BEGIN: " & conScriptName
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
strComputerName = objNetwork.ComputerName
strUserName = objNetwork.UserName
strUserDomain = objNetwork.UserDomain
strMsg = conScriptName & " values: CN = " & strComputerName & "; UN = " & strUserName & "; DN = " & strUserDomain
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

if (conPilot and NOT PilotByList(strUserName)) then
strMsg = conScriptName & "; Stopped. User not part of pilot group. User = " & strUserName
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
Wscript.Quit
end if ' Pilot

' ============================================================
' Main:
' ' Enumerate each Outlook profile for this user
' ' Remove key with PST file reference
' ============================================================
objReg.EnumKey HKCU, conOutlookProfileKey, arrProfiles
For Each Profile in arrProfiles
if conDEBUG then Wscript.Echo "Profile = " & Profile
objReg.EnumKey HKCU, conOutlookProfileKey & Profile & "\", arrProfileSubKeys
For Each ProfileSubkey In arrProfileSubKeys
strMsg = "ProfileSubkey = " & ProfileSubkey
if conDEBUG then Wscript.Echo strMsg
objReg.EnumValues HKCU,conOutlookProfileKey & Profile & "\" & ProfileSubKey & "\",arrEntryNames,arrValueTypes
Err.Clear
junk = UBound(arrEntryNames) ' Ignore keys that have no entries.
If Err.Number = 0 Then
strPSTFileName = ""
strPSTRefence = ""
strPSTKey = ProfileSubkey
For Count=0 To UBound(arrEntryNames)
' 001f6700 = Fully qualified file name
strKey = "001f6700"
If arrEntryNames(Count) = strKey Then
objReg.GetBinaryValue HKCU,conOutlookProfileKey & Profile & "\" & ProfileSubKey & "\",strKey,arrValue
strPSTFileName = BinaryToString(arrValue)
End If
' 001f3006 = Name of reference in Outlook
strKey = "001f3006"
If arrEntryNames(Count) = strKey Then
objReg.GetBinaryValue HKCU,conOutlookProfileKey & Profile & "\" & ProfileSubKey & "\",strKey,arrValue
strPSTRefence = BinaryToString(arrValue)
end if
Next ' UBound(arrEntryNames)
' Remove key(s) with PST file reference.
if LEN(strPSTFileName) > 0 then
strMsg = "*strPSTKey = " & strPSTKey & "; strPSTFileName = " & strPSTFileName & "; strPSTRefence =" & strPSTRefence
if conDEBUG then Wscript.Echo strMsg
strRemoveKey = conOutlookProfileKey & Profile & "\" & strPSTKey
strMsg = "*strRemoveKey = " & strRemoveKey
if conDEBUG then Wscript.Echo strMsg
if conUpdateRegKeys then
Return = objReg.DeleteKey(HKCU, strRemoveKey)
If (Return = 0) And (Err.Number = 0) Then
strMsg = conScriptName & ": REMOVED KEY: = " & strRemoveKey
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
strMsg = conScriptName & ": strPSTFileName = " & strPSTFileName & "; strPSTRefence =" & strPSTRefence
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
Else
Wscript.Echo conScriptName & ": DeleteKey failed. Error = " & Err.Number & " on key = " & strRemoveKey
objShell.LogEvent 0,strMsg
End If
end if
end if
End If
Next ' arrProfileSubKeys
Next ' arrProfiles
' ============================================================
' The End
' ============================================================
strMsg = "END: " & conScriptName
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
set objShell = nothing
Set objNetwork = Nothing
set objReg = nothing

' ============================================================
' Functions: BinaryToString
' ============================================================
Function BinaryToString(val)
Dim bByte, retval, i
For i = 0 To (UBound(val)-2) Step 2
bByte = val(i)
If bByte <> "" Then retval = retval & Chr(bByte)
Next
BinaryToString = retval
End Function

' ============================================================
' Function: PilotByList
' ============================================================
Function PilotByList(strUserID)
' PilotByList: determine pilot group by list of users
' strUserID String Passed User Network ID (sAMAccountname)
' PilotByList Boolean Returned TRUE=UserID is part of pilot group, FALSE=it aint
Dim strUser
PilotByList = FALSE ' default
strUser = lcase(strUserID) ' only lower case
PilotByList = ( _
strUser = "sleepy" or _
strUser = "sneezy" or _
strUser = "weepy" or _
strUser = "dopey" or _
strUser = "grumpy")
End Function ' PilotByList


Friday, October 27, 2006

DriveMapEmployee.vbs: Map network drive

Author: Robert Lawson
Environment: Windows Server, Active Directory, Group Policy, vb-script
Description: This script maps a user's network drive to a pre-reserved Windows drive for two campus. The campus is determined by user's primary IP address. This script is run at log on from Active Directory Group Policy. Each step is written to application event log for easy trouble shooting.

Code:

'=========================================================================
' FILE : DriveMapEmployee.vbs
' AUTHOR : Robert Lawson
' COMPANY: Soka University of America
' DATE : 10/27/2006
' COMMENT: Map primary drive for employees
'
'=========================================================================
Option Explicit
On Error Resume Next ' Required, or fails if already mapped

const conScriptName = "DriveMapEmployee.vbs"
const conDEBUG = TRUE

Dim objNetwork, objShell, objDrives
Dim strComputerName, strUserName, strUserDomain
Dim strDrive, strShare, strCurrentCampus, strDriveOld, strShareOld
Dim bolAlreadyMapped, bolAVCampus, bolCALCampus
Dim wmi, nics, nic, ip, strIP, i
Dim strMsg

Const conAVIP = "10."
Const conCALIP = "172.16"
Const conAVCampus = "AlisoViejo"
Const conCALCampus = "Calabasas"
Const conUNKCampus = "Unknown"
Const conAVshare = "\\server1\userstore\"
Const conCALshare = "\\rserver2\Employees\"
Const conMapDrive = "U:"

' ============================================================
' Setup
' ============================================================
Set objNetwork = Wscript.CreateObject("Wscript.Network")
Set objShell = CreateObject( "WScript.Shell" )

strMsg = "BEGIN: " & conScriptName
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

' ============================================================
' Get user info
' ============================================================
strComputerName = objNetwork.ComputerName
strUserName = objNetwork.UserName
strUserDomain = objNetwork.UserDomain
strMsg = conScriptName & " values: CN = " & strComputerName & "; UN = " & strUserName & "; DN = " & strUserDomain
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

' Get IP address (there could be multiple)
bolAVCampus = FALSE
bolCALCampus = FALSE
Set wmi = GetObject("winmgmts:\\.\root\cimv2")
Set nics = wmi.ExecQuery("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True")
For Each nic In nics
For Each ip In nic.ipaddress
strIP = ip
'strIP = "172.16.10.11" '*************** DEBUG
if conDEBUG then WScript.Echo "IP: " & strIP
if LEN(strIP) > 0 then
if left(strIP,3) = conAVIP then
bolAVCampus = TRUE
elseif left(strIP,6) = conCALIP then
bolCALCampus = TRUE
End if
End if
Next
Next

' You know current campus
if bolAVCampus then
strCurrentCampus = conAVCampus
elseif bolCALCampus then
strCurrentCampus = conCALCampus
else
strCurrentCampus = conUNKCampus
end if
if conDEBUG then Wscript.Echo "Campus = " & strCurrentCampus

' Did you figure out campus?
if strCurrentCampus = conUNKCampus then
strMsg = conScriptName & ": Unable to deterine campus from IP address"
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
WScript.Quit
end if

' ============================================================
' Map away
' ============================================================
strDrive = conMapDrive

if strCurrentCampus = conAVCampus then
strShare = conAVshare & strUserName
elseif strCurrentCampus = conCALCampus then
strShare = conCALshare & strUserName
end if

' Get current mapping
bolAlreadyMapped = False
Set objDrives = objNetwork.EnumNetworkDrives
For i = 0 to objDrives.Count - 1 Step 2
strDriveOld = objDrives.Item(i)
strShareOld = objDrives.Item(i+1)
if conDEBUG then WScript.Echo "Drive " & strDriveOld & " = " & strShareOld
bolAlreadyMapped = (strDrive = strDriveOld) and (strShare = strShareOld)
Next
if conDEBUG then WScript.Echo "bolAlreadyMapped = " & bolAlreadyMapped

if NOT bolAlreadyMapped then
' Remove mapping if it is already there (else mapping will fail)
objNetwork.RemoveNetworkDrive strDrive, TRUE, TRUE
err.clear

' Map thu pig
objNetwork.MapNetworkDrive strDrive, strShare, TRUE
If err.number = 0 then
strMsg = conScriptName & ": Mapped " & strDrive & " to " & strShare
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
else
strMsg = conScriptName & ": Err = " & err.number & "; " & err.description
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
WScript.Quit
End if
else
strMsg = conScriptName & ": No change, alread mapped " & strDrive & " to " & strShare
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
end if ' bolAlreadyMapped

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

Set objNetwork = Nothing

Wednesday, October 11, 2006

OC.SendAppMail: New user introductory email

Author: Robert Lawson
Environment: Windows Server, Access/VBA, Microsoft SQL Server
Description: This code sends a new user an introductory orientation email for both email and phone/voice mail. The wording was crafted in conjunction with User Services to serve as basis for orientation training. For MS Exchange email, this email also forces the mailbox setup (known issue/consideration). The email orientation is sent upon account/mailbox creation (this also forces the Exchange mailbox setup). The phone orientation is sent when the phone is setup (when the Active Directory phone number is synced with the Cisco Unity system, see OC.CPRebuild).
Features:

- HTML form email, designed in DreamWeaver
- Personalized with variable substitution
- bcc copy to administrator and help desk
Samples:





Code:

Public Sub SendAppMail(strID As String, strUType As String, strEmailType As String, bolOnLine As Boolean, intStatus2 As Integer)

' Sends email to users

' 11-Sept-2006 Robert Lawson Creation date

' 27-Dec-2007 Robert Lawson Updated for ADO



' strID Passed OneCard ID number

' strUType Passed User Type from GetUtype function

' strEmailType Passed Type of email: "NewEmailUser", "NewPhoneUser"

' bolOnLine Passed TRUE=you're interactive

' intstatus2 Returned 0=OK, <>0 You're not OK

On Error GoTo ErrorBegin

Dim strName As String

strName = "SendAppMail"



Dim strNETEmail As String, strFullName As String

Dim strLDCode As String, strCampusPhone As String

Dim strFrom As String, strTo As String, strBCC As String, strSubject As String, strBody As String

Dim strFile As String, strLine As String, strExt



Const conFullName = "#FULLNAME#"

Const conPhoneNumber = "#PHONENUMBER#"

Const conLDCode = "#LDCODE#"

Const conEmail = "#EMAIL#"



Const conEmailUserAdmin = "Robert.Lawson@uni.edu"

Const conPhoneUserAdmin = "winky@uni.edu,Robert.Lawson@uni.edu,sleepy@uni.edu"

Const conOneCardAdmin = "admin@uni.edu"



intStatus2 = 0

strMessage = conNoMessage



Call LoadSysDbconn(intStatus)

If intStatus <> 0 Then

strMessage = "Error calling LoadSysDbconn."

Err.Raise (vbObjectError + 10), , strMessage

GoTo ErrorBegin

End If

strTodayDate = Format(Now(), "mm/dd/yyyy")



' Valid type?

If Not (strEmailType = conEmailUser Or strEmailType = conPhoneUser) Then

strMessage = strName & ":invalid EmailType = " & strEmailType

intStatus2 = -10

GoTo ErrorBegin

End If



' Get person's info

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

Debug.Print strSQL

Set objRS = CreateObject("ADODB.Recordset")

objRS.Open strSQL, conDbOneCard, adOpenDynamic, adLockReadOnly ' read access

With objRS

If (.BOF Or .EOF) Then

strMessage = strName & ": Unable to get OneCardMaster record for ID = " & strID

intStatus2 = -20

GoTo ErrorBegin

Else

strNETEmail = Nz(!NETEMail, "")

strFullName = Trim(Nz(!NameFirst, "")) & " " & Trim(Nz(!NameLast, ""))

strCampusPhone = Trim(Nz(!CampusPhone, ""))

End If

End With

Set objRS = Nothing



' Verify they have email address

If (Len(strNETEmail) = 0) Then

strMessage = strName & ": No email for ID = " & strID

intStatus2 = -30

GoTo ErrorBegin

End If



' Get Long Distance Code ***********************

If strEmailType = conPhoneUser Then

'strExt = Right(strCampusPhone, 4)

'strSQL = "SELECT code FROM FACInfo WHERE description = " & """" & strExt & """"

'Debug.Print strSQL

'Set rs = Db.OpenRecordset(strSQL, dbOpenDynaset, dbSeeChanges)

'If (rs.BOF Or rs.EOF) Then

' StrMessage = strName & ": Unable to get Long Distance code for ID = " & strID

' intstatus2 = -1

' GoTo ErrorBegin

'End If

'strLDCode = rs!code

'rs.Close

strLDCode = " "

End If



' Set correct variables for email type

If strEmailType = conEmailUser Then

strFile = "D:\Data\doc\OneCardNoticeMail.htm"

strTo = strNETEmail

strFrom = conOneCardAdmin

strBCC = conEmailUserAdmin

strSubject = "Your email information" & strFullName

ElseIf strEmailType = conPhoneUser Then

strFile = "D:\Data\doc\OneCardNoticePhone.htm"

strTo = strNETEmail

strFrom = conOneCardAdmin

strBCC = conPhoneUserAdmin

strSubject = "Your phone information" & strFullName

End If



' Open file for email body (it must be in HTML format)

strBody = ""

Open strFile For Input As #1

Do Until EOF(1)

Line Input #1, strLine

strBody = strBody & strLine

Loop

Close #1

' Debug.Print strBody



' Substitute variables

If strEmailType = conEmailUser Then ' conEmail

strBody = Replace(strBody, conFullName, strFullName)

strBody = Replace(strBody, conEmail, strNETEmail)

ElseIf strEmailType = conPhoneUser Then

strBody = Replace(strBody, conFullName, strFullName)

strBody = Replace(strBody, conPhoneNumber, strCampusPhone)

strBody = Replace(strBody, conLDCode, strLDCode)

End If



Call SendHTMLmail(strFrom, strTo, strBCC, strSubject, strBody, intStatus)

Debug.Print "intStatus = " & intStatus



' Write to trans log table

Call DoDataLog(strName, "IN", "SUB-USER", strEmailType & " email notification", "", strID, strID, bolOnLine)



ExitBegin:

Exit Sub



ErrorBegin:

If intStatus2 = 0 Then ' General message

strMessage = "Error in " & strName & " " & Err.Number & " " & Err.Description & " on strID = " & Nz(strID, "")

intStatus2 = -100 ' I'm NOT OK

End If

If bolOnLine Then MsgBox strMessage

Call DoEventLog("ERR", strName, 500, strMessage, True, bolOnLine)

GoTo ExitBegin

End Sub

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

VWEASUserQuotaUsage.SQL: EAS usage view

Author: Robert Lawson
Environment: Windows Server, Microsoft SQL Server, EAS
Description: This view simplifies access to EAS sytem tables and provides key to inhouse Onecard system and match to Active Directory sAMAccount name.
Used in conjunction with vbscripts to report over-quota and weekly usage. See EASUsageAudit.vbs and EASNearQuotaEmail.vbs .
Code:

/*
File : VWEASUserQuotaUsage.SQL
Update : 08-July-2006/Robert Lawson
Purpose: Usage and quota for EAS users (only users with usage)
Notes :
- Size and Quota are expressed in MB, Quota = -1, is unlimited
- Works with VWEASUserTopMsgs

SELECT * FROM VWEASUserQuotaUsage
*/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[VWEASUserQuotaUsage]') and OBJECTPROPERTY(id, N'IsView') = 1)
drop view [dbo].[VWEASUserQuotaUsage]

CREATE VIEW dbo.VWEASUserQuotaUsage AS
SELECT
US.USERID,
RTRIM(US.USERNAME) AS UserName,
US.EASQUOTAOPTION,
QuotaSize = CASE WHEN
US.EASQUOTAOPTION = 1 THEN GP.EASQUOTA
ELSE US.EASQUOTA
END,
GP.GROUPNAME,
QuotaType = CASE WHEN
US.EASQUOTAOPTION = 1 THEN 'Group'
ELSE 'User'
END,
RTRIM(RIGHT(NT.NTACCOUNT,(LEN(NT.NTACCOUNT) - CHARINDEX('\',NT.NTACCOUNT)))) AS sAMAccountName,
RTRIM(RIGHT(NT.NTACCOUNT,(LEN(NT.NTACCOUNT) - CHARINDEX('\',NT.NTACCOUNT)))) + '@uni.edu' AS Email,
COUNT(*) AS MsgCount,
SUM(CAST(PR.MSGSIZE AS BIGINT))/1048576 AS MsgSize
FROM PROFILE PR, REFER RF, GROUPS GP, NTACCOUNT NT, USERS US
WHERE
US.EASSTATUS = 0 AND
(US.GROUPID > 0 AND US.GROUPID <> 2) AND
NT.USERID = US.USERID AND
GP.GROUPID = US.GROUPID AND
RF.USERID = US.USERID AND
RF.FOLDERID > 0 AND
RF.FOLDERID = (SELECT MAX(R2.FOLDERID) FROM REFER R2 WHERE
R2.USERID = RF.USERID AND R2.MSGID = RF.MSGID AND R2.FOLDERID > 0) AND
PR.MSGID = RF.MSGID
GROUP BY US.USERID, US.USERNAME, US.EASQUOTAOPTION, GP.EASQUOTA, US.EASQUOTA, NT.NTACCOUNT, GP.GROUPNAME

VWEASUserTopMsgs.sql: EAS top user attachments

Author: Robert Lawson
Environment: Windows Server, Microsoft SQL Server, EAS
Description: This view simplifies access to EAS sytem tables and list of largest email attachments. Used in conjunction with vbscripts to report over-quota and weekly usage. See EASUsageAudit.vbs .
Code:
/*
File : VWEASUserTopMsgs.sql
Update : 08-July-2006/Robert Lawson
Purpose: Get biggest emails for a given user
Notes :
- Size is in MB to be consistent with Quota and VWEASUserQuotaUsage
- Works with VWEASUserQuotaUsage (gets the user information)

SELECT TOP 20 * FROM VWEASUserTopMsgs WHERE USERID = 9 ORDER BY MsgSize DESC
*/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[VWEASUserTopMsgs]') and OBJECTPROPERTY(id, N'IsView') = 1)
drop view [dbo].[VWEASUserTopMsgs]

CREATE VIEW dbo.VWEASUserTopMsgs AS
SELECT
RF.MSGID,
RF.USERID,
FL.FOLDERNAME,
PR.SUBJECT,
PR.FROMFLD,
PR.MSGDATE,
PR.MSGSIZE/1048576 MsgSize
FROM FOLDER FL, PROFILE PR, REFER RF
WHERE
RF.FOLDERID > 0 AND
RF.FOLDERID = (SELECT MAX(R2.FOLDERID) FROM REFER R2 WHERE
R2.USERID = RF.USERID AND R2.MSGID = RF.MSGID AND R2.FOLDERID > 0) AND
PR.MSGID = RF.MSGID AND
FL.USERID = RF.USERID AND
FL.FOLDERID = RF.FOLDERID

Monday, June 19, 2006

UserOutlookEAS.vbs: Install EAS Outlook client

Author: Robert Lawson
Environment: Windows XP, Outlook , EAS, vb-script
Description: This installs the EAS client for Outlook users in a given Active Directory OU, if they are a member of an EAS group
. This script is run as Active Directory Group Policy log on script, and to make trouble shooting easier, all steps are written to application event log.
Code:
'=========================================================================
' VBScript Source File -- Created with XLnow OnScript
' FILE : UserOutlookEAS.vbs
' AUTHOR : Robert Lawson
' COMPANY: Soka University of America
' DATE : 6/19/2006 Robert Lawson Creation Date
' 11/20/2006 Robert Lawson Always do Outlook updates, improved on EAS logic
' 12/01/2006 Robert Lawson Added disable menu and remove pst references
' COMMENT: Manage EAS deployment: installing EAS client, and making Outlook setting
' conUpdateRegKeys controls if this will update registry keys (Outlook settings)
' Office 2003 only (Office Versions: 11.0 = 2003; 10.0 = XP)
' Registry keys are not setup by default by Outlook

'=========================================================================
option explicit
On Error Resume Next ' Required for reading registry
const conScriptName = "UserOutlookEAS.vbs"
const conDEBUG = FALSE
const conUpdateRegKeys = TRUE ' TRUE = will update Outlook reg keys

Dim strMsg, intLoc
Dim objShell, varTemp, bolRegKeyExists, varNewValue
Dim objFSO, objTS, objExecute
Dim bolOutlookInstalled, bolZantazClientInstalled, bolEASUser
Dim objNetwork, strUserName, strUserDomain, strGroupName, strComputerName
Dim strOU, strFilter, strQuery, rs, objCommand, UserADsPath, objUser, objConnection, objGroup, strKey

const conOutlookRegistryKey = "HKCU\Software\Microsoft\Office\11.0\Outlook\OutlookName"
const conOutlookDisableAutoArchiveKey = "HKCU\Software\Microsoft\Office\11.0\Outlook\Preferences\DoAging"
const conOutlookDisableCreatePSTfilesKey = "HKLM\SOFTWARE\Microsoft\Office\11.0\Outlook\DisablePST"
const conOutlookDisabledCmdBarKey = "HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\11.0\Outlook\DisabledCmdBarItemsList"
const conZantazFile = "C:\Program Files\ZANTAZ\EAS Client\EASCOMPRESS.dll"
const conEASclient = "\\server3\Client\uniClient.msi"
const conRegKeyYes = 1
const conEASGroup = "EASUser"

' Window stype to run
const WINDOWHIDDEN = 0
const WINDOWNORMAL = 1
const WINDOWMINIMIZE = 2
Const ADS_SCOPE_SUBTREE = 2

' ============================================================
' Setup
' ============================================================
Set objShell = CreateObject( "WScript.Shell" )
Set objNetwork = Wscript.CreateObject("Wscript.Network")

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

strMsg = "BEGIN: " & conScriptName
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

' ============================================================
' Determine if EAS User (determined by AD group membership)?
' ============================================================
' Get User Info from Network log in
strComputerName = objNetwork.ComputerName
strUserName = objNetwork.UserName
strUserDomain = objNetwork.UserDomain
strMsg = conScriptName & " values: CN = " & strComputerName & "; UN = " & strUserName & "; DN = " & strUserDomain
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

' Get User Active Directory information
bolEASUser = FALSE
strOU = "DC=uni,DC=edu"
strFilter = "sAMAccountName = " & "'" & strUserName & "'"
strQuery = "SELECT ADsPath FROM 'LDAP://" & strOU & "' WHERE " & strFilter

strMsg = conScriptName & ": LDAP strQuery = " & strQuery
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

objCommand.CommandText= strQuery
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set rs = objCommand.Execute
if rs.EOF or rs.BOF then
intLoc = 5
strMsg = conScriptName & ": Error @ " & intLoc & ". Unabled to get AD user for " & strUserName
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
else
' Verify if user is member of an EAS group
UserADsPath = rs.fields("ADsPath").value
Set objUser = GetObject(UserADsPath)

For Each objGroup In objUser.Groups
' sample: "CN=grpPeopleSoftDBTech"
strGroupName = objGroup.Name
if conDEBUG then Wscript.Echo strGroupName
bolEASUser = (instr(1,strGroupName,conEASGroup) > 0)
if bolEASUser then Exit For
Next
end if
strMsg = conScriptName & ": bolEASUser = " & bolEASUser
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

' ============================================================
' Is Outlook installed for this computer user?
' ============================================================
varTemp = objShell.RegRead (conOutlookRegistryKey)
bolOutlookInstalled = (Err.number= 0)
if conDEBUG then Wscript.Echo " bolOutlookInstalled= " & bolOutlookInstalled

' ============================================================
' Is Zantaz EAS client installed on this computer? If not, do so
' ============================================================
set objFSO = CreateObject("Scripting.FileSystemObject")
bolZantazClientInstalled = (objFSO.FileExists(conZantazFile))
strMsg = conScriptName & ": bolOutlookInstalled = " & bolOutlookInstalled & "; conUpdateRegKeys = " & conUpdateRegKeys & _
"; bolZantazClientInstalled = " & bolZantazClientInstalled
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg

' Need to install EAS client?
if bolOutlookInstalled and Not bolZantazClientInstalled then
set objFSO = CreateObject("Scripting.FileSystemObject")
if (objFSO.FileExists(conEASclient)) then
objShell.Run conEASclient, WINDOWHIDDEN, True
if err.number = 0 then
strMsg = conScriptName & ": Installed successfully " & conEASclient
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
bolZantazClientInstalled = TRUE
else
intLoc = 10
strMsg = conScriptName & ": Error @ " & intLoc & " Num = " & Err.number & " " & Err.Description
DoError(strMsg) ' Failed to execute
end if
else
intLoc = 15
strMsg = conScriptName & ": Error @ " & intLoc & ". File does not exist " & conEASclient
DoError(strMsg) ' File does not exist
end if
end if

' ============================================================
' Update Outlook Registry Entries?
' ============================================================
if bolOutlookInstalled and conUpdateRegKeys then
' Disable auto archive features? 1=yes, 0=no (if no registry, treated as = 0)
varTemp = ""
varTemp = obJShell.RegRead(conOutlookDisableAutoArchiveKey)
bolRegKeyExists = (err.number = 0)
err.Clear
if Not bolRegKeyExists or (varTemp <> conRegKeyYes) then
objShell.RegWrite conOutlookDisableAutoArchiveKey, conRegKeyYes, "REG_DWORD"
if err.number = 0 then
strMsg = conScriptName & ": Updated registry " & conOutlookDisableAutoArchiveKey
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
else
intLoc = 20
strMsg = conScriptName & ": Error @ " & intLoc & " Num = " & Err.number & " " & Err.Description
DoError(strMsg) ' Failed to execute
end if
else
strMsg = conScriptName & ": Registry not updated, value already set for " & conOutlookDisableAutoArchiveKey
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
end if

' Disable creating any pst files? 1=yes, 0=no (if no registry, treated as = 0)
varTemp = ""
varTemp = obJShell.RegRead(conOutlookDisableCreatePSTfilesKey)
bolRegKeyExists = (err.number = 0)
err.Clear
if Not bolRegKeyExists or (varTemp <> conRegKeyYes) then
objShell.RegWrite conOutlookDisableCreatePSTfilesKey, conRegKeyYes, "REG_DWORD"
if err.number = 0 then
strMsg = conScriptName & ": Updated registry " & conOutlookDisableCreatePSTfilesKey
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
else
intLoc = 23
strMsg = conScriptName & ": Error @ " & intLoc & " Num = " & Err.number & " " & Err.Description
DoError(strMsg) ' Failed to execute
end if
else
strMsg = conScriptName & ": Registry not updated, value already set for " & conOutlookDisableCreatePSTfilesKey
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
end if

' Disable Outlook menu items KB309136
' TCID1 5575 Disable option to create a PST (File>New>Outlook Data File)
' TCID2 5576 Disable option to open a PST (File>Open>Outlook Data File)
strKey = conOutlookDisabledCmdBarKey & "\TCID1" ' Unique value for menu disable
varNewValue = "5575" ' Disable option to create a PST
objShell.RegWrite strKey, varNewValue, "REG_SZ"
if err.number = 0 or err.number = 500 then
err.Clear
strMsg = conScriptName & ": Updated registry " & strKey
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
else
intLoc = 25
strMsg = conScriptName & ": Error @ " & intLoc & " Num = " & Err.number & " " & Err.Description
DoError(strMsg) ' Failed to execute
end if

strKey = conOutlookDisabledCmdBarKey & "\TCID2" ' Unique value for menu disable
varNewValue = "5576" ' Disable option to open a PST
objShell.RegWrite strKey, varNewValue, "REG_SZ"
if err.number = 0 or err.number = 500 then
err.Clear
strMsg = conScriptName & ": Updated registry " & strKey
if conDEBUG then Wscript.Echo strMsg
objShell.LogEvent 0,strMsg
else
intLoc = 30
strMsg = conScriptName & ": Error @ " & intLoc & " Num = " & Err.number & " " & Err.Description
DoError(strMsg) ' Failed to execute
end if
end if ' Registry Entry update

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

Set objNetwork = 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