Novell Home

Nwaddin

From Developer Community

Contents

Details

How to extend the functionality of Microsoft Excel to aid in the management and monitoring of Novell Netware servers and volumes.

Version 1.0

By Thomas Roll (troll<at>propodean.co.uk)


Introduction

The intention of this code is to provide a simple set of functions that, when included in an Excel spreadsheet, can be used to extract basic MIS information of Novell Netware environments based on basic Server and Volume parameters and values. This represents a simple and convenient way in which to extract basic information about disk space availability, server connection usage etc.

In most setups - it will not be required to authenticate/login to the NDS tree in order to get basic information such as disk space statistics or server uptime.

The individual functions have been put together based on information published on the Novell Developer Network about the use of the Novell Client API calls, and sample code published. A special thanks to Karl Durrance - without his work on the Novell clsNovellAPI VB 6 class, I would never have been able to put this library together.

The code will in time be added to in order to provide further functionality to aid in the monitoring and management of Novell Netware environments.


Supported Platforms

Testing has been done against the following systems:

Microsoft Windows 2000, Windows XP SP1 and SP2

Novell Client 4.9 and later

Novell Netware 5.x, 6.x

Microsoft Excel 97 - 2007

Note - No IPX specific testing has been carried out. I see no reason why it would not work, but Netware 3 and 4 releases and IPX can behave in unexpected manners now and again.


Code

Option Explicit

' Name      NWAddIn
' Version   1.0

' Author    Thomas Roll

' The intention of this code is to provide a simple set of functions that, when included in an Excel spreadsheet, can
' be used to extract basic MIS information of Novell Netware environments.

' The individual functions have been put together based on information published on the Novell Developer Network,
' showing the use of Novell Client API calls
'
' A special thanks to Karl Durrance - without his work on the Novell clsNovellAPI VB 6 class, I would never have been able
' to put this library together.
'

Private Const ERR_SUCCESS = 0

Private Const NW_MAX_VOLUME_NAME_LEN = 17

Private Const NWCC_NAME_FORMAT_BIND = &H2
Private Const NWCC_OPEN_LICENSED = &H1
Private Const NWCC_TRAN_TYPE_WILD = &H8000

Private Type VERSION_INFO
    serverName(47) As Byte
    fileServiceVersion As Byte
    fileServiceSubVersion As Byte
    maximumServiceConnections As Integer
    connectionsInUse As Integer
    maxNumberVolumes As Integer
    revision As Byte
    SFTLevel As Byte
    TTSLevel As Byte
    maxConnectionsEverUsed As Integer
    accountVersion As Byte
    VAPVersion As Byte
    queueVersion As Byte
    printVersion As Byte
    virtualConsoleVersion As Byte
    restrictionLevel As Byte
    internetBridge As Byte
    reserved(59) As Byte
End Type

Private Type SERVER_AND_VCONSOLE_INFO
    currentServerTime As Long
    vconsoleVersion As Byte
    vconsoleRevision As Byte
End Type

Private Type CPU_INFO
    pageTableOwnerFlag As Long
    CPUTypeFlag As Long
    coProcessorFlag As Long
    busTypeFlag As Long
    IOEngineFlag As Long
    FSEngineFlag As Long
    nonDedicatedFlag As Long
End Type

Private Type NWFSE_CPU_INFO
    serverTimeAndVConsoleInfo As SERVER_AND_VCONSOLE_INFO
    reserved As Integer
    numOfCPUs As Long
    CPUInfo As CPU_INFO
End Type

Private Type DIR_SPACE_INFO
    totalBlocks As Long
    availableBlocks As Long
    purgeableBlocks As Long
    notYetPurgeableBlocks As Long
    totalDirEntries As Long
    availableDirEntries As Long
    reserved As Long
    sectorsPerBlock As Byte
    volLen As Byte
    volName(NW_MAX_VOLUME_NAME_LEN - 1) As Byte
End Type

Type NWFSE_OS_VERSION_INFO
    serverTimeAndVConsoleInfo As SERVER_AND_VCONSOLE_INFO
    reserved As Integer
    OSMajorVersion As Byte
    OSMinorVersion As Byte
    OSRevisionNum As Byte
    accountingVersion As Byte
    VAPVersion As Byte
    queueingVersion As Byte
    securityRestrictionsLevel As Byte
    bridgingSupport As Byte
    maxNumOfVolumes As Long
    numOfConnSlots As Long
    maxLoggedInConns As Long
    maxNumOfNameSpaces As Long
    MaxNumOfLANs As Long
    maxNumOfMediaTypes As Long
    maxNumOfProtocols As Long
    maxMaxSubdirTreeDepth As Long
    maxNumOfDataStreams As Long
    maxNumOfSpoolPrinters As Long
    serialNum As Long
    applicationNum As Integer
