WMI to access devices over SNMP – Error Invalid Namespace

January 20, 2015

I wanted to run an old script of mine to read out some network printer information using WMI – SNMP.

But I got an error saying that “Invalid Namespace“ Sad smile

Solutions :

You need to add the SNMP WMI providers to your machine.

1. Go to the Control Panel
2. Next select Programs and Features
3. Select Simple Network Management Protocol (SNMP)
4. Select WMI SNMP Provider

image

Once installed all errors are gone Smile

; Initialize error handler
$oMyError = ObjEvent("AutoIt.Error","MyErrFunc")   $iIP = 31   For $iIP = 31 To 45 ; IP range   $strTargetSnmpDevice = "10.0.0." & $iIP
 ConsoleWrite("Target Device : " & $strTargetSnmpDevice & @CRLF)
 ConsoleWrite("-------------" & @CRLF)   $objWmiLocator = ObjCreate("WbemScripting.SWbemLocator")
 $objWmiServices = $objWmiLocator.ConnectServer("", "root\snmp\localhost")   $objWmiNamedValueSet = ObjCreate("WbemScripting.SWbemNamedValueSet")
 $objWmiNamedValueSet.Add ("AgentAddress", $strTargetSnmpDevice)
 $objWmiNamedValueSet.Add ("AgentReadCommunityName", "public")   $colIfTable = $objWmiServices.InstancesOf("SNMP_RFC1213_MIB_ifTable",Default , $objWmiNamedValueSet)   For $objInterface In $colIfTable
    ConsoleWrite ("ifIndex [Key]:        " & $objInterface.ifIndex  & @CRLF & _
        "   ifAdminStatus:     " & $objInterface.ifAdminStatus 		& @CRLF & _
        "   ifDescr:           " & $objInterface.ifDescr         	& @CRLF & _
        "   ifInDiscards:      " & $objInterface.ifInDiscards    	& @CRLF & _
        "   ifInErrors:        " & $objInterface.ifInErrors      	& @CRLF & _
        "   ifInNUcastPkts:    " & $objInterface.ifInNUcastPkts   	& @CRLF & _
        "   ifInOctets:        " & $objInterface.ifInOctets      	& @CRLF & _
        "   ifInUcastPkts:     " & $objInterface.ifInUcastPkts 		& @CRLF & _
        "   ifInUnknownProtos: " & $objInterface.ifInUnknownProtos 	& @CRLF & _
        "   ifLastChange:      " & $objInterface.ifLastChange     	& @CRLF & _
        "   ifMtu:             " & $objInterface.ifMtu            	& @CRLF & _
        "   ifOperStatus:      " & $objInterface.ifOperStatus     	& @CRLF & _
        "   ifOutDiscards:     " & $objInterface.ifOutDiscards 		& @CRLF & _
        "   ifOutErrors:       " & $objInterface.ifOutErrors      	& @CRLF & _
        "   ifOutNUcastPkts:   " & $objInterface.ifOutNUcastPkts  	& @CRLF & _
        "   ifOutOctets:       " & $objInterface.ifOutOctets      	& @CRLF & _
        "   ifOutQLen:         " & $objInterface.ifOutQLen        	& @CRLF & _
        "   ifOutUcastPkts:    " & $objInterface.ifOutUcastPkts   	& @CRLF & _
        "   ifPhysAddress:     " & $objInterface.ifPhysAddress 		& @CRLF & _
        "   ifSpecific:        " & $objInterface.ifSpecific       	& @CRLF & _
        "   ifSpeed:           " & $objInterface.ifSpeed          	& @CRLF & _
        "   ifType:            " & $objInterface.ifType           	& @CRLF)
		ConsoleWrite("" & @CRLF)
 Next
ConsoleWrite("" & @CRLF)
Next

Output is like this :

image

For Powershell it looks a bit different:


CLS

For ($iIP=32; $iIP -le 45; $iIP++){

    $CommunityString = "public"
    $IPAddress     = "10.0.0."+$iIP
    write-host $IPAddress

    $Opt = new-object Management.ConnectionOptions
    $Opt.Impersonation = 'Impersonate'

    $context = new-object management.ManagementNamedValueCollection
    $context.Add("AgentAddress", $IPAddress)
    $context.Add("AgentReadCommunityName", $CommunityString)

    $ogo =  new-object management.ObjectGetOptions($context, (new-object TimeSpan(0,0,0,5)), $true)

    $scope = new-object management.ManagementScope("root\snmp\localhost", $Opt)

    $query = new-object Management.ObjectQuery("select * from SNMP_RFC1213_MIB_system")

    $searcher = new-object Management.ManagementObjectSearcher($scope,$query)
    $searcher.Options.Context = $context

    $searcher.get()

}

