Query all objects in active directory using LDAP, vbScript or PowerShell - powershell

I'm hoping someone has already developed a script to do this.
I'm need to query all objects in AD (users, computers, containers (OU's), everything exceot for the forest root) and show which objects in AD do not have the "Include inheritable permissions from this object's parent" attribute checked.
Thanks much

If you show some initiative, I can help in VBS. I wrote a VBS a while ago to query everything in AD for below attributes via LDAP, and putting results in Excel and plain text file.
"objectCategory"
"objectClass"
"objectGUID"
"objectSid"
"sIDHistory"
"sAMAccountName"
"description"
"sAMAccountType"
"userAccountControl"
"whenCreated"
"whenChanged"
"givenName"
"sn"
"displayName"
"title"
"mail"
"physicalDeliveryOfficeName"
"memberOf"
"telephoneNumber"
"mobile"
"pager"
"company"
"lastLogon"
"badPwdCount"
"badPasswordTime"
"streetAddress"
"l"
"postalCode"
"st"
"co"
I will show you my first 50/360 lines of code:
Const ADS_SCOPE_SUBTREE = 2
Const PageSize = 2000
Const GAP = "——————————————————————————————————————————————————"
'=== Public Variables ===
Dim aADProp, sRootLDAP, oRecordSet, oFSO, oLogFile, oExcel, oWB, oWS
Dim lObjects, lComputersEnabled, lUsersEnabled, lComputersDisabled, lUsersDisabled, lOtherDisabled, lExcelRow
Dim aUAC ' AD's UserAccountControl flags array
Dim aSAT ' AD's sAMAccountType flags array
'==================================================
Main
'==================================================
Sub Main
Init
ConnectAD
If Err.Number = 0 Then ProcessRecords
CleanUp
End Sub
'--------------------------------------------------
Sub Init
Dim dNow
dNow = Now
Wscript.echo dNow & vbTab & "Init"
DefineADProp
DefineUACArray
DefineSATArray
Set oFSO = CreateObject("scripting.filesystemobject")
Set oLogFile = oFSO.CreateTextFile(WScript.ScriptFullName & "_" & Join(Array(Year(dNow),Month(dNow),Day(dNow)),".") & ".log")
sRootLDAP = "'LDAP://" & GetObject("LDAP://RootDSE").Get("defaultNamingContext") & "'"
LogT vbCrlf & Q(WScript.ScriptFullName) & " started."
Logg "RootLDAP: " & sRootLDAP
Logg "Listing AD Attributes: " & Join(aADProp,", ")
Logg GAP
lObjects = 0
lUsersEnabled = 0
lUsersDisabled = 0
lComputersEnabled = 0
lComputersDisabled = 0
lOtherDisabled = 0
If Err.Number = 0 Then
lExcelRow = 1
Set oExcel = CreateObject("Excel.Application")
oExcel.visible = True
Set oWB = oExcel.Workbooks.Add
Set oWS = oWB.Worksheets(1)
oWS.Cells(lExcelRow,1) = "distinguishedName"
oWS.Range(oWS.Cells(lExcelRow,2),oWS.Cells(lExcelRow,UBound(aADProp)+2)) = aADProp
End If
End Sub

Yes I made a mistake and didn't post the question initially. When I posted originally, I wasn't able to enumerate all AD objects and had a question about that, but it is since been resolved and the code below works (in case anyone else needs it - sharing is OK). No need to try and reinvent the wheel if the code already existed. And many thanks to Rems # Petri
'
'//----------------------------- Code below -----------------------------//
'
Const SE_DACL_PROTECTED = &H1000
Dim objRootDSE
With WScript.CreateObject("WScript.Network")
Set objRootDSE = GetObject ("LDAP://" & .UserDomain & "/RootDSE")
End With
strDomainDN = objRootDSE.Get("DefaultNamingContext")
Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection
objCommand.Properties("Searchscope") = 2 ' SUBTREE
objCommand.Properties("Page Size") = 250
objCommand.Properties("Timeout") = 30
objCommand.Properties("Cache Results") = False
objCommand.CommandText = "SELECT ADsPath FROM 'LDAP://" & strDomainDN & "'"
Set objRecordSet = objCommand.Execute
On Error Resume Next
If Not objRecordSet.eof Then
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
ModUser objRecordSet.Fields("ADsPath").Value
objRecordSet.MoveNext
Loop
End If
objRecordset.Close : objConnection.Close
wscript.echo vbCrLf & "-- All done --" : wscript.quit 0
Sub ModUser(strADsPath)
Dim objUser, objNtSecurityDescriptor, intNtSecurityDescriptorControl
Set objuser = GetObject(strADsPath)
Set objNtSecurityDescriptor = objUser.Get("ntSecurityDescriptor")
intNtSecurityDescriptorControl = objNtSecurityDescriptor.Control
If (intNtSecurityDescriptorControl And SE_DACL_PROTECTED) Then
Wscript.Echo objUser.sAMAccountName & " (" & objUser.distinguishedName & ") is NOT checked"
End If
End Sub