End Type

Type FSE_SERVER_INFO
    replyCanceledCount As Long
    writeHeldOffCount As Long
    writeHeldOffWithDupRequest As Long
    invalidRequestTypeCount As Long
    beingAbortedCount As Long
    alreadyDoingReallocCount As Long
    deAllocInvalidSlotCount As Long
    deAllocBeingProcessedCount As Long
    deAllocForgedPacketCount As Long
    deAllocStillTransmittingCount As Long
    startStationErrorCount As Long
    invalidSlotCount As Long
    beingProcessedCount As Long
    forgedPacketCount As Long
    stillTransmittingCount As Long
    reExecuteRequestCount As Long
    invalidSequenceNumCount As Long
    duplicateIsBeingSentAlreadyCnt As Long
    sentPositiveAcknowledgeCount As Long
    sentDuplicateReplyCount As Long
    noMemForStationCtrlCount As Long
    noAvailableConnsCount As Long
    reallocSlotCount As Long
    reallocSlotCameTooSoonCount As Long
End Type

Type FILE_SERVER_COUNTERS
    tooManyHops As Integer
    unknownNetwork As Integer
    noSpaceForService As Integer
    noReceiveBuffers As Integer
    notMyNetwork As Integer
    netBIOSProgatedCount As Long
    totalPacketsServiced As Long
    totalPacketsRouted As Long
End Type

Type NWFSE_FILE_SERVER_INFO
    serverTimeAndVConsoleInfo As SERVER_AND_VCONSOLE_INFO
    reserved As Integer
    NCPStationsInUseCount As Long
    NCPPeakStationsInUseCount As Long
    numOfNCPRequests As Long
    serverUtilization As Long
    ServerInfo As FSE_SERVER_INFO
    fileServerCounters As FILE_SERVER_COUNTERS
End Type

Private Declare Function NWCCCloseConn Lib "clxwin32" (ByVal connHandle As Long) As Long
Private Declare Function NWCCOpenConnByName Lib "clxwin32" (ByVal startConnHandle As Long, ByVal name As Long, ByVal nameFormat As Long, ByVal openState As Long, ByVal tranType As Long, pConnHandle As Long) As Long

Private Declare Function NWGetCPUInfo Lib "calwin32" (ByVal conn As Long, ByVal CPUNum As Long, ByVal CPUName As String, ByVal numCoprocessor As String, ByVal bus As String, fseCPUInfo As NWFSE_CPU_INFO) As Long
Private Declare Function NWGetDirSpaceInfo Lib "calwin32" (ByVal conn As Long, ByVal dirHandle As Byte, ByVal volNum As Integer, spaceInfo As DIR_SPACE_INFO) As Long
Private Declare Function NWGetFileServerInfo Lib "calwin32" (ByVal conn As Long, fseFileServerInfo As NWFSE_FILE_SERVER_INFO) As Long
Private Declare Function NWGetFileServerVersionInfo Lib "calwin32" (ByVal conn As Long, versBuffer As VERSION_INFO) As Long
Private Declare Function NWGetVolumeNumber Lib "calwin32" (ByVal conn As Long, ByVal volName As String, volNum As Integer) As Long

Private Declare Function NWGetOSVersionInfo Lib "calwin32" (ByVal conn As Long, fseOSVersionInfo As NWFSE_OS_VERSION_INFO) As Long


' ====================================================
' Function: NWSrvConnsInUse
'
' Input     Server Name
' Returns   Number of connections on the server
' On error  Returns NULL
' ====================================================

Public Function NWSrvConnsInUse(ByVal Server As String) As Long
    
    Dim lhConn As Long
    Dim lRet As Long
    Dim VI As VERSION_INFO
    
    lhConn = OpenConnByName(Server)
    If lhConn <> 0 Then
        lRet = NWGetFileServerVersionInfo(lhConn, VI)
        If lRet = ERR_SUCCESS Then
            NWSrvConnsInUse = VI.connectionsInUse
        Else
            NWSrvConnsInUse = Null
        End If
        Call NWCCCloseConn(lhConn)
    Else
        NWSrvConnsInUse = Null
    End If

End Function

' ====================================================
' Function: NWSrvNCPStations
'
' Input     Server Name
' Returns   Current number of NCP connections on the server
' On error  Returns NULL
' ====================================================