Output is like this :

image

If you want to access devices like routers, switches, printers etc. using Native SNMP protocol.

You will need some tools to get hold of their public or private MIB Object ID’s.

Once of the many tools out there is Softperfect Network scanner.

image

Maybe I will address this later how to access the network Devices using native SNMP protocol Winking smile

Enjoy !


Install TTF Barcode Fonts

August 28, 2014

I had to install some barcode fonts to be used in Word and Excel for Label printing.

After installing it will look like this.

image

Some of the fonts are free to download from then net, like (Barcode 39 TTF), others are not.

Installing is normally a piece of cake. Right click the font file and choose Install.

image

But in some PC’s the file association has changed because of other applications being installed.

So there is no Install Sad smile

image

To find the associated application on the machine, use assoc.exe

image

Indeed you see it here :

HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts

image

To find what was the original file association, have a look here.

http://dhetricks.blogspot.be/2012/01/windows-7-file-association-fix.html

You see it was associated with Windows Fonts Viewer.

Being here : C:\Windows\System32\Fontview.exe

Solution :

Let fix it using AutoIT

#RequireAdmin

FileExtAssoc("ttf", "Fontview.exe")

func FileExtAssoc($sExt, $sApplication)
    RunWait(@COMSPEC & " /c ASSOC ." & $sExt & "=ExTest", "", @SW_HIDE)
    RunWait(@COMSPEC & " /c FTYPE ExTest=" & $sApplication , "", @SW_HIDE)
    MsgBox(0,"File Extension Application Association",'"' & $sExt & '"is now asscoiated with "' & $sApplication & '"',3)
EndFunc

Or using the GUI way like this.

image

image

image

Enjoy !


AutoIT – Visual Studio Light

August 24, 2014

Sometime you find some nice code on the internet like VB.Net or C#.

But it is of no use if it is not compiled Sad smile

As explained in this post you can compile you own .NET COM objects on the fly.

But if you want to do it using a GUI interface without installing the full blown Visual Studio. You can use this GUI Wrapper – Visual Studio Light

image

The first option is for compiling GUI Applications EXE’s.

The second one is to create DLL’s (Libraries) which you can use later on in a .Net application.

The third one is for compiling Console Applications EXE’s.

You can download it here

PS :  This wrapper is for VB.Net but can easily be changed to use C# replace the vbc.exe by csc.exe

If you run it you get an EXE or DLL

image

image

This is the code :

imports System.Windows.Forms

' The name of the module must match the name of the code item
' created in the hosting application via CreateItem.
module Script
  sub Main()
    MessageBox.Show("hi From DotNET !!")
  end sub
end module

How to run .Net Assemblies in Powershell see here

How to run .Net Assemblies form Memory in Powershell see here

Enjoy !


Using AutoIT to compile your own .NET COM Object

August 24, 2014

Wouldn’t it be nice to compile your own .NET COM DLL and use it on AutoIT.

Well we don’t need much to do this. Everything is available on your system.

Let’s see :

First we need of course some VB.Net code or C# that will exposes some methods or properties.

Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices

Namespace myDotNetLibrary
  <classinterface   (CLASSINTERFACETYPE.AUTODUAL)> _
  Public Class myDotNetClass
    Private myProperty As String

    Public Sub New()
    End Sub

    Public Function myDotNetMethod(input As String) As String
      Return "Hello " & input
    End Function

    Public Property myDotNetProperty() As String
      Get
        Return myProperty
      End Get
      Set(ByVal value As String)
        myProperty = value
      End Set
    End Property

  End Class
End Namespace

Next we need a .Net compiler ? Ha but that is default available on each system that has a .Net Framework installed Smile

Go and have a look here : C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\vbc.exe

The vbc.exe is the compiler for the .Net 2.0 framework. But you will find as well the compiler for .NET 3.0 and 4.0 if you have that framework installed.

So now we need to compile the code to a DLL and register it.

#RequireAdmin

; Framework 2.0
;$vbc = "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\vbc.exe" ;  ; check the path of your version
;$RegAsm = "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe" ; check the path of your version
; Framework 4.0
$vbc = "C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\vbc.exe" ;  ; check the path of your version
$RegAsm = "C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" ; check the path of your version

RunWait($vbc & " /target:library hello.vb", @ScriptDir, @SW_HIDE) ; compile the .net DLL
RunWait($RegAsm & " /codebase hello.dll", @ScriptDir, @SW_HIDE) ; register the .net DLL

$obj = ObjCreate("myDotNetLibrary.myDotNetClass")
$obj.myDotNetProperty = " ... from DotNet to the AutoIt World !"

