Monday 19 December 2011

Sending SMS via AQL's SOAP gateway using vb.net

I'm working on a project currently and a requirement I have is for Systems Center Operations Manager to send certain alerts as an SMS message, SCOM has this functionality built in but requires a GSM modem connected to the RMS in order to do this. We currently use AQL to provide an SMS gateway service for another project so this looked like a good starting point as we were already paying for it. A quick email to AQL resulted in an apology from AQL saying they didn't have any SDK samples and would add it to their list, but they did send some sample code in C# which I was able to knock into some vb.net code (C# isn't my strong point - I could argue the same about vb.net!) Anyway the following should do the trick if you need it (You need to add a web service reference to the aql gateway http://gw.aql.com/soap/sendservice.php?WSDL - Web Service, Not a service Reference, Click Advanced under service reference and name it AQLSoapGateway. At the moment this will just build you a command line utility that can be used for sending SMS, I'll cover getting SCOM to utilise this later.
Imports System
Imports SendSMS.AQLSoapGateway
Imports System.Web.Services.Protocols


Module Module1

    Public Sub Main()

        ' AutoIncrement done with http://autobuildversion.codeplex.com

        'Display Info
        Console.WriteLine(vbCrLf & _
                "SendSMS.exe - SMS Sending Utility, using the AQL SMS Gateway. Version " & My.Application.Info.Version.ToString & vbCrLf & _
                "David Wallis, 2011" & vbCrLf)

        'Define Usage Message
        Dim strUsageMsg As String = vbCrLf & _
                "Usage: SendSMS.exe " & vbCrLf & vbCrLf & _
                "Available Options: " & vbCrLf & vbCrLf & _
                "/Username:AQLUserName" & vbCrLf & _
                "/Password:AQLPassword" & vbCrLf & _
                "/DestinationNumber:PhoneNumber" & vbCrLf & _
                "/Originator:Originator" & vbCrLf & _
                "/Message:Message" & vbCrLf

        Dim strDestinationNumber As String = "", strUserName As String = "", strPassword As String = "", strOriginator As String = "", strMessage As String = ""

        ' Match Command Line Arguments with variables
        For Each arg As String In My.Application.CommandLineArgs

            If arg.ToLower.StartsWith("/destinationnumber:") Then strDestinationNumber = arg.Remove(0, 19)
            If arg.ToLower.StartsWith("/username:") Then strUserName = arg.Remove(0, 10)
            If arg.ToLower.StartsWith("/password:") Then strPassword = arg.Remove(0, 10)
            If arg.ToLower.StartsWith("/originator:") Then strOriginator = arg.Remove(0, 12)
            If arg.ToLower.StartsWith("/message:") Then strMessage = arg.Remove(0, 9)

        Next

        ' Exit out if options arent passed, otherwise proceed and initalise API connection.

        If Len(strDestinationNumber) = 0 Or Len(strUserName) = 0 Or Len(strPassword) = 0 Or Len(strOriginator) = 0 Or Len(strMessage) = 0 Then
            Console.WriteLine(strUsageMsg & vbCrLf & vbCrLf & "Error:" & vbCrLf & "All parameters are mandatory.")
            Environment.ExitCode = 1
            Exit Sub
        End If


        Dim cpLatestBrief = New SendSmsService()

        ' Define destination number(s) from 
        ' Create an array to pass for the destination number(s) - this code supports one number for simplicity
        Dim destarr As String() = New String(0) {}


        If strDestinationNumber.Substring(0, 1) = 0 Then
            ' Number begins 0 - strip 0 and add country code (UK Specific) - Not sure if this is required, but the
            ' example code specified the number in the 447733333333 format, ie drop the leading 0 and shove in 44. 
            destarr(0) = "44" & strDestinationNumber.Substring(1, strDestinationNumber.Length - 1)
        End If

        ' create authentication object with AQL Username and Password
        cpLatestBrief.authValue = New auth()
        cpLatestBrief.authValue.username = strUserName
        cpLatestBrief.authValue.password = strPassword

        Dim creditsused As String
        Dim outdesr As String

        Dim dt As System.DateTime = DateTime.Now

        Dim cbe As SendSMS.AQLSoapGateway.callbackelement = New callbackelement()
        cbe.callbackurl = "http://url.com"
        cbe.callbacktype = SendSMS.AQLSoapGateway.callbacktypeoptions.HTTPGET

        If cpLatestBrief IsNot Nothing Then
            Try
                cpLatestBrief.SoapSendSms(destarr, strOriginator, strMessage, SendSMS.AQLSoapGateway.mtype.text, "2", dt, _
                 False, cbe, creditsused, outdesr)
                Console.WriteLine("Message Sent, " & creditsused & " credits used.")
            Catch e As SoapHeaderException
                Console.WriteLine("Name Entry Error" & vbCrLf & e.Message)
            Catch e As SoapException
                Dim node As System.Xml.XmlNode = e.Detail
                Dim errorcode As String = e.Detail.FirstChild.InnerText
                Dim errortext As String = e.Detail.FirstChild.NextSibling.InnerText

                If errorcode = "DESTERROR-INVALIDNUMBERS" Then
                    Console.WriteLine("Name Entry Error" & vbCrLf & e.Message)
                ElseIf errorcode = "MESSAGE-NOTSUPPLIED" Then
                    Console.WriteLine("Name Entry Error" & vbCrLf & e.Message)
                Else
                    Console.WriteLine("Error:" & vbCrLf & "Error Code " & errorcode & vbCrLf & e.Message & "  " & errortext)
                End If
            End Try
            Return
        Else

            Return
        End If
    End Sub
