WinBatch® Technical Support Forum

Archived Boards => WinBatch Script Exchange => Topic started by: ....IFICantBYTE on May 17, 2014, 01:54:11 AM

Title: SNMP v1 Examples
Post by: ....IFICantBYTE on May 17, 2014, 01:54:11 AM
Here is a post related to a recent question about SNMP (Simple Network Management Protocol) and if WinBatch could do it.
This is a very simple way of doing some SNMP v1 stuff... I have been using this for a few years and it works well... hope it is useful to someone else.

Code (winbatch) Select
; SNMP v1 Example (SNMP = Simple Network Management Protocol) ....IFICantBYTE

; These examples use Microsoft's OLE ISNMP printer automation wrapper for ASP Internet printing http://msdn.microsoft.com/en-us/library/windows/hardware/ff554396(v=vs.85).aspx
; You can use this to perform SNMP requests to other network devices too, not just printers.
; This is VERY easy to use compared to other SNMP libraries out there, BUT it is also VERY basic .. SNMP V1 ONLY, no trap support or MIB support (find your own OIDS).
; Use Google to learn about SNMP, OIDS, MIBS etc.  There are many web sites out there that can explain it far better than I understand it or could possibly write about here.

; Here are the absolute basics of use:

;HostAddress = "192.168.1.1" ;Change it to your device you want to query (can use a DNS name instead)
;Community = "public" ;Change this to your read community name
;Retry = 2 ; recommended value
;Timeout = 1000 ; recommended value
;OID = ".1.3.6.1.2.1.1.1.0" ; sysDescr = System Description = .iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1).sysDescr(1)
;SNMPobj = ObjectCreate("OlePrn.OleSNMP.1") ; create the OLE/COM object
;Con = SNMPobj.Open(HostAddress,Community,Retry,Timeout) ; make the connection
;GetData = SNMPobj.Get(OID);The Get command (method) to get the value (referenced by the OID) from the device ... there are a few other useful methods such as GetAsByte, GetList, GetTree, Set and SetList (Be careful with set - you can reprogram a device!)
;SNMPobj.Close() ; close things
;message("Result of Get",GetData) ; show the returned value



;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

;!!!!!!!!!!  Below are 3 relatively simple example scripts that build upon the above to actually do something a bit useful...
;            they should run on any version of WinBatch from the last 10 years or so that supports OLE/COM objects.  Just run and modify to suit your needs.  ....IFICantBYTE

;!!!!!!!!!!  Also, read the notes at the bottom below the examples for a few ideas that might help you.

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


;Error capture UDS
#DefineSubRoutine OnNextError(wberrorarray)
   lasterr = wberrorarray[0]
   handlerline = wberrorarray[1]
   textstring = wberrorarray[5]
   linenumber = wberrorarray[8]
   errstr = StrCat("Number: ",lasterr,@LF,"String: ",textstring,@LF,"Line (",linenumber,"):'",handlerline,"'")
   ;Message("Error Information",errstr)
   If lasterr <> 1261
    Message("Error Information",errstr);show any error OTHER than General OLE Exception 1261 which will happen if SNMP OID or object does not exist
   Else
    IntControl(73,3,@TRUE,"OnNextError",0); Arm error handler with a @TRUE to clear the extended error info, otherwise it can build up and become too long to display on a fatal error screen
   EndIf
   Return(1) ; Return to next statement, therefore continue and Re-arm error handler
#EndSubRoutine

IntControl(73,3,@TRUE,"OnNextError",0); Arm error handler


;Conversion UDF ... Returned UpTime in 100ths of secs to YYYY:MM:DD:HH:MM:SS
;================================
#DefineFunction TimeStamp(HundredthsOfSecs)
If IsInt(HundredthsOfSecs)==@FALSE Then HundredthsOfSecs = 0
Secs = Abs(HundredthsOfSecs)/100
Ret = TimeDiff(TimeAdd("0000:01:01:00:00:00","0000:00:00:00:00:":Secs),"0000:01:01:00:00:00")
Return Ret
#EndFunction
;================================