MsgBox(0,"My Own DotNet Object " , $obj.myDotNetMethod($obj.myDotNetProperty) & @CRLF)

RunWait($RegAsm & " /unregister hello.dll", @ScriptDir, @SW_HIDE) ; unregister the .net DLL

Ones you run the code it will compile the code to a DLL and register it in the GAC

Or if you want don’t want to register the COM Assembly to the GAC, you can use this approach 😉

 

image

And run it as a COM object, where AU3 will access it’s methods and properties.

image

You can see if the COM object registered correctly here :

image

For a C# compiler you need to look for the csc.exe instead of the vbc.exe

Enjoy!


AutoIT module for Powershell

August 24, 2014

In the last Beta releases AutoIT is shipped with a .NET Assembly as well as a Powershell Module

You can find it here :

image

First import the module and run this example.

CLS

# Import the module manfiest
Import-Module (${Env:ProgramFiles(x86)} + "\AutoIt3\Beta\AutoItX\AutoItX3.psd1")

Invoke-AU3Run("Notepad")

Wait-AU3WinActive("Untitled")

Send-AU3Key("I'm in notepad");

$winHandle = Get-AU3WinHandle("Untitled");

Sleep -Seconds 2

Close-AU3Win($winHandle)

# Get the list of AutoItX cmdlets
Get-Command *AU3*

# Get detailed help for a particular cmdlet
Get-Help Get-AU3WinHandle

Getting help on the cmdlets and commands using the Get-Command and Get-Help will list you all needed information to get started.

image

image

Even if the functionality is limited at the moment, it is a good sign AU3 is moving towards PS. Smile


The ‘Microsoft.Jet.OLEDB.4.0’ provider is not registered on the local machine

August 22, 2014

If you get this error

Exception calling “Open” with “0” argument(s): “The ‘Microsoft.Jet.OLEDB.4.0’ provider is not registered on the local machine.”

image

Background
Microsoft OLEDB Drivers work on 32 or 64 bit architecture, running Windows XP, Vista, 7 or Windows 8.

Some of the drivers are only 32 Bit compatible ! like this above one.

Additionally on some Windows 64 bit systems, it is possible that some of the Microsoft OLEDB DLLs have not been registered.

Solution No. 1

Check that you are running the 32 bit PowerShell Console or ISE. In the past with Powershell v1.0 you could start it form here :

image

 

 

 

 

 

 

 

But later on after upgrading to v3.0 it disappeared.There are still 2 hints where you can see if you are running x64 or x86.After starting the ISE

image

you will see it here in the Title Bar it says … x86image

The command window you see the location SysWOW64

You can start it from here :

image 

The Solution No. 2.
The solution is to manually register those DLLs.
go to Start->Run and type cmd
this starts the Command Prompt

Go to a special folder
cd c:\windows\sysWOW64

Now you need to register the OLE DB 4.0 DLLs by typing these commands and pressing return after each. Might be only the first 2 will register, no problem.

regsvr32 Msjetoledb40.dll
regsvr32 Msjet40.dll
regsvr32 Mswstr10.dll
regsvr32 Msjter40.dll
regsvr32 Msjint40.dll

http://support.microsoft.com/kb/278604

image

If errors appear.

Install AccessDatabaseEngine.exe from the MS site and try again.

http://www.microsoft.com/en-us/download/details.aspx?id=13255

x86 for MS Office x32 bit and

x64 for MS Office x64 bit

image

Hope this will help solving some frustrations.


AutoIT meeting Powershell

August 21, 2014

Both scripting languages have their advandtages.

AutoIT is good at Windows API’s, GUI automation, and more …

Powershell is good at using .Net Classes and more …

So making this a couple would be just great Smile

Well here we go.

This code here will take AU3 output and PS will re-use them by means of objects.

CLS

function Au3_cmd ($sEnv = "env:programfiles(x86)" $sArch = "\AutoIt3\AutoIt3_x64.exe "$sType = " /AutoIt3ExecuteLine ", $sCmd = "" )
{

$sPath = get-content $sEnv

$sPath =  $sPath + $sArch

$oObj = New-Object -ComObject Scripting.FileSystemObject

$sf = $oObj.GetFile($sPath) # GetFile gets the dir ShortPath

    Return $sPath, $sf.ShortPath, $sType, $sCmd
}

$sCmd1 = Au3_cmd -sCmd "InputBox('Question', 'Where were you born?', 'Planet Earth 1', '', -1, -1, 0, 0)" 
$sCmd1 = Au3_cmd -sCmd "InputBox('Question', 'Where were you born?', 'Planet Earth 1', '', -1, -1, 0, 0)"
$sCmd2 = Au3_cmd -sCmd "MsgBox(0,'Au3 => PS Test','Hello World 2')"
$sCmd3 = Au3_cmd -sCmd "ConsoleWrite(@CRLF & 'Hello World 3' & @CRLF)"
$sCmd4 = Au3_cmd -sCmd "ConsoleWrite(@CRLF & 'Hello World 4' & ' - ' & @IPAddress1 & @CRLF)"

