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

Hi, Can you help with a Win32::OLE WMI question please. I know WMI and the module fairly well, but have run aground on something that must be fairly simple, if only I could see it. I'm trying to convert this VB to perl.
Set wmiFileSecSetting = GetObject ("winmgmts:Win32_LogicalFileSecurity +Setting.path='d:\\programming'") RetVal = wmiFileSecSetting.GetSecurityDescriptor(wmiSecurityDescriptor +)
Here's what I think should work.
use Win32::OLE; $wmiFileSecSetting = Win32::OLE->GetObject("winmgmts:Win32_LogicalFile +SecuritySetting.path='d:\\programming'"); $RetVal = $wmiFileSecSetting->GetSecurityDescriptor($wmiSecurityDescri +ptor);
but it doesn't. $RetVal is returned as a success status, but the object returned from GetSecurityDescriptor is recognised by Data::Dumper as an empty hash. The VB works and returns an object with content. ...Thanks.

Replies are listed 'Best First'.
Re: Win32::OLE and WMI
by Courage (Parson) on Feb 02, 2004 at 12:20 UTC
    Here is my tested similar script, so you can learn by example.
    (please ignore irrelevant non-English comments there)
    use Win32::OLE; $ADsPath = "WinNT://VAD/lanmanserver"; $c = Win32::OLE->GetObject($ADsPath) or die "Невозможно получить $ADsP +ath\n"; $s = $c->Create("fileshare",'ddd-doom'); $s->{path} = 'C:\DOOM2'; $s->{description} = "This is a Perl created share"; $s->SetInfo();
    ... and another one ...
    use Win32::OLE; $ADsPath = "WinNT://RU0028/VAD,computer"; $c = Win32::OLE->GetObject($ADsPath) or die "Невозможно получить $ADsP +ath\n"; # создаем и возвращаем объект User $u = $c->Create("user","xx"); $u->SetInfo(); # нужно создать пользователя, перед тем как менять зна +чения # в пространстве имен WinNT: пробел между "Full" и "Name" недопустим $u->{FullName} = "XXX-user!"; $su->SetInfo();

    Courage, the Cowardly Dog

      Thanks for your reply. You've demonstrated how to create a share, and I have no difficulty with this, myself. My problem is with retrieving the security descriptor for an existing share or file via the GetSecurityDescriptor method. Have you ever tried this yourself?
        It is easy to change my script to do the reverse:
        use Win32::OLE; $ADsPath = "WinNT://VAD-MM/lanmanserver"; $c = Win32::OLE->GetObject($ADsPath) or die "Невозможно получить $ADsP +ath\n"; print map {"[$_->{path}=$_->{description}]\n"} in $c;
        outputs on my machine "vad-mm" (you should substitute your machine of interest there of course)
        [C:\=] [D:\=]
        I am not WMI expert and do not know how to use GetSecurityDescriptor method without reading proper documentation, but I do know that an example shown by me uses WMI and may be it could solve your problem as well?

        Let me know if something should be clarified better.

        Courage, the Cowardly Dog

Re: Win32::OLE and WMI
by maa (Pilgrim) on Feb 02, 2004 at 12:33 UTC

    Hi, grmm2
    I suspect you just need to be more explicit in what you ask WMI for.

    Your VB is interpreted as a WQL Where clause. It's unlikely Win32::OLE will interpret it the same way.

    If I were you I'd create my WMI handle and use the $wmi->ExecQuery("SELECT * FROM Win32_LogicalFileSecuritySetting WHERE path='d:\\programming'")

    HTH - mark

      You mean like this...
      use Win32::OLE; use Data::Dumper; $wmi = Win32::OLE->GetObject('winmgmts:root/cimv2'); $query = 'SELECT * FROM Win32_LogicalFileSecuritySetting WHERE Path="d +:\\\\Programming"'; $resultset = $wmi->ExecQuery($query); foreach $obj (in $resultset) { $rc = $obj->GetSecurityDescriptor($sec); print "Path=[$obj->{Path}] rc=[$rc]\n"; print Data::Dumper->Dump([$sec], [qw(*sec)]); }
      No luck there either, I'm afraid :-( The output from the above code is...
      Path=[d:\Programming] rc=[0] $sec = undef;

        I tried this... but it just hangs!

        my $stuff =Win32::OLE->GetObject( "WinMgmts:!Win32_LogicalFileSecuritySetting.path='C:\\\\TEMP'" );
        I'll be interested to see what the final solution is!

        Note: The VBScript Example from MSDN hangs on my PC too. NT4 SP6a. Weird

Re: Win32::OLE and WMI
by Courage (Parson) on Feb 03, 2004 at 11:33 UTC
    Okay, given all specualtions that were in this thread here is the code that works and solves your problem:
    use Win32::OLE; use Win32::OLE::Variant; $wmiFileSecSetting = Win32::OLE->GetObject("winmgmts:Win32_LogicalFile +SecuritySetting.path='E:\\VK'"); my $wmiSecurityDescriptor = Win32::OLE->GetObject('winmgmts:Win32_Secu +rityDescriptor'); my $v = Variant(VT_DISPATCH|VT_BYREF,$wmiSecurityDescriptor); $RetVal = $wmiFileSecSetting->GetSecurityDescriptor($v); print "$RetVal;[".$v->Get->{Owner}->{Name}."]";
    BTW documentation inside Win32::OLE::Variant tells us how to use "byval" in Win32::OLE.

    Courage, the Cowardly Dog

      That's great. I wondered if OLE::Variant was implicated in some way, but frankly its documentation could be enhanced for those at intermediate level like me. Now you've pointed that out, I've been able to get the DACL's out which was my main aim all along. Thanks.
      use Win32::OLE; use Win32::OLE::Variant; $wmiFileSecSetting = Win32::OLE->GetObject("winmgmts:Win32_LogicalFile +SecuritySetting.path='D:\\Programming\\test\\a.pl'"); my $wmiSecurityDescriptor = Win32::OLE->GetObject('winmgmts:Win32_Secu +rityDescriptor'); my $v = Variant(VT_DISPATCH|VT_BYREF,$wmiSecurityDescriptor); $RetVal = $wmiFileSecSetting->GetSecurityDescriptor($v); foreach my $ace (@{$v->Value->{DACL}}) { print $ace->{Trustee}->{Domain}.'\\'.$ace->{Trustee}->{Name}.': '. +$ace->{AccessMask}."\n"; }
Re: Win32::OLE and WMI
by NetWallah (Canon) on Feb 02, 2004 at 23:31 UTC
    Just hazarding a guess here, but since the VB requires the double-backslash (Verified in the MSDN Document), wouldn't you need 4 backslashes in perl, since 2 get eaten in Intrapolation ?
    $wmiFileSecSetting = Win32::OLE->GetObject("winmgmts:Win32_LogicalFi +leSecuritySetting.path='d:\\\\programming'");

    "When you are faced with a dilemma, might as well make dilemmanade. "

      Good point. I've just tried 2 backslashes and then 4, and get almost the same result. A $wmiFileSecSetting object in each case but Data::Dumper shows it in two different ways. 2 backslashes - 'Path' => '\\\\PCCS023\\root\\cimv2:Win32_LogicalFileSecuritySetting.Path="d:\\\\programming"' 4 backslashes: 'Path' => '\\\\PCCS023\\root\\cimv2:Win32_LogicalFileSecuritySetting.Path="d:\\\\\\\\programming"'