;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


;Example 1 .. Simple Get of a single OID value

Message("Example 1","Press OK to start a simple example of a single Get")
HostAddress = AskLine("Host Address","Enter a valid device's network address or DNS name." ,"192.168.1.1")
Community = AskLine("Community name (read)","Enter the SNMP community name for reading the device." ,"public")
Retry = 2 ; recommended value
Timeout = 1000 ; recommended value
OID = ".1.3.6.1.2.1.1.1.0" ; sysDescr = System Description = .iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1).sysDescr(1)
SNMPobj = ObjectCreate("OlePrn.OleSNMP.1") ; create the OLE/COM object
Con = SNMPobj.Open(HostAddress,Community,Retry,Timeout) ; make the connection
GetData = SNMPobj.Get(OID);The Get command (method) to get the value (referenced by the OID) from the device ... there are a few other useful methods such as GetAsByte, GetList, GetTree, Set and SetList (Be careful with set - you can reprogram a device!)
SNMPobj.Close() ; close things
If GetData == 0
Message("Error:","Looks like nothing was returned... check that the details you entered were correct and that the device can be seen on the network.")
Else
Message("Result of Get",GetData) ; show the returned data
EndIf


;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


;Example 2 .. Grab a handfull of different values (OIDs stored in an array) with one GetList command that returns a new Array of the values

Message("Example 2","Press OK to start an example of a GetList on a few specific OIDs")
HostAddress = AskLine("Host Address","Enter a valid device's network address or DNS name." ,"192.168.1.1")
Community = AskLine("Community name (read)","Enter the SNMP community name for reading the device." ,"public")
Retry = 2 ; recommended value
Timeout = 1000 ; recommended value

;The following OIDs are very well known and should be supported on almost all SNMP devices, that is why I have chosen them for this example... you will have to look up your own device's unique OIDs yourself
OIDs = ArrDimension(7)
OIDs[0] = ".1.3.6.1.2.1.1.1.0" ; sysDescr = System Description = .iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1).sysDescr(1)
OIDs[1] = ".1.3.6.1.2.1.1.2.0" ; sysObjectID = Prefix: iso.org.dod.internet.private.enterprise (1.3.6.1.4.1).X
; Note: Lookup the number 'X' after the prefix for the iso Private enterprise code of the manufacturer or entity at http://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
;       numbers after that are for the manufacturer to assign to identify the specific device if they want to. This is one way SNMP applications sniff and work out what they have found.
OIDs[2] = ".1.3.6.1.2.1.1.3.0" ; sysUpTime in 100ths of seconds ... I have included a small UDF to convert this to YYYY:MM:DD:HH:MM:SS
OIDs[3] = ".1.3.6.1.2.1.1.4.0" ; sysContact
OIDs[4] = ".1.3.6.1.2.1.1.5.0" ; sysName
OIDs[5] = ".1.3.6.1.2.1.1.6.0" ; sysLocation
OIDs[6] = ".1.3.6.1.2.1.1.7.0" ; sysServices (Sum of OSI layers supported)

SNMPobj = ObjectCreate("OlePrn.OleSNMP.1") ; create the OLE/COM object
Con = SNMPobj.Open(HostAddress,Community,Retry,Timeout) ; make the connection
GetListData = SNMPobj.GetList(OIDs); Get the data for all the OIDs in the array passed in and return a new array with the values
SNMPobj.Close() ; close things


If ArrInfo(GetListData,-1) == @TRUE;If a valid array is returned
MessageText = StrCat("Description: ",GetListData[0],@CR,"ObjectID: ",GetListData[1],@CR,"UpTime: ",GetListData[2],"(100ths of secs)   Converted UpTime: ",TimeStamp(GetListData[2]),@CR,"Contact: ",GetListData[3],@CR,"Name: ",GetListData[4],@CR,"Location: ",GetListData[5],@CR,"Services: ",GetListData[6])
Message("Result of GetList",MessageText) ; show the returned values
Else
MessageText = StrCat("Sorry, a valid array was not returned!",@CR,"Make sure the address is valid and can be reached via SNMP on the community you entered",@CR,@CR,"Error data held in IntControl73 capture: ",@CR,lasterr,@CR,errstr)
Message("Error:",MessageText)
EndIf