invoke-expression  ($sCmd1[1] + $sCmd1[2] + [CHAR]34 + $sCmd1[3] + [CHAR]34) | % { "processing Au3 Output 4 : $_ " } 
invoke-expression  ($sCmd2[1] + $sCmd2[2] + [CHAR]34 + $sCmd2[3] + [CHAR]34) 

# 2 ways to capture the invoke-expression Pipe output 
# 1. Write-Host 2. using the tee-object where objects can be re-used via the pipe.

$Ret3 =  ($sCmd3[1] + $sCmd3[2] + [CHAR]34 + $sCmd3[3] + [CHAR]34) 
invoke-expression  "$Ret3  | Write-Host"

$Ret4 =  ($sCmd4[1] + $sCmd4[2] + [CHAR]34 + $sCmd4[3] + [CHAR]34) 
invoke-expression "$Ret4 | tee-object -variable return" | % { "processing Au3 Output 4 : $_ " }

echo "Number of Objects $($Return.Count) :)" 

# -----------------------------------------------

$sCmd5 = Au3_cmd -sType " /AutoIt3ExecuteScript " -sCmd "C:\_\Apps\_PowerShell\_Au3 & VBScript in PS\test.au3"
$Ret5 = ($sCmd5[1] + $sCmd5[2] + [CHAR]34 + $sCmd5[3] + $sCmd5[4] + [CHAR]34)

Echo ' --- ' # All object as output
invoke-expression  "$Ret5 | Write-Host" 

Echo ' --- ' # All objects moved to a variable and passed on to PS.
invoke-expression "$Ret5 | tee-object -variable script" | % { "processing Au3 Output 5 : $_ " } | Where-object {$_ -notlike '*Idle*'}


rv sCmd1
rv sCmd2
rv sCmd3
rv sCmd4
rv sCmd5

rv ret3
rv ret4
rv ret5

rv script

And call some Windows GUI’s like Msg boxes or Input boxes as well. AutoIT can use command line and script file input.

image

This output comes from AU3 calling some Windows API’s

image

And passes it to PS as Object where we can apply filters to it etc.

image

This is the AU3 script file code.

ConsoleWrite(test() & @CRLF)

Func test()
	$sRet = StringLeft("I am a string", 3)
 Return $sRet
EndFunc

; ------------------------------------------

ConsoleWrite("Idle since " &_IdleTicks() & " MSecs"& @CRLF)

Func _IdleTicks()
    Local $aTSB, $ticksSinceBoot, $struct, $ticksSinceIdle

    $aTSB = DllCall ("kernel32.dll", "long", "GetTickCount")
    $ticksSinceBoot = $aTSB[0]

    $struct = DllStructCreate("uint;dword");
    DllStructSetData($struct, 1, DllStructGetSize($struct));
    DllCall("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr($struct))
    $ticksSinceIdle = DllStructGetData($struct, 2)

    return $ticksSinceBoot - $ticksSinceIdle
endfunc

; ------------------------------------------

Dim $idays
Dim $ihours
Dim $imins
Dim $isecs

_uptime($idays,$ihours,$imins,$isecs)

MsgBox(0,"Uptime","Days: " & $idays & " - Hours: " & $ihours & " - mins: " & $imins & " - secs: " & $isecs)

ConsoleWrite("Days: " & $idays & " - Hours: " & $ihours & " - mins: " & $imins & " - secs: " & $isecs & @CRLF)

Func _uptime(ByRef $iDays, ByRef $iHours, ByRef $iMins, ByRef $iSecs)
    $iTicks = DllCall("kernel32.dll", "long", "GetTickCount")
    $iTicks = $iTicks[0]
    If Number($iTicks) > 0 Then
        $iTicks = Round($iTicks / 1000)
        $iDays  = Int($iTicks / 86400)
        $iHours = Int($iTicks / 3600)
        $iTicks = Mod($iTicks, 3600)
        $iMins = Int($iTicks / 60)
        $iSecs = Round(Mod($iTicks, 60))
        Return 1
    ElseIf Number($iTicks) = 0 Then
        $iDays = 0
        $iHours = 0
        $iTicks = 0
        $iMins = 0
        $iSecs = 0
        Return 1
    Else
        SetError(1)
        Return 0
    EndIf
EndFunc   ;==>_uptime

As you can see PS can handle this perfectly for further processing.

Great marriage !