End Module

Monday 24 October 2011

netapp perfstat

I needed to run some perfstats today to capture some benchmarking, unfortunatley the netapp provided example didnt work for me which is listed as:

perfstat -f filer1 -t 30 -i 46 > perfstat-"Date_%date:~4,2%%date:~7,2%%date:~10,4%-Time_%time:~0,2%h%time:~3,2%m%time:~6,2%s"

Having had a quick look at this, there are a number of reasons, I am on windows 2008 r2 and its trying to RSH - dont bother in 2008.. you need to use plink as stated in the documentation. so i changed the cmd line to use plink as follows, substitute username and password...

perfstat -S pw:netapp -l root -f filer1 -t 30 -i 46 > perfstat-"Date_%date:~4,2%%date:~7,2%%date:~10,4%-Time_%time:~0,2%h%time:~3,2%m%time:~6,2%s"

This still didnt work as the SSH host key hadnt been saved on the system I was using, quick work around, fire up putty, Login whilst saving the key.

Running this: perfstat -S pw:netapp -l root -f filer1 -t 30 -i 46 now works.

The next problem I have is the date format my system is using or something I couldnt be bothered to investigate.. so if you do

echo Date_%date:~4,2%%date:~7,2%%date:~10,4%-Time_%time:~0,2%h%time:~3,2%m%time:~6,2%s

You get a garbled date string back with a slash in it this is because the example expects echo %date% to return the day of the week ie, Mon 24/10/2011

Where as mine displays a short date ie 24/10/2011, This is a simple fix, but for reference in DOS part of a string can be retuned (MID) by the following VariableName Start,Legth Which in this case %date:~4,2% should return 24 as %date% SHOULD = Mon 24/10/2011 but it doesn't.

Anyway here's the modified version for todays use - however I shoved it into a batch file to run both filers

@echo off
c:\
cd\perfstat
start perfstat -S pw:netapp -l root -f filer1 -t 30 -i 46 > c:\perfstat\Filer1_perfstat-Date_%date:~0,2%_%date:~3,2%_%date:~6,4%-Time_%time:~0,2%h%time:~3,2%m%time:~6,2%s
start perfstat -S pw:netapp -l root -f filer2 -t 30 -i 46 > c:\perfstat\Filer2_perfstat-Date_%date:~0,2%_%date:~3,2%_%date:~6,4%-Time_%time:~0,2%h%time:~3,2%m%time:~6,2%s

Thursday 20 October 2011

slow sql connections

I had a wierd problem today whilst we were doing some testing, we have a web application which was producing random results and no consistent performance, we though initally it was SQL being slow, but looking at profiler it was returning the queries in around 11ms once it actually got the request.

After bodging our way around some firewalls to rule them out I eventually knocked up a rough and ready vbs script that echoed the current time then attempted to do an ADODB connection to the database and then echo the time out again..

