ChrisLD has asked for the wisdom of the Perl Monks concerning the following question:

Need Help converting this vbscript from technet to perl
Const BcdLibraryString_Description = &h12000004 Const Current = "{fa926493-6f1c-4193-a414-58f0b2456d1e}" strComputer = "." Set objStoreClass = GetObject("winmgmts:{(Backup,Restore)}\\" & _ strComputer & "\root\wmi:BcdStore") objStoreClass.OpenStore "", objStore objStore.OpenObject Current, objDefault objDefault.GetElement BcdLibraryString_Description, objElement Wscript.Echo "Current operating system: " & objElement.String
My attempt to transfer into Perl which is not working.
use strict; use Win32::OLE; use Data::Dumper; use warnings; my $BcdLibraryString_Description = "&h12000004"; my $Current = "{fa926493-6f1c-4193-a414-58f0b2456d1e}"; my $strComputer = "\\\\localhost"; my $root = "\\root\\wmi:BcdStore"; my $class = ("winmgmts:{impersonationlevel=impersonate,(Backup,Restore +)}$strComputer$root"); my $wmi = Win32::OLE->GetObject($class); $wmi->OpenStore("", my $bcdst) or die "failed to get bcd"; #Also tried my $setopenstore = $wmi->OpenStore("",my $bcdst); $bcdst->OpenObject($Current, my $defaultclass ) or die "failed to open +object"; #Failing Point “Can't call method "OpenObject" on an undefined value at ASR_test2.pl” It looks like the previous line openstore is not assigning the store to $bcdst #Also tried my $setdefaultclass = $openstore->OpenObject($Current, my +$defaultclass); $defaultclass->GetElement($BcdLibraryString_Description, my $debugstat +us); print "\n$debugstatus\n";
Am I missing something obvious?

Replies are listed 'Best First'.
Re: Perl - WMI - BCD
by GrandFather (Saint) on Jul 08, 2008 at 01:00 UTC

    Yup. $wmi is undef so Win32::OLE->GetObject failed. Check that the contents of $class is correct.

    Update: the following test code works for me:

    use strict; use Win32::OLE; use warnings; my $wmi = Win32::OLE->GetObject('winmgmts:!\\\\localhost\root\default' +); print "Got a wmi object" if defined $wmi;

    Perl is environmentally friendly - it saves trees
      If I dump the value of $wmi It shows the expected information from wmi:bcdstore
      $VAR1 = bless( { 'Qualifiers_' => bless( { 'Count' => 3 }, 'Win32::OLE' ), 'Properties_' => bless( { 'Count' => 1 }, 'Win32::OLE' ), 'Methods_' => bless( { 'Count' => 15 }, 'Win32::OLE' ), 'Derivation_' => undef, 'Path_' => bless( { 'Path' => '\\\\V-CHRDIE1\\ROOT\\w +mi:BcdStor e', 'RelPath' => 'BcdStore', 'Server' => 'V-CHRDIE1', 'Namespace' => 'ROOT\\wmi', 'ParentNamespace' => 'ROOT', 'DisplayName' => 'WINMGMTS:{authe +nticationL evel=pktPrivacy,impersonationLevel=impersonate,(Backup,Restore)}!\\\\V +-CHRDIE1\\ ROOT\\wmi:BcdStore', 'Class' => 'BcdStore', 'IsClass' => 1, 'IsSingleton' => 0, 'Keys' => bless( { 'Count' => 0 }, 'Win32::OLE' +), 'Security_' => bless( { 'Imperson +ationLevel ' => 3, 'Authenti +cationLeve l' => 6, 'Privileg +es' => ble ss( { 'Count' => 2 }, 'Win32::OLE' ) }, 'Win32:: +OLE' ), 'Locale' => '', 'Authority' => '' }, 'Win32::OLE' ), 'Security_' => bless( { 'ImpersonationLevel' => 3, 'AuthenticationLevel' => 6, 'Privileges' => bless( { 'Cou +nt' => 2 }, 'Wi +n32::OLE' ) }, 'Win32::OLE' ), 'SystemProperties_' => bless( { 'Count' => 10 }, 'Win32::OLE' ) }, 'Win32::OLE' );
Re: Perl - WMI - BCD
by ww (Archbishop) on Jul 08, 2008 at 01:44 UTC
    This may not help much, but reading the Win32::OLE yields this nugget:
    Warn     This variable determines the behavior of the Win32::OLE modulewhen an error happens. Valid values are:
    0 Ignore error, return undef
    1 Carp::carp if $^W is set (-w option)
    2 always Carp::carp
    3 Carp::croak

    The error number and message (without Carp line/module info) are available through the "Win32::OLE-"LastError> class method.

    Alternatively the Warn option can be set to a CODE reference.
    E.g.

    Win32::OLE->Option(Warn => 3); is equivalent to Win32::OLE->Option(Warn => \&Carp::croak); This can even be used to emulate the VisualBasic "On Error Goto Label" + construct: Win32::OLE->Option(Warn => sub {goto CheckError}); # ... your normal OLE code here ... CheckError: # ... your error handling code here ...

    So, firing up an w32 box (w2k) and adding a shebang, #!C:/perl/bin -w, this is the output:

    F:\_wo\pl_test>perl 696125.pl Win32::OLE(0.1701) error 0x80041002 after character 0 in "winmgmts:{impersonationlevel=impersonate,(Backup,Restore)}\\localhost +\root\wmi:BcdStore" at 696125.pl line 14 eval {...} called at 696125.pl line 14 Can't call method "OpenStore" on an undefined value at 696125.pl line +16.

    And, compounding my demonstration of iggerance, as applied to your comment,

    It looks like the previous line openstore is not assigning the store to $bcdst

    I don't see how the openstore line would assign a value to a var declared without a value at your line 15.

    UpdateFixed code tags

      I seem to recall (but can't quickly find examples) that Win32::OLE can do funny stuff where it sets variables passed into its functions to be references to stuff. The openstore line is very likely correct in that respect.


      Perl is environmentally friendly - it saves trees
      As this is attempting to access the BCD this script will only work on W2K8 and Windows Vista.

        From technet's troubleshooting help" in the subhead, "My script doesn’t return any data," (and possibly related to your OS vs what I have available, but maybe not):

        Note. Instead of an error 0x80041010, you might get error 0x80041002 (“Object could not be found”) or error 0x80041006 (“Insufficient memory”) when trying to connect to a nonexistent class.