Public Function NWSrvNCPStations(ByVal Server As String) As Long
    
    Dim lhConn As Long
    Dim lRet As Long
    Dim NFSI As NWFSE_FILE_SERVER_INFO
    
    lhConn = OpenConnByName(Server)
    If lhConn <> 0 Then
        lRet = NWGetFileServerInfo(lhConn, NFSI)
        If lRet = ERR_SUCCESS Then
            NWSrvNCPStations = NFSI.NCPStationsInUseCount
        Else
            NWSrvNCPStations = Null
        End If
        Call NWCCCloseConn(lhConn)
    Else
        NWSrvNCPStations = Null
    End If

End Function

' ====================================================
' Function: NWSrvNCPStationsPeak
'
' Input     Server Name
' Returns   Highest number of NCP station connections
'           reached on the server
' On error  Returns NULL
' ====================================================

Public Function NWSrvNCPStationsPeak(ByVal Server As String) As Long
    
    Dim lhConn As Long
    Dim lRet As Long
    Dim NFSI As NWFSE_FILE_SERVER_INFO
    
    lhConn = OpenConnByName(Server)
    If lhConn <> 0 Then
        lRet = NWGetFileServerInfo(lhConn, NFSI)
        If lRet = ERR_SUCCESS Then
            NWSrvNCPStationsPeak = NFSI.NCPPeakStationsInUseCount
        Else
            NWSrvNCPStationsPeak = Null
        End If
        Call NWCCCloseConn(lhConn)
    Else
        NWSrvNCPStationsPeak = Null
    End If

End Function

' ====================================================
' Function: NWSrvUptime
'
' Input     Server Name
' Returns   Date/Time stamp for last server boot
' On error  Returns NULL
' ====================================================

Public Function NWSrvUptime(ByVal Server As String) As Date
    
    Dim lhConn As Long
    Dim lRet As Long
    
    Dim CPUNum As Long
    Dim CPUName As String
    Dim COPRName As String
    Dim BUSName As String
    Dim CPUInfo As NWFSE_CPU_INFO
    
    lhConn = OpenConnByName(Server)
    If lhConn <> 0 Then
        lRet = NWGetCPUInfo(lhConn, CPUNum, CPUName, COPRName, BUSName, CPUInfo)
        If lRet = ERR_SUCCESS Then
            NWSrvUptime = DateAdd("s", -(CPUInfo.serverTimeAndVConsoleInfo.currentServerTime / 18.2065), Now())
        Else
            NWSrvUptime = Null
        End If
        Call NWCCCloseConn(lhConn)
    Else
        NWSrvUptime = Null
    End If
    
End Function

' ====================================================
' Function: NWSrvOSVersion
'
' Input     Server Name
' Returns   Version string for the Netware OS
' On error  Returns NULL
' ====================================================

Public Function NWSrvOSVersion(ByVal Server As String) As String
    
    Dim lhConn As Long
    Dim lRet As Long
    Dim VI As NWFSE_OS_VERSION_INFO
    
    lhConn = OpenConnByName(Server)
    If lhConn <> 0 Then
        lRet = NWGetOSVersionInfo(lhConn, VI)
        If lRet = ERR_SUCCESS Then
            NWSrvOSVersion = VI.OSMajorVersion & "." & VI.OSMinorVersion & "." & VI.OSRevisionNum
        Else
            NWSrvOSVersion = Null
        End If
        Call NWCCCloseConn(lhConn)
    Else
        NWSrvOSVersion = Null
    End If

End Function

' ====================================================
' Function: NWVolSize
'
' Input     Server Name
'           Volume Name
' Returns   Size of volume in MB
' On error  Returns NULL
' ====================================================

Public Function NWVolSize(ByVal Server As String, ByVal Volume As String) As Long
        
    Dim lhConn As Long
    Dim lRet As Long
    Dim DSI As DIR_SPACE_INFO
    Dim iVol As Integer
   
    lhConn = OpenConnByName(Server)
    If lhConn <> 0 Then
        lRet = NWGetVolumeNumber(lhConn, UCase$(Volume) & vbNullChar, iVol)
        If lRet = ERR_SUCCESS Then
            lRet = NWGetDirSpaceInfo(lhConn, 0, iVol, DSI)
                If lRet = ERR_SUCCESS Then
                    NWVolSize = (DSI.totalBlocks * DSI.sectorsPerBlock / 2) / 1024
                Else
                    NWVolSize = Null
                End If
        Else
            NWVolSize = Null
        End If
        Call NWCCCloseConn(lhConn)
    Else
        NWVolSize = Null
    End If
    
End Function

' ====================================================
' Function: NWVolSpaceAvail
'
' Input     Server Name
'           Volume Name
' Returns   Amount of available space of volume in MB
' On error  Returns NULL
' ====================================================