Related

Tracking Chnages in Enterprise Architect

I encounter a real difficulty in tracking changes and updates in the company models.
I research the tool abilities a lot, but still didn't find the golden way that match my requirements of:
Provide indication where was a change
What was the change
Keep the original model state, aside to the up-to-date state
EA offers the following ways:
Baselines
Version Control
Clone
Change Elements
None of them provides indication on what exactly was the change and where.
What is the easiest way to manage the changes effectively?
You forgot the last resort: audit. Turn on auditing and you can get a lot more information. Of course this also has its drawbacks
it uses a lot of space
there are still changes that are not tracked in the detail you might need it.
Turn it on at Project/Auditing. More information here.
Additionally you could think of writing triggers, but I would not recommend that since it makes your repository almost unmaintainable.
Auditing is of course also no silver bullet. Tracking changes is tedious. And personally I would not spend too much effort in this "accusation mode". Better spend your energy in driving the model towards the company goals. Nobody needs yesterday's model.
I wrote some scripts to handle change management in EA.
The idea is that the user links the changed items to a change request element that represents a workitem, project, change request, bug,...
Each link contains the date, user and a comment for the change to that item.
The scripts are part of the open source EA VBScript library:
The main script is the following
'[path=\Projects\Project A\A Scripts]
'[group=Atrias Scripts]
!INC Local Scripts.EAConstants-VBScript
!INC Atrias Scripts.Util
' Script Name: LinkToCRMain
' Author: Geert Bellekens
' Purpose: Link Elemnents to a change
' Date: 2015-10-30
'
'
function linkItemToCR(selectedItem, selectedItems)
dim groupProcessing
groupProcessing = false
'if the collection is given then we initialize the first item.
if selectedItem is nothing then
if not selectedItems is nothing then
if selectedItems.Count > 0 then
set selectedItem = selectedItems(0)
if selectedItems.Count > 1 then
groupProcessing = true
end if
end if
end if
end if
if selectedItem is nothing then
set selectedItem = Repository.GetContextObject()
end if
'get the select context item type
dim selectedItemType
selectedItemType = selectedItem.ObjectType
select case selectedItemType
case otElement, otPackage, otAttribute, otMethod, otConnector :
'if the selectedItem is a package then we use the Element part of the package
if selectedItemType = otPackage then
set selectedItem = selectedItem.Element
end if
'get the logged in user
Dim userLogin
userLogin = getUserLogin
dim lastCR as EA.Element
set lastCR = nothing
dim CRtoUse as EA.Element
set CRtoUse = nothing
set lastCR = getLastUsedCR(userLogin)
'get most recent used CR by this user
if not selectedItem is nothing then
dim lastComments
lastComments = vbNullString
'if there is a last CR then we ask the user if we need to use that one
if not lastCR is nothing then
dim response
if groupProcessing then
response = Msgbox("Link all " & selectedItems.Count & " elements to change: """ & lastCR.Name & """?", vbYesNoCancel+vbQuestion, "Link to CR")
elseif not isCRLinked(selectedItem,lastCR) then
response = Msgbox("Link element """ & selectedItem.Name & """ to change: """ & lastCR.Name & """?", vbYesNoCancel+vbQuestion, "Link to CR")
end if
'check the response
select case response
case vbYes
set CRToUse = lastCR
case vbCancel
'user cancelled, stop altogether
Exit function
end select
end if
'If there was no last CR, or the user didn't want to link that one we let the user choose one
if CRToUse is nothing then
dim CR_id
CR_ID = Repository.InvokeConstructPicker("IncludedTypes=Change")
if CR_ID > 0 then
set CRToUse = Repository.GetElementByID(CR_ID)
end if
else
'user selected same change as last time. So he might want to reuse his comments as well
lastComments = getLastUsedComment(userLogin)
end if
'if the CRtoUse is now selected then we link it to the selected element
if not CRToUse is nothing then
dim linkCounter
linkCounter = 0
'first check if this CR is not already linked
if isCRLinked(selectedItem,CRToUse) and not groupProcessing then
MsgBox "The CR was already linked to this item", vbOKOnly + vbExclamation ,"Already Linked"
else
'get the comments to use
dim comments
comments = InputBox("Please enter comments for this change", "Change Comments",lastComments)
if len(comments) > 2 then
if groupProcessing then
for each selectedItem in selectedItems
'check the object type
selectedItemType = selectedItem.ObjectType
select case selectedItemType
case otElement, otPackage, otAttribute, otMethod, otConnector :
if not isCRLinked(selectedItem,CRToUse) then
linkToCR selectedItem, selectedItemType, CRToUse, userLogin, comments
linkCounter = linkCounter + 1
end if
end select
next
if linkCounter > 0 then
MsgBox "Successfully linked " & selectedItems.Count & " elements to change """ & CRToUse.Name& """" , vbOKOnly + vbInformation ,"Elements linked"
else
MsgBox "No links created to change " & CRToUse.Name & "." & vbNewLine & "They are probably already linked" , vbOKOnly + vbExclamation ,"Already Linked"
end if
else
linkToCR selectedItem, selectedItemType, CRToUse, userLogin, comments
end if
else
MsgBox "The CR has not been linked because no comment was provided", vbOKOnly + vbExclamation ,"No CR link"
end if
end if
end if
end if
case else
MsgBox "Cannot link this type of element to a CR" & vbNewline & "Supported element types are: Element, Package, Attribute, Operation and Relation"
end select
end function
function isCRLinked(item, CR)
dim taggedValue as EA.TaggedValue
isCRLinked = false
for each taggedValue in item.TaggedValues
if taggedValue.Value = CR.ElementGUID then
isCRLinked = true
exit for
end if
next
end function
function linkToCR(selectedItem, selectedItemType, CRToUse, userLogin, comments)
Session.Output "CRToUse: " & CRToUse.Name & " userLogin: " & userLogin & " comments: " & comments
dim crTag
set crTag = nothing
set crTag = selectedItem.TaggedValues.AddNew("CR","")
if not crTag is nothing then
crTag.Value = CRToUse.ElementGUID
crTag.Notes = "user=" & userLogin & ";" & _
"date=" & Year(Date) & "-" & Right("0" & Month(Date),2) & "-" & Right("0" & Day(Date),2) & ";" & _
"comments=" & comments
crTag.Update
end if
end function
function getLastUsedCR(userLogin)
dim wildcard
dim sqlDateString
if Repository.RepositoryType = "JET" then
wildcard = "*"
sqlDateString = " mid(tv.Notes, instr(tv.[Notes],'date=') + len('date='),10) "
Else
wildcard = "%"
sqlDateString = " substring(tv.Notes, charindex('date=',tv.[Notes]) + len('date='),10) "
end if
dim sqlGetString
sqlGetString = "select top 1 o.Object_id " & _
" from (t_objectproperties tv " & _
" inner join t_object o on o.ea_guid = tv.VALUE) " & _
" where tv.[Notes] like 'user=" & userLogin & ";" & wildcard & "' " & _
" order by " & sqlDateString & " desc, tv.PropertyID desc "
dim CRs
dim CR as EA.Element
set CR = nothing
'get the last CR
set CRs = getElementsFromQuery(sqlGetString)
if CRs.Count > 0 then
set CR = CRs(0)
end if
set getLastUsedCR = CR
end function
function getLastUsedComment(userLogin)
dim wildcard
dim sqlDateString
dim sqlCommentsString
if Repository.RepositoryType = "JET" then
wildcard = "*"
sqlDateString = " mid(tv.Notes, instr(tv.[Notes],'date=') + len('date='),10) "
sqlCommentsString = " mid(tv.Notes, instr(tv.[Notes],'comments=') + len('comments=')) "
Else
wildcard = "%"
sqlDateString = " substring(tv.Notes, charindex('date=',tv.[Notes]) + len('date='),10) "
sqlCommentsString = " substring(tv.Notes, charindex('comments=',tv.[Notes]) + len('comments='), datalength(tv.Notes)) "
end if
dim sqlGetString
sqlGetString = "select top 1 " & sqlCommentsString & " as comments " & _
" from (t_objectproperties tv " & _
" inner join t_object o on o.ea_guid = tv.VALUE) " & _
" where tv.[Notes] like 'user=" & userLogin & ";" & wildcard & "' " & _
" order by " & sqlDateString & " desc, tv.PropertyID desc "
dim queryResult
queryResult = Repository.SQLQuery(sqlGetString)
Session.Output queryResult
dim results
results = convertQueryResultToArray(queryResult)
if Ubound(results) > 0 then
getLastUsedComment = results(0,0)
else
getLastUsedComment = vbNullString
end if
end function

Process Records EOF

Wondering if someone might be able to help me solve this issue. Have an Access database where I want to send an email for each "Submit" box that is checked is checked. Have tried several thing and either get 1 record processed before the code stops or will give me several emails for the same record without moving on. Any help with where I am missing the boat would be much appreciated. Below is what I have for the code:
Dim r As DAO.Recordset
Set r = CurrentDb.OpenRecordset("SELECT * FROM [CIs_All_Statuses] WHERE [Submit] = True")
If r.RecordCount = 0 Then
MsgBox ("No records selected")
GoTo Done
Else
End If
r.MoveFirst
i = 1
Begin:
Do Until r.EOF = True
product = r![Product Name]
serial = r![Serial Number]
agency = r![Company]
User = r![Used By]
Submit = r![Submit]
Processed = r![Processed]
If Processed = True Then
r.Edit
r("Submit").Value = False
r.Update
r.MoveNext
GoTo Begin
Else
End If
r.Edit
r("Processed").Value = True
r.Update
r.Edit
r("Submit").Value = False
r.Update
r.MoveNext
Dim oOutlook As Outlook.Application
Dim oEmailItem As MailItem
' prevent 429 error, if outlook not open
On Error Resume Next
Err.Clear
Set oOutlook = GetObject(, "Outlook.application")
If Err.Number <> 0 Then
Set oOutlook = New Outlook.Application
End If
Set oEmailItem = oOutlook.CreateItem(olMailItem)
With oEmailItem
.To = "#email.com"
.CC = Me.Used_By
.Subject = "EmailTicket: [Subject]"
.Body = "Equipment to be verified:" & Space(2) & product & vbCrLf & "Serial Number:" & Space(2) & serial & vbCrLf & "Agency:" & Space(2) & agency & vbCrLf & "User Name:" & Space(2) & User & vbCrLf & vbCrLf & "By inserting the user name in the CC line the Customer Information on the Incident Customer tab will be auto-completed. ONLY append information to the end of the SUBJECT LINE"
.Display
End With
r.MoveNext
Check:
Do While r.EOF = False
NextComputer = r![Serial Number]
If (serial = NextComputer) Then
r.Edit
r("Submit").Value = False
r.Update
r.Edit
r("Processed").Value = True
r.Update
r.MoveNext
GoTo Check
Else
r.MovePrevious
End If
Loop
r.MovePrevious
Loop
r.Close
Set r = Nothing
Done:
End Sub
It is - among other things - the GoTo Check.
Remove that and rebuild your loop.
Also, you only need one .Edit and .Update for each record.

Error -2147352571 Type Mismatch: cannot coerce parameter value

I am struggling with the above error when trying to write the Visual Basic code for a 2010 Access Form. I am trying to get ensure that the associate and the Team Lead get the same email. When I first wrote the code, it worked initially. I have since added an "issue date" to the form, but not to the email. I attempted to add the issue date to the Script, but that did not work. I have since removed both the issue date from the form and the script. Any help would appreciated:
Private Sub cmdEmail_Click()
Dim objOutlook As Object
Dim objMailItem As Object
Const olMailItem As Integer = 0
Dim objMailItem1 As Object
Const olMailItem1 As Integer = 0
Set objOutlook = CreateObject("Outlook.Application")
Set objMailItem = objOutlook.CreateItem(olMailItem)
Set objMailItem1 = objOutlook.CreateItem(olMailItem1)
Dim strPathAttach As String
On Error GoTo err_Error_handler
'set receipient, you can use a DLookup() to retrieve your associate Email address
objMailItem.To = DLookup("Email_ID", "dbo_Noble_Associates", "[Fullname]='" & Me.cboAssociate & "'")
objMailItem1.To = DLookup("Email_ID", "dbo_TeamLeads$", "[Fullname]='" & Me.txtTeamLead & "'")
'set subject with text and Form values
objMailItem.Subject = "Attendance Violation " & Me.cboAssociate
objMailItem1.Subject = "Attendance Violation " & Me.cboAssociate
'set body content with text and Form values etc.
objMailItem.htmlBody = "Date of Occurrence: " & Format(Me.Occurrence_Date, "mm/dd/yyyy") & "<br>" & "Attendance Points: " & Me.CboType & "<br>" & "Total Points: " & Me.txtTotalpoints & "<br>" & "Notes: " & Me.txtNotes
objMailItem1.htmlBody = "Date of Occurrence: " & Format(Me.Occurrence_Date, "mm/dd/yyyy") & "<br>" & "Attendance Points: " & Me.CboType & "<br>" & "Total Points: " & Me.txtTotalpoints & "<br>" & "Notes: " & Me.txtNotes
' display email
' objMailItem.Display
' sending mail automaticly
objMailItem.Send
objMailItem1.Send
Set objOutlook = Nothing
Set objMailItem = Nothing
Set objMailItem1 = Nothing
exit_Error_handler:
On Error Resume Next
Set objOutlook = Nothing
Set objMailItem = Nothing
Set objMailItem1 = Nothing
Exit Sub
err_Error_handler:
Select Case Err.Number
'trap error 287
Case 287
MsgBox "Canceled by user.", vbInformation
Case Else
MsgBox "Error " & Err.Number & " " & Err.Description
End Select
Resume exit_Error_handler
End Sub
Private Sub CheckEmail_Click()
End Sub
Private Sub cmdSaveandNew_Click()
If Me.txtOccurrence_Date & "" = "" Then
MsgBox "Please enter the date."
Me.txtOccurrence_Date.SetFocus
Exit Sub
ElseIf Me.cboAssociate & "" = "" Then
MsgBox "Please select the associate's name."
Me.cboAssociate.SetFocus
Exit Sub
ElseIf Me.txtPoints & "" = "" Then
MsgBox "Please enter the number of Points."
Me.txtPoints.SetFocus
Exit Sub
End If
If Me.CheckEmail = True Then
cmdEmail_Click
End If
DoCmd.Close acForm, Me.Name
End Sub
Private Sub cmd_Cancel_Click()
Me.Undo
DoCmd.Close acForm, Me.Name
End Sub
Private Sub cboassociate_AfterUpdate()
Me.txtTeamLead.Value = Me.cboAssociate.Column(1)
End Sub
Private Sub cboFullname_AfterUpdate()
Me.txtCurrentpoints.Value = Me.cbofullname.Column(1)
End Sub
Private Sub CboType_AfterUpdate()
Me.txtPoints.Value = Me.CboType.Column(1)
End Sub
I am open to any suggestions.

how to check service state using vbscript?

Is there anyway to check the status of service using vbscript ? I would like to have a function for each possible service state :
LINK
Any help would be great. I did write a function for checking if service is stopped :
Public Function IsServiceStop(ByVal serviceName)
On Error Resume Next
Dim objServices, service
Set oWmiService = GetObject("winmgmts:\\.\root\cimv2")
Set objServices = oWmiService.ExecQuery("Select * from Win32_Service where Name='" & serviceName & "'")
For Each service In objServices
IsServiceStop = (service.Started = False)
Exit Function
Next
IsServiceStop = True
On Error Goto 0
End Function
When in doubt, read the documentation. All you need to do is check the State property of the service object:
serviceName = "..."
Set wmi = GetObject("winmgmts://./root/cimv2")
state = wmi.Get("Win32_Service.Name='" & serviceName & "'").State
WScript.Echo state
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colListOfServices = objWMIService.ExecQuery ("Select * from Win32_Service Where Name ='" & strServiceName & "'")
For Each objService in colListOfServices
status = objService.State
Next
Reporter.ReportEvent micPass, "startService", "Service status " & status
' Michael Maher
' 3/10/07
' Checks if services exists and is running
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colRunningServices = objWMIService.ExecQuery("Select * from Win32_Service Where Name='Messenger'")
nItems = colRunningServices.Count
' If the collection count is greater than zero the service will exist.
If nItems > 0 Then
For Each objItem in colRunningServices
If objItem.State = "Stopped" Then
Wscript.Echo objItem.DisplayName & " Installed/Stopped"
ElseIf objItem.State = "Started" Then
Wscript.Echo objItem.DisplayName & " Installed/Running"
End If
Next
Else
Wscript.Echo "Service Not Installed"
End If
Here is the source

How to read email and retrieve attachement using CDO (Collaborative Data Object) in VB6?

Has anyone been able to download email that contains attachment with CDO in vb6?
Can you help me with an example?
I'm still not sure where you want to retrieve email from but here is some code for retrieving email from an Exchange server. I did this as an experiment to learn some methods I would need on another project so it is not production quality but should get you started. This code is dependent on an Exchange client already being setup on the computer this is running on.
This function creates a session and logs in:
Function Util_CreateSessionAndLogon(Optional LogOnName As Variant) As Boolean
On Error GoTo err_CreateSessionAndLogon
Set objSession = CreateObject("MAPI.Session")
objSession.Logon , , False, False
Util_CreateSessionAndLogon = True
Exit Function
err_CreateSessionAndLogon:
Util_CreateSessionAndLogon = False
Exit Function
End Function
This function get information on items in the inbox and demonstrates some of the available properties.
Public Function GetMessageInfo(ByRef msgArray() As String) As Long
Dim objInboxFolder As Folder ' Folder object
Dim objInMessages As mapi.Messages ' Messages collection
Dim objMessage As Message ' Message object
Dim InfoRtnString
Dim i As Long
Dim lngMsgCount As Long
InfoRtnString = ""
If objSession Is Nothing Then
If Util_CreateSessionAndLogon = False Then
Err.Raise 429, "IBS_MAPI_CLASS", "Unable to create MAPI session object."
Exit Function
End If
End If
Set objInboxFolder = objSession.Inbox
Set objInMessages = objInboxFolder.Messages
lngMsgCount = objInMessages.Count
ReDim msgArray(0) 'initalize the array
For Each objMessage In objInMessages
If i / lngMsgCount * 100 > 100 Then
RaiseEvent PercentDone(100)
Else
RaiseEvent PercentDone(i / lngMsgCount * 100)
End If
InfoRtnString = ""
i = i + 1
ReDim Preserve msgArray(i)
InfoRtnString = InfoRtnString & Chr$(0) & objMessage.ID
InfoRtnString = InfoRtnString & Chr$(0) & objMessage.Subject
InfoRtnString = InfoRtnString & Chr$(0) & objMessage.Sender
InfoRtnString = InfoRtnString & Chr$(0) & objMessage.TimeSent
InfoRtnString = InfoRtnString & Chr$(0) & objMessage.TimeReceived
InfoRtnString = InfoRtnString & Chr$(0) & "" 'objMessage.Text
InfoRtnString = InfoRtnString & Chr$(0) & objMessage.Unread
InfoRtnString = InfoRtnString & Chr$(0) & objMessage.Attachments.Count
msgArray(i) = InfoRtnString
DoEvents
Next
GetMessageInfo = i
End Function
This function demonstrates getting attachments from a message.
Function GetAttachments(msgID As String, lstBox As ListBox) As Boolean
Dim objMessage As Message ' Messages object
Dim AttchName As String
Dim i As Integer
Dim x As Long
If objSession Is Nothing Then
x = Util_CreateSessionAndLogon()
End If
Set objMessage = objSession.GetMessage(msgID)
For i = 1 To objMessage.Attachments.Count
Select Case objMessage.Attachments.Item(i).Type
Case Is = 1 'contents of a file
AttchName = objMessage.Attachments.Item(i).Name
If Trim$(AttchName) = "" Then
lstBox.AddItem "Could not read"
Else
lstBox.AddItem AttchName
End If
lstBox.ItemData(lstBox.NewIndex) = i
Case Is = 2 'link to a file
lstBox.AddItem objMessage.Attachments.Item(i).Name
lstBox.ItemData(lstBox.NewIndex) = i
Case Is = 1 'OLE object
Case Is = 4 'embedded object
lstBox.AddItem "Embedded Object"
lstBox.ItemData(lstBox.NewIndex) = i
End Select
Next i
GetAttachments = True
End Function