set myconn = createObject("ADODB.Connection")

wscript.echo now()
myconn.open ="DRIVER={SQL Server};SERVER=10.0.0.1\TEST;OPTION=35"
wscript.echo now()
Each time I executed this it took 9 seconds just to connect.


After much playing running the script locally on the sql box it resulted in returning immediatley, I installed wireshark on the DB box and had a look at what was happing, we were seing a few packets for LLMNR, I disabled this in group policy (Computer Configuration\Administrative Templates\Network\DNS Client\Turn off Multicast Name Resolution) this made no difference -apart from stopping this traffic, I then disabled LMHOSTS lookup and disabled NetBIOS over TCP/IP this didnt make a difference either.

I then added the hostname of the sql server into the clients hosts file and this resolved the issue immediatley.. from looking at an early MDAC bug relating to sql 2000 it seems that this was previously a bug - which has been fixed but it attempts to do a reverse lookup and then times out after 5 seconds - despite me specifying the ip\instance name as there is no DNS in use in this enviroment!

Anyway its fixed it for now, I may try and MDAC update later but for now Ill move on and find the next problem.

Friday 26 August 2011

CP2102 USB to TTL bridge with Ubuntu 8.10

Well I got the SMS working from a simple script, so it's onto working on the input and output board, I've ruled out my other option as
I dont have a serial port anymore on the HP microserver, so I thought I'd look at interfacing with the Mega32 using USB.. every option was getting
over complicated and then I stumbled across the CP2102 chip on sparkfun. I was going to order one when I noticed that they were out of stock
quick search on google shopping showed play selling some for £4.18 or so including free delivery! - So I ordered two and they arrived the next day.

Seems to good to be true, anyway I Inserted the USB to TTL convertor and typed dmesg to look at the kernel messages and was presented with:

[6390234.520185] usb 4-3: new full speed USB device using ohci_hcd and address 3
[6390234.731367] USB Serial support registered for cp210x
[6390234.731450] cp210x 4-3:1.0: cp210x converter detected
[6390234.880248] usb 4-3: reset full speed USB device using ohci_hcd and address 3
[6390235.066809] usb 4-3: cp210x converter now attached to ttyUSB2
[6390235.066848] usbcore: registered new interface driver cp210x
[6390235.066854] cp210x: v0.09:Silicon Labs CP210x RS232 serial adaptor driver


Well that was easier than expected, beter than windows that wanted a driver installing..

Now to see if I can talk to my board!...

(15 mins later)

All Working, shocked... now just to write a daemon that will monitor for input on the serial port and do something and also send stuff when requested, now that will take me some doing!

Ill add some pictures next week.

Friday 19 August 2011

Update on SMS

Well I was given a 3G dongle which was on the three network, which I managed to unlock using both master unlock Master Unlock and then used the huawei modem code writer tool to flash the device Code Writer I believe these can be written by AT+ commands but I didn't investigate that route. One thing I noticed is that it didn't work on my desktop, I don't know if that's because it's on XP x64 or because the drivers weren't installed - anyway I plugged it into my laptop that has the drivers on for the previous dongle and it was detected fine and unlocked easily :)

I stuck in my old mobile's sim to see if that would work but it seems to have expired and needs topping up or something - anyway that involved effort so I ordered a couple of sims from vodaphone - I get crap reception on vodaphone compared to O2 but I'm informed that they dont expire if you don't top them up, so Ideal for my plans - I managed to order two from here for free Vodaphone so we will see if that works.

Another thing I was looking to build in was alerting around the credit available, I could either do this by counting the number of text's sent but I did stumble across a blog posting here blog which suggests that on vodaphone you can issue the command AT+CUSD=1,"*&1345;",15

which should return +CUSD: 0,"#14.66.",0

Which is your dongle's way of saying £14.66 remaining.

I have yet to try this but I am hopefull that it may work :)

I've also got two new books at work: The bash cookbook and Mastering Unix Shell scripting which may help me out with this process.

I've just been looking more into USB I/O boards though and decide that the
Veleman K8055
Looks a little pricey for what it does and what I want, I've since realised that my WRT job wont quite accomplish what I want due to the lack of a serial port and the fact that I never finished writing the demon that I started but gave up on due to my lack of interest/skills in the C language! Perl just seemed wrong, but I may go back to it!