Public Function NWVolSpaceAvail(ByVal Server As String, ByVal Volume As String) As Long
    
    Dim lhConn As Long
    Dim lRet As Long
    Dim DSI As DIR_SPACE_INFO
    Dim iVol As Integer
    
    lhConn = OpenConnByName(Server)
    If lhConn <> 0 Then
        lRet = NWGetVolumeNumber(lhConn, UCase$(Volume) & vbNullChar, iVol)
        If lRet = ERR_SUCCESS Then
            lRet = NWGetDirSpaceInfo(lhConn, 0, iVol, DSI)
            If lRet = ERR_SUCCESS Then
                NWVolSpaceAvail = (DSI.availableBlocks * DSI.sectorsPerBlock / 2) / 1024
            Else
                NWVolSpaceAvail = Null
            End If
        Else
            NWVolSpaceAvail = Null
        End If
        Call NWCCCloseConn(lhConn)
    Else
        NWVolSpaceAvail = Null
    End If
    
End Function

' ====================================================
' Function: NWVolSpacePurgeable
'
' Input     Server Name
'           Volume Name
' Returns   Amount of purgeable space on volume in MB
' On error  Returns NULL
' ====================================================

Public Function NWVolSpacePurgeable(ByVal Server As String, ByVal Volume As String) As Long
    
    Dim lhConn As Long
    Dim lRet As Long
    Dim DSI As DIR_SPACE_INFO
    Dim iVol As Integer
    
    lhConn = OpenConnByName(Server)
    If lhConn <> 0 Then
        lRet = NWGetVolumeNumber(lhConn, UCase$(Volume) & vbNullChar, iVol)
        If lRet = ERR_SUCCESS Then
            lRet = NWGetDirSpaceInfo(lhConn, 0, iVol, DSI)
            If lRet = ERR_SUCCESS Then
                NWVolSpacePurgeable = (DSI.purgeableBlocks * DSI.sectorsPerBlock / 2) / 1024
            Else
                NWVolSpacePurgeable = Null
            End If
        Else
            NWVolSpacePurgeable = Null
        End If
        Call NWCCCloseConn(lhConn)
    Else
        NWVolSpacePurgeable = Null
    End If

End Function

' =================
' Support Functions
'
' OpenConnByName - Connection handle to named server
' TrimNull - Truncate null terminated string (API string return value)
'
' =================

Private Function OpenConnByName(Server As String) As Long

    Dim bytename() As Byte
    Dim lhConn  As Long
    Dim lRet As Long
    
    bytename = StrConv(UCase$(Server) & vbNullChar, vbFromUnicode)
    lRet = NWCCOpenConnByName(0, VarPtr(bytename(0)), NWCC_NAME_FORMAT_BIND, NWCC_OPEN_LICENSED, NWCC_TRAN_TYPE_WILD, lhConn)
    If lRet <> ERR_SUCCESS Then
        lhConn = 0
    End If
    OpenConnByName = lhConn

End Function

Private Function TrimNull(CString As String) As String

    CString = CString & vbNullChar
    TrimNull = Left(CString, InStr(1, CString, vbNullChar, vbBinaryCompare) - 1)

End Function


Installation

To use this code - open a new Excel spreadsheet, open the VBA editor and copy the code into a new module.

All functions defined as public will now be available in the Excel spreadheet as a User Defined function. If the spreadheet is saved as an Excel AddIn, it is possible to use these functions in any spreadsheet as long as the Excel AddIn is loaded.


In Use

The following example require the customized MS Excel Add-in loaded or alternatively the required code embedded in a code module within the spreadsheet itself.

To access the functions, use the function (fx) button on the Excel toolbar.


Server Function Example


The functions will be listed in the User Defined functions section - in this case the date/time stamp for when the server was last rebooted is extracted.


Image:NWSrvUptime.jpg


Supply the required parameters - in this case the Server Name.


Image:NWSrvUptime_Arguments.jpg


The spreadsheet with the result. In this case, the cell has been formatted as a custom Date/Time format.


Image:NWSrvUptime_Result.jpg


A convenient way to see if any server has been rebooted overnight.


Volume Function Example

The functions will be listed in the User Defined functions section - in this case the volume size.


Image:NWVolSize.jpg


Supply the required parameters - in this case the Server Name and Volume Name.


Image:NWVolSize_Arguments.jpg


The spreadsheet with the result.


Image:NWVolSize_Result.jpg


Combining this function with functions for available space and purgeable space, it is easy to get a quick overview of where you may be running a bit low.

Compiled Add-Ins for Microsoft Excel 97-2003 and Excel 2007 are available from coolsolutions on [1]

Happy reporting.

Novell® Making IT Work As One

© 2009 Novell, Inc. All Rights Reserved.