;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


;Example 3 .. Do a GetTree (walk) from an OID through each sub-node to the end of its tree 

Message("Example 3","Press OK to start an example of a GetTree (walk) from an OID through each sub-node to the end of its tree.")
HostAddress = AskLine("Host Address","Enter a valid device's network address or DNS name." ,"192.168.1.1")
Community = AskLine("Community name (read)","Enter the SNMP community name for reading the device." ,"public")
Retry = 2 ; recommended value
Timeout = 1000 ; recommended value

RootOID = ".1.3.6.1.2.1" ;

SNMPobj = ObjectCreate("OlePrn.OleSNMP.1") ; create the OLE/COM object
Con = SNMPobj.Open(HostAddress,Community,Retry,Timeout) ; make the connection
GetTreeData = SNMPobj.GetTree(RootOID); Do a GetTree (walk) from an OID through each sub-node to the end of its tree and return a new 2 dimension array with the names and values found.
SNMPobj.Close() ; close things

If ArrInfo(GetTreeData,-1) == @TRUE;If a valid array is returned
OutputFile = StrCat(DirScript(),"SNMP_Example_GetTree_Output.csv")
ArrayFilePutCSV(OutputFile, GetTreeData, ",",@TRUE,0)
MessageText = StrCat("Two-dimension array of SNMP GetTree data written to file:",@CR,OutputFile,@CR,@CR,"Click OK to view it.")
Message("Results of GetTree (walk) done",MessageText)
Run("notepad.exe", OutPutFile)
Else
MessageText = StrCat("Sorry, a valid array was not returned!",@CR,"Make sure the address is valid and can be reached via SNMP on the community you entered",@CR,@CR,"Error data held in IntControl73 capture: ",@CR,lasterr,@CR,errstr)
Message("Error:",MessageText)
EndIf

Exit

;NOTES:

; If you have a recent version of WinBatch that supports ReportView in a dialog, it can be nice to use that to see the returned data. (not going to do that in these simple examples though)

; An exercise for the reader... if you like, use a Get on the sysObjectID ".1.3.6.1.2.1.1.2.0" and then use its returned value as the root OID to pass to a GetTree and see what comes up!

; Lookup your device's SNMP documentation and see if it describes some things that might be handy to know.
; Also, an SNMP viewing utility to do essentially what we are doing in these examples, but with more control, ability to decode your device's MIBs and support for v3 security
; and traps etc. is very handy if you start getting into it.
; I have made some nice WinBatch utilities for the company I work for using the above basic SNMP stuff here and then taking it further in fancy dynamic dialogs etc.
; There are also some open-source libraries out there that support SNMP v2C/v3 properly and might be able to be used by WinBatch scripts (I haven't tried yet)
; Hope this is of use to someone. Have fun. ....IFICantBYTE
Title: Re: SNMP v1 Examples
Post by: Deana on May 19, 2014, 08:03:29 AM
Awesome. Thanks for sharing. I have posted your code sample in the tech database:
http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+WinBatch/OLE~COM~ADO~CDO~ADSI~LDAP/Samples~from~Users+SNMP~v1~Examples.txt
Title: Re: SNMP v1 Examples
Post by: td on May 19, 2014, 08:09:44 AM
Yes, nice bit of work.
Title: Re: SNMP v1 Examples
Post by: ....IFICantBYTE on May 19, 2014, 05:50:44 PM
Thanks Deana and Tony.
Title: Re: SNMP v1 Examples
Post by: kdmoyers on May 20, 2014, 07:55:14 AM
Very cool!! thanks for posting!
-Kirby