none
Working with WbemScripting

    Question

  • I have a vbs script that gets different values from any network device through SNMP. Here is it:

    CommunityString = "public"
    IPAddress = "192.168.1.2"
    Set wmiLocator = CreateObject("WbemScripting.SWbemLocator")
    wmiLocator.Security_.ImpersonationLevel = 3
    Set wmiService = wmiLocator.ConnectServer(, "root\snmp\localhost")
    Set wmiContext = CreateObject("WbemScripting.SWbemNamedValueSet")
    Set strNamedValue = wmiContext.Add("AgentAddress", IPAddress)
    Set strNamedValue = wmiContext.Add("AgentReadCommunityName", CommunityString)
    Set mibDataObjects = wmiService.ExecQuery ("Select sysName from SNMP_RFC1213_MIB_system", , , wmiContext)
    For Each mibDataObject In mibDataObjects
    	WScript.Echo "SysName: " & mibDataObject.sysName
    Next
    

    This vbs script works well.
    I try to convert it into the PS-script. Here is my code:

    $CommunityString = "public"
    $IPAddress = "192.168.1.2 $wmiLocator = New-Object -com WbemScripting.SWbemLocator $wmiLocator.Security_.ImpersonationLevel = 3 $wmiService = $wmiLocator.ConnectServer('.', 'root\snmp\localhost') $wmiContext = New-Object -com WbemScripting.SWbemNamedValueSet $strNamedValue = $wmiContext.Add("AgentAddress", $IPAddress) $strNamedValue = $wmiContext.Add("AgentReadCommunityName", $CommunityString) $mibDataObjects = $wmiService.ExecQuery("Select sysName from SNMP_RFC1213_MIB_system","WQL",16,$wmiContext) foreach ($objSystem in $mibDataObjects) { 'Sysname: ' + $objSystem.sysName }

    Script doesn't return anything. OK. Lets see:
    >$mibDataObjects

    Qualifiers_       : {dynamic, group_objectid, module_name, provider...}
    Properties_       : {sysName}
    Methods_          :
    Derivation_       : {SnmpObjectType, SnmpMacro}
    Path_             : System.__ComObject
    Security_         : System.__ComObject
    SystemProperties_ : {__PATH, __NAMESPACE, __SERVER, __DERIVATION...}


     >$mibDataObjects | get-member

    Name               MemberType Definition
    ----               ---------- ----------
    AssociatorsAsync_  Method     void AssociatorsAsync_ (IDispatch, string, string,...
    Associators_       Method     ISWbemObjectSet Associators_ (string, string, stri...
    Clone_             Method     ISWbemObject Clone_ ()
    CompareTo_         Method     bool CompareTo_ (IDispatch, int)
    DeleteAsync_       Method     void DeleteAsync_ (IDispatch, int, IDispatch, IDis...
    Delete_            Method     void Delete_ (int, IDispatch)
    ExecMethodAsync_   Method     void ExecMethodAsync_ (IDispatch, string, IDispatc...
    ExecMethod_        Method     ISWbemObject ExecMethod_ (string, IDispatch, int, ...
    GetObjectText_     Method     string GetObjectText_ (int)
    GetText_           Method     string GetText_ (WbemObjectTextFormatEnum, int, ID...
    InstancesAsync_    Method     void InstancesAsync_ (IDispatch, int, IDispatch, I...
    Instances_         Method     ISWbemObjectSet Instances_ (int, IDispatch)
    PutAsync_          Method     void PutAsync_ (IDispatch, int, IDispatch, IDispatch)
    Put_               Method     ISWbemObjectPath Put_ (int, IDispatch)
    ReferencesAsync_   Method     void ReferencesAsync_ (IDispatch, string, string, ...
    References_        Method     ISWbemObjectSet References_ (string, string, bool,...
    Refresh_           Method     void Refresh_ (int, IDispatch)
    SetFromText_       Method     void SetFromText_ (string, WbemObjectTextFormatEnu...
    SpawnDerivedClass_ Method     ISWbemObject SpawnDerivedClass_ (int)
    SpawnInstance_     Method     ISWbemObject SpawnInstance_ (int)
    SubclassesAsync_   Method     void SubclassesAsync_ (IDispatch, int, IDispatch, ...
    Subclasses_        Method     ISWbemObjectSet Subclasses_ (int, IDispatch)
    Derivation_        Property   Variant Derivation_ () {get}
    Methods_           Property   ISWbemMethodSet Methods_ () {get}
    Path_              Property   ISWbemObjectPath Path_ () {get}
    Properties_        Property   ISWbemPropertySet Properties_ () {get}
    Qualifiers_        Property   ISWbemQualifierSet Qualifiers_ () {get}
    Security_          Property   ISWbemSecurity Security_ () {get}
    SystemProperties_  Property   ISWbemPropertySet SystemProperties_ () {get}
    If I try to change IP or CommunityString, $mibDataObjects doesn't return anything so it seems that methods work

    How I can get sysName value?
    Wednesday, October 7, 2009 12:32 PM

Answers

  • I could not get it working with the COM Object, but translated the script using .NET and found the following version that works :

    $CommunityString = "public"
    $IPAddress     = "192.168.1.2"

    $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()

    Enjoy,

    Greetings MOW
    • Marked as answer by Mervyn ZhangModerator Monday, October 12, 2009 10:54 AM
    • Unmarked as answer by Alexx_B Tuesday, October 13, 2009 8:10 AM
    • Marked as answer by Alexx_B Thursday, October 15, 2009 5:59 AM
    Monday, October 12, 2009 9:13 AM
  • You can select properties like this :

    PS C:\Users\_morsouw> $result = $searcher.get()
    PS C:\Users\_morsouw> $r | select sysname

    sysname
    -------
    SERVER01

    or

    PS C:\Users\_morsouw> $r |% {$_.sysname}
    SERVER01

    to see the difference in PowerShell V2 this looks like this :

    PS C:\Users\_morsouw> $searcher.get()


    __GENUS          : 2
    __CLASS          : SNMP_RFC1213_MIB_system
    __SUPERCLASS     : SnmpObjectType
    __DYNASTY        : SnmpMacro
    __RELPATH        : SNMP_RFC1213_MIB_system=@
    __PROPERTY_COUNT : 7
    __DERIVATION     : {SnmpObjectType, SnmpMacro}
    __SERVER         : server
    __NAMESPACE      : root\snmp\localhost
    __PATH           : \\server1\root\snmp\localhost:SNMP_RFC1213_MIB_system=@
    sysContact       :
    sysDescr         : Hardware: Intel64 Family 6 Model 15 Stepping 11 AT/AT COMPATIBLE - Software: Windows Version 6.1 (Bu
                       ild 7600 Multiprocessor Free)
    sysLocation      :
    sysName          : server.some.com
    sysObjectID      : 1.3.6.1.4.1.311.1.1.3.1.2
    sysServices      : 76
    sysUpTime        : 202564

    as syscontact and syslocation where NULL on my system
    this was the max I could get :

    PS > $searcher.get() | select sysDescr,sysName,sysObjectID,sysServices,sysUpTime


    sysDescr    : Hardware: x86 Family 6 Model 23 Stepping 10 AT/AT COMPATIBLE -
                  Multiprocessor Free)
    sysName     : SERVER1
    sysObjectID : 1.3.6.1.4.1.311.1.1.3.1.2
    sysServices : 79
    sysUpTime   : 7534327

    Enjoy,
    Greetings MOW

    • Proposed as answer by Marco ShawModerator Thursday, October 15, 2009 12:48 AM
    • Marked as answer by Alexx_B Thursday, October 15, 2009 5:59 AM
    Wednesday, October 14, 2009 7:49 PM
  • Your welcome,

    I know it is confusing but the bug is in properties that return NULL (syscontact and syslocation in our example)
    as long as you do not select those properties it works.

    when you do $searcher.get() all properties are returned including the empty ones that gives the error.

    Greetings MOW

    Thursday, October 15, 2009 9:14 AM

All replies

  • I do not have SNMP provider installed here, but seems that the result is store in properties_ property can you test it like this ? :

    $mibDataObjects.Properties_.sysName
    $mibDataObjects.Properties_('sysName')

    another option would be not to use COM object but native Powershell (example by head not tested)

    get-WmiObject -query "Select sysName from SNMP_RFC1213_MIB_system WHERE AgentAddress = '$IPAddress' AND AgentReadCommunityName = '$CommunityString'  " -namespace 'root\snmp\localhost'

    If you not find the answre before the weekend I can further test in my test environment

    h.t.h.

    Greetings MOW
    Wednesday, October 7, 2009 1:57 PM
  • $mibDataObjects.Properties_.sysName
    $mibDataObjects.Properties_('sysName')

    I try these variants. First of them retuns nothing and the second returns an error:

    >$mibDataObjects.Properties_('sysName')
    Method invocation failed because [System.__ComObject] doesn't contain a method named 'Properties_'.
    At line:1 char:28
    + $mibDataObjects.Properties_( <<<< 'sysName')
    It seems that first variant is rightful (i try the same previously) but sysName property is blank. Of course if I try to run vbscript I see the proper name so I think that my vbscript translation to powershell is not right

    another option would be not to use COM object but native Powershell
    I've got the following error:
    >gwmi -query "SELECT * from SNMP_RFC1213_MIB_system WHERE AgentAddress='192.168.1.2' AND AgentReadCommunityName='public'" -namespace 'root\snmp\localhost'
    Get-WmiObject : Invalid class
    At line:1 char:5
    + gwmi  <<<< -query "SELECT * from SNMP_RFC1213_MIB_system WHERE AgentAddress='192.168.1.2' AND AgentReadCommunityName='public'" -namespace 'root\snmp\localhost'
    Thursday, October 8, 2009 6:11 AM
  • I could not get it working with the COM Object, but translated the script using .NET and found the following version that works :

    $CommunityString = "public"
    $IPAddress     = "192.168.1.2"

    $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()

    Enjoy,

    Greetings MOW
    • Marked as answer by Mervyn ZhangModerator Monday, October 12, 2009 10:54 AM
    • Unmarked as answer by Alexx_B Tuesday, October 13, 2009 8:10 AM
    • Marked as answer by Alexx_B Thursday, October 15, 2009 5:59 AM
    Monday, October 12, 2009 9:13 AM
  • Thanks for your solution but I have some troubles with it.

    When I execute $searcher.get() - I've got an error 'format-default : Exception retrieving members: "Not found "'

    If I try to change IP to invalid value, I've got another error:
    An error occurred while enumerating through a collection: Invalid class .
    At line:1 char:14
    + $searcher.get( <<<< )

    So It seems that code is valid but I can't get values.
    I try this script on 3 different PCs when VBScript works well.

    Unfortunately I'm not .Net coder so I can't find the error

    could you help me a bit?
    My .Net version is 3.5 SP2 and Powershell version is 1.0

    Tuesday, October 13, 2009 8:10 AM
  • I tested my solution in PowerShell V2 there it works, seems you have hit a bug in the WMI adapter in PowerShell V1 that is solved in PowerShell V2.
    IIRC (I bugged it) there is a bug with properties that are writeonly, but when you select specific properties (not the one that is giving problems it works

    2 bad I can not test this in PowerShell V1 at the moment ,  can you try getting only the sysname like this ?

    $searcher.get().sysName

    if not I need another raincheck until I can test again.

    Greetings MOW
     
    Tuesday, October 13, 2009 8:36 AM
  • Thanks for your comment about version uncompatibility
    I'm forced to use v1 beacuse v2 (AFAIK) hasn't been realeased and OpsMgr supports only v1 version

    I try $searcher.get().sysName and it nothing returns. Now I'm not sure that I can solve my problem directly. I think that I can use something like vbscript wrapper in my PS1 code but this solution isn't nice :)

    So if you have some time and you are able to make an experiment with the 1st version  - let me know please, it would be great if I could use Powershell only

    Tuesday, October 13, 2009 11:35 AM
  • You can select properties like this :

    PS C:\Users\_morsouw> $result = $searcher.get()
    PS C:\Users\_morsouw> $r | select sysname

    sysname
    -------
    SERVER01

    or

    PS C:\Users\_morsouw> $r |% {$_.sysname}
    SERVER01

    to see the difference in PowerShell V2 this looks like this :

    PS C:\Users\_morsouw> $searcher.get()


    __GENUS          : 2
    __CLASS          : SNMP_RFC1213_MIB_system
    __SUPERCLASS     : SnmpObjectType
    __DYNASTY        : SnmpMacro
    __RELPATH        : SNMP_RFC1213_MIB_system=@
    __PROPERTY_COUNT : 7
    __DERIVATION     : {SnmpObjectType, SnmpMacro}
    __SERVER         : server
    __NAMESPACE      : root\snmp\localhost
    __PATH           : \\server1\root\snmp\localhost:SNMP_RFC1213_MIB_system=@
    sysContact       :
    sysDescr         : Hardware: Intel64 Family 6 Model 15 Stepping 11 AT/AT COMPATIBLE - Software: Windows Version 6.1 (Bu
                       ild 7600 Multiprocessor Free)
    sysLocation      :
    sysName          : server.some.com
    sysObjectID      : 1.3.6.1.4.1.311.1.1.3.1.2
    sysServices      : 76
    sysUpTime        : 202564

    as syscontact and syslocation where NULL on my system
    this was the max I could get :

    PS > $searcher.get() | select sysDescr,sysName,sysObjectID,sysServices,sysUpTime


    sysDescr    : Hardware: x86 Family 6 Model 23 Stepping 10 AT/AT COMPATIBLE -
                  Multiprocessor Free)
    sysName     : SERVER1
    sysObjectID : 1.3.6.1.4.1.311.1.1.3.1.2
    sysServices : 79
    sysUpTime   : 7534327

    Enjoy,
    Greetings MOW

    • Proposed as answer by Marco ShawModerator Thursday, October 15, 2009 12:48 AM
    • Marked as answer by Alexx_B Thursday, October 15, 2009 5:59 AM
    Wednesday, October 14, 2009 7:49 PM
  • At first I thought that your solution didn't work again but then I saw that you replaced $result in your code $r :)
    I try to use $result and it works well

    Very strange but if I try $searcher.get()  - I've got an error, but if I try $searcher.get() | select sysDescr,sysName,sysObjectID,sysServices,sysUpTime - it works well. It is a wonder :)


    Thank you very much for your solution!

    Thursday, October 15, 2009 5:59 AM
  • Your welcome,

    I know it is confusing but the bug is in properties that return NULL (syscontact and syslocation in our example)
    as long as you do not select those properties it works.

    when you do $searcher.get() all properties are returned including the empty ones that gives the error.

    Greetings MOW

    Thursday, October 15, 2009 9:14 AM