Quick Update (26/07/2011)

Is that issuing the command to check balance doesnt quite work as said..

sending:

AT+CUSD=1,"*&1345;",15

results in:

OK


Hmm, need to look into this a little more :)

Thursday 11 August 2011

SMS from Linux

It has to be said that I'm pretty tight when it comes to parting with cash, I was wanting my home alarm and cctv to be able to text me - I started looking at GSM based diallers but they are stupid money. So I though the easier way would be to interface with the PC.

I already have a network based IO board I erm fashioned out of a WRT54G which lets me communicate with inputs and outputs - so interfacing shouldnt be a problem, however I will probably knock up a USB based IO board given the lack of parrallel ports or anything else on my new HP Microserver and save me having to pass things over the network to the wrt54..

Anyway quick google turns out that a 3G dongle will let me send texts.. hmm :) - Quick look in my laptop bag finds me a Huawei K3765 (Or a white vodaphone 3g dongle to me and you) - It belongs to work but it will do for a quick POC!

Given my linux knowledge is bordering on being a beginner I relied on google and typing commands and hoping for the best as you do, Windows would have been easy but my HP Microserver is running Ubuntu Server 10.10 as it does the simple things I need easier than windows, as much as it pains me to say that!

I shoved the thing in and ran the following:

lsusb

This returned the following:

Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 002: ID 0566:3002 Monterey International Corp.
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 002: ID 0680:0002 Realtek Semiconductor Corp., CPP Div. (Avance Logic) Arowana Optical Wheel Mouse MSOP-01
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 005: ID 12d1:1465 Huawei Technologies Co., Ltd.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

So at least it could see the device..

running this command:

dmesg | grep -e "modem" -e "tty"

got me this:

[ 0.000000] console [tty0] enabled

Not much there other than the console, so I dont think that found any modems..

Reading between the lines on an another post / link suggested I needed usb_modeswitch, So I ran sudo apt-get install usb-modeswitch-data

Then looking for the device again didnt show much, so I removed it and reinserted it which didnt seem to do too much, or at least I dont think it did!.

I then found another link so blindly pasted the following commands:

rmmod usb-storage
rmmod usb-serial
mknod /dev/ttyUSB0 c 188 0
mknod /dev/ttyUSB1 c 188 1
mknod /dev/ttyUSB2 c 188 2

(there was a modprobe somewhere but dont ask me where! - something like the following: modprobe usbserial vendor=0x12d1)

dmesg | grep -e "modem" -e "tty"

Now got me this:

[ 0.000000] console [tty0] enabled
[5094746.677111] USB Serial support registered for GSM modem (1-port)
[5094746.677229] option 1-3:1.0: GSM modem (1-port) converter detected
[5094746.677409] usb 1-3: GSM modem (1-port) converter now attached to ttyUSB0
[5094746.677447] option 1-3:1.3: GSM modem (1-port) converter detected
[5094746.677529] usb 1-3: GSM modem (1-port) converter now attached to ttyUSB1
[5094746.677549] option 1-3:1.4: GSM modem (1-port) converter detected
[5094746.677636] usb 1-3: GSM modem (1-port) converter now attached to ttyUSB2
[5094746.677673] option: v0.7.2:USB Driver for GSM modems
[5094747.213946] option 1-3:1.2: GSM modem (1-port) converter detected
[5094747.214211] usb 1-3: GSM modem (1-port) converter now attached to ttyUSB3

Looking better :)

Now to launch minicom, hmm no.. not installed.. Installed that (I dont think I need to post how)

I ran minicom -s to configure the required terminal settings which were:

Serial Device : /dev/ttyUSB0
Bps/Par/Bits : 115200 8N1
Hardware No
Software Flow Control : Yes

Now when I relaunched minicom I got the following:

Welcome to minicom 2.5

OPTIONS: I18n
Compiled on Feb 5 2011, 06:31:42.
Port /dev/ttyUSB0

Press CTRL-A Z for help on special keys

AT S7=45 S0=0 L1 V1 X4 &c1 E1 Q0
OK

Result..

So to send a Text / SMS you need to switch mode..
AT+CMGF=1

then to send a Text / SMS to a number you do..

AT+CMGS=”+44077******” [Enter]
> This is a test Message[Enter]
Cntrl + Z

