Answered by:
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:
>$mibDataObjectsQualifiers_ : {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-memberName 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 Zhang 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 sysnamesysname
-------
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 Shaw 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- Marked as answer by Mervyn Zhang Thursday, October 15, 2009 10:56 AM
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 MOWWednesday, 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')
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
Method invocation failed because [System.__ComObject] doesn't contain a method named 'Properties_'.
At line:1 char:28
+ $mibDataObjects.Properties_( <<<< 'sysName')
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 Zhang 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.0Tuesday, 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 versionI 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 sysnamesysname
-------
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 Shaw 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- Marked as answer by Mervyn Zhang Thursday, October 15, 2009 10:56 AM
Thursday, October 15, 2009 9:14 AM