Search code examples
powershellwmipowershell-4.0wmi-query

Why am I getting a Critical Error when creating a WMI Instance?


I have a script that is intended to create instances of a custom WMI class based on an ACL output converted to a string. This is ultimately to query permissions via that WMI class.

The meat of the process is:

    [cmdletbinding()] 


param([Parameter(ValueFromPipeline=$True, 
    ValueFromPipelineByPropertyName=$True)]$Computer = '.')  

$shares = gwmi -Class win32_share -ComputerName $computer | select -ExpandProperty Name  

foreach ($share in $shares) {  
    $acl = $null  
    #Write-Host $share -ForegroundColor Green  
    #Write-Host $('-' * $share.Length) -ForegroundColor Green  

    $objShareSec = Get-WMIObject -Class Win32_LogicalShareSecuritySetting -Filter "name='$Share'"  -ComputerName $computer 

    try {  
        $SD = $objShareSec.GetSecurityDescriptor().Descriptor    

        foreach($ace in $SD.DACL){  

            $UserName = $ace.Trustee.Name      
            If ($ace.Trustee.Domain -ne $Null) {$UserName = "$($ace.Trustee.Domain)\$UserName"}    
            If ($ace.Trustee.Name -eq $Null) {$UserName = $ace.Trustee.SIDString }     

            [Array]$ACL += New-Object Security.AccessControl.FileSystemAccessRule($UserName, $ace.AccessMask, $ace.AceType)



            for( $i = 1; $i -lt $ACL.Length; $i++)
            {
              $permission = $ACL[$i] | Out-String

              Write-Host "permission for $share is $permission"

              Set-WmiInstance -Class TestShare -Puttype CreateOnly -Argument @{Name = $share; Permissions = $permission}
            }


            } #end foreach ACE            
        } # end try  
    catch  
        { 
        Write-host "Failed to create or update instance for share $share"
        Write-Host ""       
         }  
    #$ACL  
   # Write-Host $('=' * 50)  
    } # end foreach $share

Which returns the below error:

    Set-WmiInstance : Critical error 
At ...\GetShares.ps1:35 char:15
+ ... Set-WmiInstance -Class LDLocalShare -Puttype CreateOnly - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Set-WmiInstance], ManagementException
    + FullyQualifiedErrorId : SetWMIManagementException,Microsoft.PowerShell.Commands.SetWmiInstance

There seems to be an issue with the way I'm converting Security.AccessControl.FileSystemAccessRule to a string, because using the code below and providing literal strings creates an instance without issue, with the appropriate values:

Set-WmiInstance -Class TestShare -Puttype CreateOnly -Argument @{Name = "TestShare" ; Permissions = "TestPermission"}

I've looked around on technet forum posts related to the error returned, but the issue always seems to be with trying to create an instance of a class that wasn't created. The class is definitely there. Is there some way to convert Security.AccessControl.FileSystemAccessRule without running into this, or a different way to store that information in an instance of a custom WMI class?

Edit: Example output of $permission, which gets converted to a string

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : Everyone
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None

Solution

  • To create object ,you can do this by running the below snippet once as administrator :

    $WMI_Class = ""
     $WMI_Class = New-Object System.Management.ManagementClass("Root\cimv2", $null, $null)
     $WMI_Class.name = 'TestShare'
     $WMI_Class.Properties.Add("Name", [System.Management.CimType]::String, $false)
     $WMI_Class.Properties["Name"].Qualifiers.Add("key", $true)
     $WMI_Class.Properties.Add("Permissions", [System.Management.CimType]::String, $false)
     $WMI_Class.Put()
    

    you can test this by creating a dummy object (also should be run as admin):

    Set-WmiInstance -Class TestShare -Puttype CreateOnly -Argument @{Name = 'test';Permissions = 'x'}
    

    Then your code should work fine with this small change for set-wmiinstance:

     Set-WmiInstance -Class TestShare -Puttype CreateOnly -Argument @{Name = $share;Permissions = $permission.Replace("`r`n","`n")}
    

    but ,I have defined share name as key and properties does not have write qualifier .So you won't be able to modify the object later for the same share