You should then get

OK

To recieve you can do (un-tested yet)

List SMS
AT+CMGL=”all”

Get individual msg
AT+CMGR=0

Delete message number (n)
AT+CMGD=n


I'll try and make more notes at configuring it when I get a dongle to use permanantley and also ensure that it still works after a reboot, after that it's work out how to make it into something usable for the UPS, Alarm, and CCTV :)

Sad I know, but its kept me out of the pub tonight.






Wednesday 3 August 2011

Quick and Dirty Log Viewing

I've been running some reallocates on some NetApp volumes, however you need to keep checking the syslogs. We send these to our syslog server which archives them daily so we can go back days, weeks and years should we need old logs, I needed a quick way of going through the logs and looking for what I wanted which was any messages related to this task, easy! - Yeah that easy I'll forget, hence this post.

Anyway simple 15 year old MS-DOS will do the first bit... list all the files in the current folder...

for /r in %i in (*) do @echo %i

There, simples a list of the logs.. now to find what I want..

well yeah you can use find but I prefer to use grep and have the gnu tools installed on my windows box here http://www.gnu.org/software/grep/grep.html


so the following should do the trick..

for /r %i in (*) do type %i|grep wafl.reallocate

well it would but it was a bit lacking, quick check of the logs suggests I want wafl.scan too.. Quick google for doing OR with grep (Dont suggest RegEx!) suggest that you use egrep wafl.scan|wafl.reallocate..

hmm check the help... ahh
`egrep' means `grep -E'.

for /r %i in (*) do type %i|grep -E "wafl.scan|wafl.reallocate"

Done - I think!

Sunday 24 July 2011

Fixing Disconnected VM's

When doing maintanance we have recently found that some VM's randomly dont reconnect to the network, and given the counts we have its a little hard to find them until the users complain that the servers are down, despite the fact they arent...

Anway I'm sure there is an underlying issue we need to fix but until them this is my solution, a powershell / powercli script.. it was tested with powercli 4.1.1-332441

# Ensure Networks are Connected on the currently powered On VM's
# DWallis 24/07/2011

# Adds the Powershell snapin's required if not already present.
Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue

# Ignore any SSL warnings
$WarningPreference = "SilentlyContinue"

#$viServerName = "viservernamehere"
connect-viserver $viServerName

# Connect to DataCenter

$ESXSRV = Get-DataCenter "DatacenterNameHere" | Get-VMHost

# Loop Through Each Powered On VM
Foreach ($VM in ($ESXSRV | Get-VM | where-object {$_.PowerState -eq "PoweredOn"}))
{
# Modify any un-connected VM's
$vm | Get-NetworkAdapter | Where { $_.connectionstate.connected -eq “$null” } | Set-NetworkAdapter -StartConnected:$true -Connected:$true -Confirm:$false
}

Disconnect-VIServer -Confirm:$False

Thursday 19 May 2011

Netapp Disk Sanitization

I've been using a loan SAN from Netapp that I need to return.

During my attempts to sanitize the disks I removed some shelves that aren't being returned which caused a cluster failover (I didnt care!)

However the cluster licence had expired.. Long story short, I was at home and needed to kick this disk sanitizer off so it could run over the weekend, and I couldnt be bothered to go back into the office.

One filer was accesible and one wasnt so.. I added the eval cluster licence to the working node and did a cf giveback -f (which got it out of the takeover state)

I then needed to change the ownership of the disks (the purpose of this post).. so after a lot of head scratching I tried the privledged mode commands and got a working solution!

I ended up doing the following:

options disk.auto_assign off (probably didnt need to do this - force of habit)

priv set advanced
disk remove_ownership -f 0a.121 0c.123 etc
priv set
disk assign all
disk sanitize start -c 7 0a.121 0c.122

Update: The sanitization finished, so I wanted to run another set to keep our security guys happy, I ran the same sanitize command again, hoping it would
just happily run again, no such luck - "disk start: 0a.xxx isn't a spare disk.". I then ran "disk assign all", this didn't work either it reported
"disk assign: Could not find any unowned disks to assign."

So:
Running "Disk Show" showed all the disks that had been sanitized reported as being failed. hmm.. ok..
"Priv set advanced"
"disk unfail -s 0a.xxx"
disk unfail: Can't unfail a sanitizing/sanitized disk.

