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
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