Win32_ACE represents a single Access Control Entry (ACE) which works like a key in a keyring: each ACE defines a security principal (like a user account or security group) and a set of permission flags. This ACE (“key”) can then be added to a Access Control List (ACL, “key ring”) which is part of a Win32_SecurityDescriptor. Security descriptors can then be attached to securable objects such as files, folders, shares, or other items that have a Access Control List (ACL).
Because of this, it makes absolutely no sense to query for instances of this class. This always yields nothing. Instances of Win32_ACE are not freely floating around.
Instead, most securable objects provide the methods GetSecurityDescriptor() and SetSecurityDescriptor() to read and write security descriptors.
When you read a security descriptor, you can examine its properties DACL (Discretionary Access Control List, Permissions) and SACL (Security Access Control List, Auditing). Both are arrays of Win32_ACE.
To write or change permissions, get the original security descriptor and add or remove instances of Win32_ACE in DACL or SACL. To add new instances of Win32_ACE, you need to create new instances via New-CimInstance
.
The following item types can be secured via WMI and Win32_ACE:
- Registry Keys: Windows Registry information is accessible via static methods of the class StdRegProv. This class also provides GetSecurityDescriptor() and SetSecurityDescriptor().
- Printers: Printers are represented by Win32_Printer instances. These instances come with GetSecurityDescriptor() and SetSecurityDescriptor().
- Services: Services are represented by Win32_Service. These instances come with GetSecurityDescriptor() and SetSecurityDescriptor().
- Files: File and folder access security is controlled by instances of Win32_LogicalFileSecuritySetting rather than CIM_DataFile or Win32_Directory. You can access these class instances via associations from an instance of CIM_DataFile or Win32_Directory.
- Shares: Network share access security is controlled by instances of Win32_LogicalShareSecuritySetting rather than Win32_Share. You can access these class instances via associations from an instance of Win32_Share.
In addition, there are a few internal areas that can be secured via Win32_ACE (however this is rather uncommon):
- WMI Namespaces: Access to WMI namespaces can be secured via instances of __SystemSecurity classes. These classes have a GetSecurityDescriptor() and SetSecurityDescriptor() methods. Securing WMI namespace is not a common scenario, though.
- DCOM Applications: DCOM (Distributed COM) is a remoting technique that was replaced by the more secure and simple WsMan but is still being used in many environments. DCOM applications are represented by instances of Win32_DCOMApplicationSetting. There are methods to read and write the various security descriptors used by DCOM applications, such as GetAccessSecurityDescriptor, GetConfigurationSecurityDescriptor and GetLaunchSecurityDescriptor.
Methods
Win32_ACE has no methods.
Properties
Win32_ACE returns 7 properties:
'AccessMask','AceFlags','AceType','GuidInheritedObjectType','GuidObjectType',
'TIME_CREATED','Trustee'
Unless explicitly marked as WRITEABLE, all properties are read-only.
AccessMask
Bit flags that indicate rights granted or denied to the trustee.
AccessMask returns a numeric value. To translate it into a meaningful text, use any of the following approaches:
Use Update-Type
Update-Type
tells PowerShell how to interpret the property. This command needs to be executed only once per PowerShell session:
Update-TypeData -MemberName AccessMask -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_ace" -MemberType ScriptProperty -Value {
[Flags()] Enum EnumAccessMask
{
READDATA_LISTDIRECTORY = 1
WRITEDATA_ADDFILE = 2
APPENDDATA_ADDSUBDIR = 4
READEA = 8
WRITEEA = 16
EXECUTE_TRAVERSE = 32
DELETECHILD = 64
READATTRIBUTES = 128
WRITEATTRIBUTES = 256
UNKNOWN512 = 512
UNKNOWN1024 = 1024
UNKNOWN2048 = 2048
UNKNOWN4196 = 4096
UNKNOWN8192 = 8192
UNKNOWN16384 = 16384
UNKNOWN32768 = 32768
DELETE = 65536
READCONTROL = 131072
WRITEDAC = 262144
WRITEOWNER = 524288
SYNCHRONIZE = 1048576
UNKNOWN2097152 = 2097152
UNKNOWN4194304 = 4194304
UNKNOWN8388608 = 8388608
}
[EnumAccessMask]($this.PSBase.CimInstanceProperties['AccessMask'].Value)
} -Force
Get-CimInstance -ClassName Win32_ACE | Select-Object -Property AccessMask
Use Select-Object
Select-Object
supports calculated properties. When you submit a hashtable, PowerShell dynamically calculates the result:
$AccessMask = @{
Name = 'AccessMaskText'
Expression = {
[Flags()] Enum EnumAccessMask
{
READDATA_LISTDIRECTORY = 1
WRITEDATA_ADDFILE = 2
APPENDDATA_ADDSUBDIR = 4
READEA = 8
WRITEEA = 16
EXECUTE_TRAVERSE = 32
DELETECHILD = 64
READATTRIBUTES = 128
WRITEATTRIBUTES = 256
UNKNOWN512 = 512
UNKNOWN1024 = 1024
UNKNOWN2048 = 2048
UNKNOWN4196 = 4096
UNKNOWN8192 = 8192
UNKNOWN16384 = 16384
UNKNOWN32768 = 32768
DELETE = 65536
READCONTROL = 131072
WRITEDAC = 262144
WRITEOWNER = 524288
SYNCHRONIZE = 1048576
UNKNOWN2097152 = 2097152
UNKNOWN4194304 = 4194304
UNKNOWN8388608 = 8388608
}
[EnumAccessMask][int]$_.AccessMask
}
}
Get-CimInstance -ClassName Win32_ACE | Select-Object -Property Caption, AccessMask, $AccessMask
Use a PowerShell Hashtable
You can use a PowerShell hashtable to decode numeric values. Use a hashtable like this one:
$AccessMask_map = @{
1 = 'READDATA_LISTDIRECTORY'
2 = 'WRITEDATA_ADDFILE'
4 = 'APPENDDATA_ADDSUBDIR'
8 = 'READEA'
16 = 'WRITEEA'
32 = 'EXECUTE_TRAVERSE'
64 = 'DELETECHILD'
128 = 'READATTRIBUTES'
256 = 'WRITEATTRIBUTES'
512 = 'UNKNOWN512'
1024 = 'UNKNOWN1024'
2048 = 'UNKNOWN2048'
4096 = 'UNKNOWN4196'
8192 = 'UNKNOWN8192'
16384 = 'UNKNOWN16384'
32768 = 'UNKNOWN32768'
65536 = 'DELETE'
131072 = 'READCONTROL'
262144 = 'WRITEDAC'
524288 = 'WRITEOWNER'
1048576 = 'SYNCHRONIZE'
2097152 = 'UNKNOWN2097152'
4194304 = 'UNKNOWN4194304'
8388608 = 'UNKNOWN8388608'
}
Use Enum structure
You can cast the raw property values to a new enum type to translate raw numeric values into friendly text. Use an enum like this one:
[Flags()] Enum EnumAccessMask
{
READDATA_LISTDIRECTORY = 1
WRITEDATA_ADDFILE = 2
APPENDDATA_ADDSUBDIR = 4
READEA = 8
WRITEEA = 16
EXECUTE_TRAVERSE = 32
DELETECHILD = 64
READATTRIBUTES = 128
WRITEATTRIBUTES = 256
UNKNOWN512 = 512
UNKNOWN1024 = 1024
UNKNOWN2048 = 2048
UNKNOWN4196 = 4096
UNKNOWN8192 = 8192
UNKNOWN16384 = 16384
UNKNOWN32768 = 32768
DELETE = 65536
READCONTROL = 131072
WRITEDAC = 262144
WRITEOWNER = 524288
SYNCHRONIZE = 1048576
UNKNOWN2097152 = 2097152
UNKNOWN4194304 = 4194304
UNKNOWN8388608 = 8388608
}
AceFlags
Bit flags that specify inheritance of the ACE.
AceFlags returns a numeric value. To translate it into a meaningful text, use any of the following approaches:
Use Update-Type
Update-Type
tells PowerShell how to interpret the property. This command needs to be executed only once per PowerShell session:
Update-TypeData -MemberName AceFlags -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_ace" -MemberType ScriptProperty -Value {
[Flags()] Enum EnumAceFlags
{
OBJECT_INHERIT = 1
CONTAINER_INHERIT = 2
NO_PROPAGATE_INHERIT = 4
ACE_ONLY_INHERIT = 8
INHERITED = 16
RESERVED_32 = 32
SUCCESSFUL_ACCESS = 64
FAILED_ACCESS = 128
}
[EnumAceFlags]($this.PSBase.CimInstanceProperties['AceFlags'].Value)
} -Force
Get-CimInstance -ClassName Win32_ACE | Select-Object -Property AceFlags
Use Select-Object
Select-Object
supports calculated properties. When you submit a hashtable, PowerShell dynamically calculates the result:
$AceFlags = @{
Name = 'AceFlagsText'
Expression = {
[Flags()] Enum EnumAceFlags
{
OBJECT_INHERIT = 1
CONTAINER_INHERIT = 2
NO_PROPAGATE_INHERIT = 4
ACE_ONLY_INHERIT = 8
INHERITED = 16
RESERVED_32 = 32
SUCCESSFUL_ACCESS = 64
FAILED_ACCESS = 128
}
[EnumAceFlags][int]$_.AceFlags
}
}
Get-CimInstance -ClassName Win32_ACE | Select-Object -Property Caption, AceFlags, $AceFlags
Use a PowerShell Hashtable
You can use a PowerShell hashtable to decode numeric values. Use a hashtable like this one:
$AceFlags_map = @{
1 = 'OBJECT_INHERIT'
2 = 'CONTAINER_INHERIT'
4 = 'NO_PROPAGATE_INHERIT'
8 = 'ACE_ONLY_INHERIT'
16 = 'INHERITED'
32 = 'RESERVED_32'
64 = 'SUCCESSFUL_ACCESS'
128 = 'FAILED_ACCESS'
}
Use Enum structure
You can cast the raw property values to a new enum type to translate raw numeric values into friendly text. Use an enum like this one:
[Flags()] Enum EnumAceFlags
{
OBJECT_INHERIT = 1
CONTAINER_INHERIT = 2
NO_PROPAGATE_INHERIT = 4
ACE_ONLY_INHERIT = 8
INHERITED = 16
RESERVED_32 = 32
SUCCESSFUL_ACCESS = 64
FAILED_ACCESS = 128
}
AceType
Type of ACE.
AceType returns a numeric value. To translate it into a meaningful text, use any of the following approaches:
Use Update-Type
Update-Type
tells PowerShell how to interpret the property. This command needs to be executed only once per PowerShell session:
Update-TypeData -MemberName AceType -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_ace" -MemberType ScriptProperty -Value {
Enum EnumAceType
{
Access_Allowed = 0
Access_Denied = 1
Audit = 2
}
[EnumAceType]($this.PSBase.CimInstanceProperties['AceType'].Value)
} -Force
Get-CimInstance -ClassName Win32_ACE | Select-Object -Property AceType
Use Select-Object
Select-Object
supports calculated properties. When you submit a hashtable, PowerShell dynamically calculates the result:
$AceType = @{
Name = 'AceTypeText'
Expression = {
$value = $_.AceType
switch([int]$value)
{
0 {'Access Allowed'}
1 {'Access Denied'}
2 {'Audit'}
default {"$value"}
}
}
}
Get-CimInstance -ClassName Win32_ACE | Select-Object -Property Caption, AceType, $AceType
Use a PowerShell Hashtable
You can use a PowerShell hashtable to decode numeric values. Use a hashtable like this one:
$AceType_map = @{
0 = 'Access Allowed'
1 = 'Access Denied'
2 = 'Audit'
}
Use Enum structure
You can cast the raw property values to a new enum type to translate raw numeric values into friendly text. Use an enum like this one:
Enum EnumAceType
{
Access_Allowed = 0
Access_Denied = 1
Audit = 2
}
GuidInheritedObjectType
Globally unique identifier (GUID) associated with the parent of the object to which these rights apply.
GuidObjectType
GUID associated with the type of object to which these rights apply.
TIME_CREATED
The time, in the CIM_DATETIME format, when the security descriptor was created.
Trustee
WRITEABLE MANAGEMENTBASEOBJECT
Object representing the user account, group account, or logon session to which an ACE applies.
CDXML Definition
You can turn this WMI class and its methods into PowerShell cmdlets by importing below CDXML file (Cmdlet Definition XML) as a module.
Create Win32_ACE.cdxml
$folder = "c:\wmi\Win32_ACE"
$cdxmlPath = Join-Path -Path $folder -ChildPath "Win32_ACE.cdxml"
# create folder if not present:
$exists = Test-Path -Path $folder
if (!$exists) { $null = New-Item -Path $folder -ItemType Directory }
# write file
$content = @'
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is licensed under 'Attribution 4.0 International' license (https://creativecommons.org/licenses/by/4.0/).
You can free of charge use this code in commercial and non-commercial code, and you can freely modify and adjust the code
as long as you give appropriate credit to the original author Dr. Tobias Weltner.
This material was published and is maintained here:
https://powershell.one/wmi/root/cimv2/win32_ace#cdxml-definition
-->
<PowerShellMetadata xmlns="http://schemas.microsoft.com/cmdlets-over-objects/2009/11">
<!--referencing the WMI class this cdxml uses-->
<Class ClassName="Root/CIMV2\Win32_ACE" ClassVersion="2.0">
<Version>1.0</Version>
<!--default noun used by Get-cmdlets and when no other noun is specified. By convention, we use the prefix "WMI" and the base name of the WMI class involved. This way, you can easily identify the underlying WMI class.-->
<DefaultNoun>WmiACE</DefaultNoun>
<!--define the cmdlets that work with class instances.-->
<InstanceCmdlets>
<!--query parameters to select instances. This is typically empty for classes that provide only one instance-->
<GetCmdletParameters />
<!--defining additional cmdlets that modifies instance properties-->
<!--Set-ACE: modifying instance properties-->
<Cmdlet>
<!--defining the ConfirmImpact which indicates how severe the changes are that this cmdlet performs-->
<CmdletMetadata Verb="Set" ConfirmImpact="Low" />
<!--using internal method to modify instance:-->
<Method MethodName="cim:ModifyInstance">
<!--defining the parameters of this cmdlet:-->
<Parameters>
<Parameter ParameterName="AccessMask">
<!--the underlying parameter type is uint32 which really is the enumeration [Win32_ACE.AccessMask] that is defined below in the Enums node:-->
<Type PSType="Win32_ACE.AccessMask" />
<CmdletParameterMetadata IsMandatory="false">
<ValidateNotNull />
<ValidateNotNullOrEmpty />
</CmdletParameterMetadata>
</Parameter>
<Parameter ParameterName="AceFlags">
<!--the underlying parameter type is uint32 which really is the enumeration [Win32_ACE.AceFlags] that is defined below in the Enums node:-->
<Type PSType="Win32_ACE.AceFlags" />
<CmdletParameterMetadata IsMandatory="false">
<ValidateNotNull />
<ValidateNotNullOrEmpty />
</CmdletParameterMetadata>
</Parameter>
<Parameter ParameterName="AceType">
<!--the underlying parameter type is uint32 which really is the enumeration [Win32_ACE.AceType] that is defined below in the Enums node:-->
<Type PSType="Win32_ACE.AceType" />
<CmdletParameterMetadata IsMandatory="false">
<ValidateNotNull />
<ValidateNotNullOrEmpty />
</CmdletParameterMetadata>
</Parameter>
<Parameter ParameterName="GuidInheritedObjectType">
<!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
<Type PSType="system.string" />
<CmdletParameterMetadata IsMandatory="false">
<ValidateNotNull />
<ValidateNotNullOrEmpty />
</CmdletParameterMetadata>
</Parameter>
<Parameter ParameterName="GuidObjectType">
<!--the underlying parameter type is string which corresponds to the PowerShell .NET type [system.string]-->
<Type PSType="system.string" />
<CmdletParameterMetadata IsMandatory="false">
<ValidateNotNull />
<ValidateNotNullOrEmpty />
</CmdletParameterMetadata>
</Parameter>
<Parameter ParameterName="Trustee">
<!--the underlying parameter type is Win32_Trustee which corresponds to the PowerShell .NET type [System.Management.ManagementBaseObject]-->
<Type PSType="System.Management.ManagementBaseObject" />
<CmdletParameterMetadata IsMandatory="false">
<ValidateNotNull />
<ValidateNotNullOrEmpty />
</CmdletParameterMetadata>
</Parameter>
</Parameters>
</Method>
</Cmdlet>
</InstanceCmdlets>
</Class>
<!--defining enumerations-->
<Enums>
<Enum EnumName="Win32_ACE.AccessMask" UnderlyingType="system.uint32" BitwiseFlags="true">
<Value Name="READDATALISTDIRECTORY" Value="1" />
<Value Name="WRITEDATAADDFILE" Value="2" />
<Value Name="APPENDDATAADDSUBDIR" Value="4" />
<Value Name="READEA" Value="8" />
<Value Name="WRITEEA" Value="16" />
<Value Name="EXECUTETRAVERSE" Value="32" />
<Value Name="DELETECHILD" Value="64" />
<Value Name="READATTRIBUTES" Value="128" />
<Value Name="WRITEATTRIBUTES" Value="256" />
<Value Name="UNKNOWN512" Value="512" />
<Value Name="UNKNOWN1024" Value="1024" />
<Value Name="UNKNOWN2048" Value="2048" />
<Value Name="UNKNOWN4196" Value="4096" />
<Value Name="UNKNOWN8192" Value="8192" />
<Value Name="UNKNOWN16384" Value="16384" />
<Value Name="UNKNOWN32768" Value="32768" />
<Value Name="DELETE" Value="65536" />
<Value Name="READCONTROL" Value="131072" />
<Value Name="WRITEDAC" Value="262144" />
<Value Name="WRITEOWNER" Value="524288" />
<Value Name="SYNCHRONIZE" Value="1048576" />
<Value Name="UNKNOWN2097152" Value="2097152" />
<Value Name="UNKNOWN4194304" Value="4194304" />
<Value Name="UNKNOWN8388608" Value="8388608" />
</Enum>
<Enum EnumName="Win32_ACE.AceFlags" UnderlyingType="system.uint32" BitwiseFlags="true">
<Value Name="OBJECTINHERIT" Value="1" />
<Value Name="CONTAINERINHERIT" Value="2" />
<Value Name="NOPROPAGATEINHERIT" Value="4" />
<Value Name="ACEONLYINHERIT" Value="8" />
<Value Name="INHERITED" Value="16" />
<Value Name="RESERVED32" Value="32" />
<Value Name="SUCCESSFULACCESS" Value="64" />
<Value Name="FAILEDACCESS" Value="128" />
</Enum>
<Enum EnumName="Win32_ACE.AceType" UnderlyingType="system.uint32">
<Value Name="AccessAllowed" Value="0" />
<Value Name="AccessDenied" Value="1" />
<Value Name="Audit" Value="2" />
</Enum>
</Enums>
</PowerShellMetadata>
'@ | Set-Content -LiteralPath $cdxmlPath -Encoding UTF8
# import module
Import-Module -Name $cdxmlPath -Force -Verbose
# list new cmdlets
Get-Command -Module "Win32_ACE"
See here for more information on CDXML and CDXML-based PowerShell modules.
Type Extensions for PowerShell
You can automatically improve properties of class instances by using a types.ps1xml file.
Create Win32_ACE.Types.ps1xml
$folder = "c:\wmi\Win32_ACE"
$typesPath = Join-Path -Path $folder -ChildPath "Win32_ACE.Types.ps1xml"
# create folder if not present:
$exists = Test-Path -Path $folder
if (!$exists) { $null = New-Item -Path $folder -ItemType Directory }
# write file
$content = @'
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is licensed under 'Attribution 4.0 International' license (https://creativecommons.org/licenses/by/4.0/).
You can free of charge use this code in commercial and non-commercial code, and you can freely modify and adjust the code
as long as you give appropriate credit to the original author Dr. Tobias Weltner.
This material was published and is maintained here:
https://powershell.one/wmi/root/cimv2/win32_ace#typesps1xml-file
-->
<Types>
<Type>
<!--@
Applicable type. This type is produced by Get-CimInstance.
To extend instances produced by Get-WmiObject, change the type name to:
System.Management.ManagementObject#root/cimv2\Win32_ACE
@-->
<Name>Microsoft.Management.Infrastructure.CimInstance#Root/CIMV2/Win32_ACE</Name>
<Members>
<ScriptProperty>
<Name>AccessMask</Name>
<!--casting raw content to a enum. This translates numeric values to friendly text while leaving the original property value untouched:-->
<GetScriptBlock>[Microsoft.PowerShell.Cmdletization.GeneratedTypes.Win32_ACE.AccessMask]($this.PSBase.CimInstanceProperties['AccessMask'].Value)</GetScriptBlock>
</ScriptProperty>
<ScriptProperty>
<Name>AceType</Name>
<!--casting raw content to a enum. This translates numeric values to friendly text while leaving the original property value untouched:-->
<GetScriptBlock>[Microsoft.PowerShell.Cmdletization.GeneratedTypes.Win32_ACE.AceType]($this.PSBase.CimInstanceProperties['AceType'].Value)</GetScriptBlock>
</ScriptProperty>
<ScriptProperty>
<Name>AceFlags</Name>
<!--casting raw content to a enum. This translates numeric values to friendly text while leaving the original property value untouched:-->
<GetScriptBlock>[Microsoft.PowerShell.Cmdletization.GeneratedTypes.Win32_ACE.AceFlags]($this.PSBase.CimInstanceProperties['AceFlags'].Value)</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
</Types>
'@ | Set-Content -LiteralPath $typesPath -Encoding UTF8
# import type definition
Update-TypeData -PrependPath $typesPath
Note: Win32_ACE.Types.ps1xml is using enumerations defined in ClassName.cdxml which are available only when you imported the .cdxml file via
Import-Module
.
Or, you can manually update the PowerShell type database using Update-TypeData
.
View Update-TypeData
commands for Win32_ACE properties
Update-TypeData -MemberName AccessMask -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_ace" -MemberType ScriptProperty -Value {
[Flags()] Enum EnumAccessMask
{
READDATA_LISTDIRECTORY = 1
WRITEDATA_ADDFILE = 2
APPENDDATA_ADDSUBDIR = 4
READEA = 8
WRITEEA = 16
EXECUTE_TRAVERSE = 32
DELETECHILD = 64
READATTRIBUTES = 128
WRITEATTRIBUTES = 256
UNKNOWN512 = 512
UNKNOWN1024 = 1024
UNKNOWN2048 = 2048
UNKNOWN4196 = 4096
UNKNOWN8192 = 8192
UNKNOWN16384 = 16384
UNKNOWN32768 = 32768
DELETE = 65536
READCONTROL = 131072
WRITEDAC = 262144
WRITEOWNER = 524288
SYNCHRONIZE = 1048576
UNKNOWN2097152 = 2097152
UNKNOWN4194304 = 4194304
UNKNOWN8388608 = 8388608
}
[EnumAccessMask]($this.PSBase.CimInstanceProperties['AccessMask'].Value)
} -Force
Update-TypeData -MemberName AceFlags -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_ace" -MemberType ScriptProperty -Value {
[Flags()] Enum EnumAceFlags
{
OBJECT_INHERIT = 1
CONTAINER_INHERIT = 2
NO_PROPAGATE_INHERIT = 4
ACE_ONLY_INHERIT = 8
INHERITED = 16
RESERVED_32 = 32
SUCCESSFUL_ACCESS = 64
FAILED_ACCESS = 128
}
[EnumAceFlags]($this.PSBase.CimInstanceProperties['AceFlags'].Value)
} -Force
Update-TypeData -MemberName AceType -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_ace" -MemberType ScriptProperty -Value {
Enum EnumAceType
{
Access_Allowed = 0
Access_Denied = 1
Audit = 2
}
[EnumAceType]($this.PSBase.CimInstanceProperties['AceType'].Value)
} -Force
Requirements
To use Win32_ACE, the following requirements apply:
PowerShell
Get-CimInstance
was introduced with PowerShell Version 3.0, which in turn was introduced on clients with Windows 8 and on servers with Windows Server 2012.
If necessary, update Windows PowerShell to Windows PowerShell 5.1, or install PowerShell 7 side-by-side.
Operating System
Win32_ACE was introduced on clients with Windows Vista and on servers with Windows Server 2008.
Namespace
Win32_ACE lives in the namespace root/cimv2. This is the default namespace. There is no need to use the -Namespace parameter in Get-CimInstance
.
Implementation
Win32_ACE is implemented in CIMWin32.dll and defined in Secrcw32.mof. Both files are located in the folder C:\Windows\system32\wbem
:
explorer $env:windir\system32\wbem
notepad $env:windir\system32\wbem\Secrcw32.mof