Ok.. quick look at some documentation and you need to release the disk from the maintanance pool..

"disk sanitize release 0a.xxx"

I then attempted "disk assign all" however it then reported that the disks had bad labels, hmm ok..
again I then did "disk unfail -s 0a.xxx" which now worked as they all were added as spare disks..

I was then able to start the process over again, once this completes I will also zero the spares.

Tuesday 10 May 2011

Syncing Files with vb.net

This is a breif update to my rant the other day, I went away and looked at methods for doing what I wanted to achieve without having to rely on freeware utilities, scripts and reinventing the wheel.

Anyway whilst looking to see if there was anything available for .Net using RDC (Remote Differential Compression), My reason behind this was just because I have plenty of bandwidth (Over 1 gig) there was no reason to be sloppy. Google turned up the Microsoft Sync Framework SDK which looked just what I was after.

Ten lines of code or so later and I was able to sync a couple of folders locally which was a good step forward.

The next part it to watch the folder and trigger the sync which I am currently playing with the filesystemwatcher class.

I plan to post an update shortly when I've dealt with locked files etc!

Thursday 5 May 2011

Argh

Well that will teach me not to test things properly, I was working on the assumption that I could use DFS-R to replicate some data from two servers in serperate DMZ's for resilience. Think again as 2008 R2 DFS-R seems to want the server to be a domain member, thanks MS!. So much for a standalone namespace. Back to the drawing board and I suspect I'll be looking at .NET and RDC if its supported!.

Hmm, I've got until monday and I'm not working tomorrow.. so a late night tonight maybe, or a rough and ready robocopy script scheduled to buy a little time, however those rough and ready 'work around' bodges have a nasty habit of becoming permanent and biting you in the arse in months or years to come!

Update: Looks like the Sync Framework is going to be the easiest way of doing this.

Friday 15 April 2011

Update to Finding Server's Network Port Programatically

As I posted yesterday I said I may update the batch file to do a little more, well I've been sat around awaiting an engineer so I made a start on doing some improvements.

The following scripts attempts to find the physical adapters in a server that are enabled and arent the HP Teaming Adapter (we are a HP house, so tough if  your not!! :)

Once it has found the adapters it builds the interface name dynamically using the GUID as this is supported by TCPDUMP and then listens for a CDP packet (This is a cisco function that could have been disabled by your network administrators)

After the packet has been recieved it does some pretty messy string manipulation, because I couldnt be bothered to pull my hair out with RegEx. After I have pulled out the information I want I check to see if the Adapter description has the switch port information and update the description if it doesn't.

The script can be ammended to not update the NIC description and just output the details to screen by commenting and uncommenting a few lines.

** Update 21-04-11 - Added code to swap to cscript rather than wscript. **

' ******************************************************************
' NameAdapters.vbs
' ******************************************************************
' Determine Pysical NIC Adapters for Team
' David Wallis - 15/04/11
' ******************************************************************

' ******************************************************************
' Check Script is being run with CSCRIPT rather than WSCRIPT due to using stdout
' ******************************************************************
    
If UCase(Right(Wscript.FullName, 11)) = "WSCRIPT.EXE" Then
    strPath = Wscript.ScriptFullName
 Wscript.Echo "This script must be run under CScript." & vbCrLf & vbCrLf & "Re-Starting Under CScript"
    strCommand = "%comspec% /K cscript //NOLOGO " & Chr(34) & strPath & chr(34)
    Set objShell = CreateObject("Wscript.Shell")
    objShell.Run(strCommand)
    Wscript.Quit
End If

strComputer = "."

Const NETWORK_CONNECTIONS = &H31&

Set objShell = CreateObject("Wscript.Shell")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objShellApp = CreateObject("Shell.Application")
Set objFolder = objShellApp.Namespace(NETWORK_CONNECTIONS)


' NetEnabled is -1 when Enabled and 0 When the NIC is disabled

Set oAdapters = objWMIService.ExecQuery _
   ("Select * from Win32_NetworkAdapter where (NetEnabled = -1)")


' Enumerate the results (list of NICS). "
For Each oAdapter In oAdapters
 If oAdapter.ProductName = "HP Network Teaming Virtual Miniport Driver" Then
  'Teamed Adapter
 Else
  'Physical Nic - Execute TCPDUMP
  strCommand = "tcpdump -nn -v -s 1500 -i \Device\" & oAdapter.GUID & " -c 1 ether[20:2] == 0x2000" 

  Wscript.echo "Executing TCP Dump for Adapter " & chr(34) & oAdapter.NetConnectionID & chr(34) & " GUID:" & oAdapter.GUID & VbCrLF
  Set objExec = objShell.Exec(strCommand) 
   
  count = 0

  Do Until objExec.Status
   count = count +1
   'Timeout to Deal with Non CDP Enabled Devices
   If count = 1200 then
    wscript.echo "TCPDUMP Execution Timeout Exceeded, Script Quiting"
    wscript.quit
   End If
       Wscript.Sleep 250
  Loop 
  
  ' Loop through the output of TCPDUMP stored in stdout and retrieve required fields
  ' Namely switch name, IP and Port

  While Not objExec.StdOut.AtEndOfStream
     strLine = objExec.StdOut.ReadLine
   If Instr(UCASE(strLine),"DEVICE-ID") > 0 Then strDeviceID = Mid(strLine,(Instr(strLine,chr(39))+1),(Len(StrLine) - (Instr(strLine,chr(39))+1)))
   If Instr(UCASE(strLine),"ADDRESS ") > 0 Then strDeviceIP = Right(strLine,(Len(strLine) - (Instrrev(strLine,")")+1)))
   If Instr(UCASE(strLine),"PORT-ID") > 0 Then strPort = Mid(strLine,(Instr(strLine,chr(39))+1),(Len(StrLine) - (Instr(strLine,chr(39))+1)))
  Wend


  
  ' Rename Nic to Contain Switch Name and Port
  ' NetConnectionID Is readonly on some versions of Windows.
  
  strName = oAdapter.NetConnectionID
  Set colItems = objFolder.Items
  
  For Each objItem in colItems

       If objItem.Name = strName Then

    'Build Description to Append to Port Name 
    ' Windows doesn't like the / Character, so Replace it with a -

    strDescription = " (" & strDeviceID & " " & strDeviceIP &  " " & Replace(strPort,"/","-") & ")"

    ' If the port doesn't contain the switchport details then add them.
    
    If Instr(objItem.Name,strDescription) = 0 then
     wscript.echo "Ammending Adapter Description." & vbCrLf
     objItem.Name = strName & strDescription
    Else
     wscript.echo "Skipping Adapter Description Ammendment."
    End If
       End If
  Next ' objItem

  'wscript.echo "Details for Adapter " & chr(34) & oAdapter.NetConnectionID & Chr(34)
  'wscript.echo "MAC Addr: " & oAdapter.MACAddress & " Switch: " & strDeviceID & " " & strDeviceIP & " Port: " & strPort & vbCrLf

 End If

Next 'oAdapter


Wednesday 13 April 2011

Finding Server's Network Port Programatically

A while ago using info available on the net I knocked together a batch file that uses a windows port of TCPDUMP that doesn't need winpcap installed.

This worked fine and was great in our environment where CDP is enabled, Some advise disabling for security though.

Well all worked fine until I started trying it on windows 2008 and was receiving the following error message:

tcpdump.exe: PacketGetAdapterNames: The operation completed successfully. (0)

I looked around and 3.9.8 seemed to be the latest version, and doesn't offer support for windows 2008 r2 however I downloaded the trial of version 4 from here  http://www.microolap.com/products/network/tcpdump/download/

Which still doesn't state it works on windows 2008.. :(  -- however my batch file now works again.. :)

Anyway my rough and ready batch file contains the following:


cls
tcpdump -D
set Interface=
echo.
set /P Interface=Enter Interface Number: %=%
tcpdump -nn -v -s 1500 -i %Interface% -c 1 ether[20:2] == 0x2000 >c:\out.txt
Echo "Port Details Are" |Echo.
type c:\out.txt |findstr /R "\Device-ID \Address.[(] \Management.Addresses \Port-ID"
del c:\ out.txt >nul
pause

I will eventually re-write this as powershell or VBS so I can deploy it via SCCM to get a view of ports the servers are patched into.