如何在 PowerShell 中使用 Windows API AuditEnumerateCategories 函数?
How to use Windows API AuditEnumerateCategories function in PowerShell?
我想使用 PowerShell 获取当前 Advanced Security Audit Policy。我可以使用 auditpol.exe
,但它的输出因 OS 语言而异,这使得它难以解析。
settings are stored in a REG_NONE value in HKEY_Local_Machine\Security\Policy\PolAdtEv
. I could try to parse the value with the help of that unofficial structure table。但是,我的首选方法是使用 advapi32.dll
的 Windows API 函数 AuditQuerySystemPolicy
。
在 this 文章的大力帮助下,我在 PowerShell 中创建了一个类型,如下所示。
$MemberDefinition = @'
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditEnumerateCategories(
out IntPtr ppAuditCategoriesArray,
out uint pCountReturned);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditLookupCategoryName(
ref Guid pAuditCategoryGuid,
out StringBuilder ppszCategoryName);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool AuditEnumerateSubCategories(
ref Guid pAuditCategoryGuid,
bool bRetrieveAllSubCategories,
out IntPtr ppAuditSubCategoriesArray,
out uint pCountReturned);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditLookupSubCategoryName(
ref Guid pAuditSubCategoryGuid,
out StringBuilder ppszSubCategoryName);
[DllImport("advapi32.dll")]
public static extern void AuditFree(
IntPtr buffer);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditQuerySystemPolicy(
Guid pSubCategoryGuids,
uint PolicyCount,
out IntPtr ppAuditPolicy);
'@
$Advapi32 = Add-Type -MemberDefinition $MemberDefinition -Name 'Advapi32' -Namespace 'Win32' -UsingNamespace System.Text -PassThru
类型创建成功,但第一步失败了——获取所有审计类别的 GUID。我有不同类型的问题。例如我试过
$guid = [Guid].MakeByRefType()
$count = [IntPtr]::Zero
[Win32.Advapi32]::AuditEnumerateCategories([ref]$guid, [ref]$count)
# Exception calling "AuditEnumerateCategories" with 2 Arguments: "The value "System.Guid&" of the type "System.RuntimeType" cannot be coverted to "System.IntPtr".
我还尝试将 AuditEnumerateCategories
定义输出从 IntPtr
更改为 Guid
。 ppAuditCategoriesArray
的输出是
A pointer to a single buffer that contains both an array of pointers to GUID structures and the structures themselves.
不幸的是,我不知道如何在 PowerShell 中处理它。
占用一个Marshal.PtrToStructure
Method (.NET
). For instance, PtrToStructure(IntPtr, Type)
将非托管内存块中的数据编组到新分配的指定类型的托管对象,参见以下评论代码片段:
### (unchanged)
### $MemberDefinition = …
### $Advapi32 = Add-Type …
$guid = [System.Int64]::MinValue ### or ### [System.Int64]0
$count = [System.Int32]::MaxValue ### or ### [System.Int64]0
$aux = [Win32.Advapi32]::AuditEnumerateCategories([ref]$guid, [ref]$count)
$guidArr = @() ### array to store GUIDs
$guidPtr = [int64]$guid ### pointer to next GUID
$guidOff = [System.Runtime.InteropServices.Marshal]::SizeOf([type][guid])
$ppszCategoryName = [System.Text.StringBuilder]::new()
for ( $i=0; $i -lt $count; $i++ ) {
$guidAux = [System.Runtime.InteropServices.Marshal]::
PtrToStructure( [System.IntPtr]$guidPtr,[type][guid] )
$guidArr += $guidAux ### update array of GUIDs for future use
$guidPtr += $guidOff ### shift pointer to next GUID
### debugging: try another method of [Win32.Advapi32] Runtime Type
$foo = [Win32.Advapi32]::AuditLookupCategoryName([ref]$guidAux,[ref]$ppszCategoryName)
### debugging: show partial results
Write-Host $('{0} {1,4} {2,4}' -f $guidAux.Guid,
$ppszCategoryName.Capacity, $ppszCategoryName.Length)
}
我想使用 PowerShell 获取当前 Advanced Security Audit Policy。我可以使用 auditpol.exe
,但它的输出因 OS 语言而异,这使得它难以解析。
settings are stored in a REG_NONE value in HKEY_Local_Machine\Security\Policy\PolAdtEv
. I could try to parse the value with the help of that unofficial structure table。但是,我的首选方法是使用 advapi32.dll
的 Windows API 函数 AuditQuerySystemPolicy
。
在 this 文章的大力帮助下,我在 PowerShell 中创建了一个类型,如下所示。
$MemberDefinition = @'
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditEnumerateCategories(
out IntPtr ppAuditCategoriesArray,
out uint pCountReturned);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditLookupCategoryName(
ref Guid pAuditCategoryGuid,
out StringBuilder ppszCategoryName);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool AuditEnumerateSubCategories(
ref Guid pAuditCategoryGuid,
bool bRetrieveAllSubCategories,
out IntPtr ppAuditSubCategoriesArray,
out uint pCountReturned);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditLookupSubCategoryName(
ref Guid pAuditSubCategoryGuid,
out StringBuilder ppszSubCategoryName);
[DllImport("advapi32.dll")]
public static extern void AuditFree(
IntPtr buffer);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool AuditQuerySystemPolicy(
Guid pSubCategoryGuids,
uint PolicyCount,
out IntPtr ppAuditPolicy);
'@
$Advapi32 = Add-Type -MemberDefinition $MemberDefinition -Name 'Advapi32' -Namespace 'Win32' -UsingNamespace System.Text -PassThru
类型创建成功,但第一步失败了——获取所有审计类别的 GUID。我有不同类型的问题。例如我试过
$guid = [Guid].MakeByRefType()
$count = [IntPtr]::Zero
[Win32.Advapi32]::AuditEnumerateCategories([ref]$guid, [ref]$count)
# Exception calling "AuditEnumerateCategories" with 2 Arguments: "The value "System.Guid&" of the type "System.RuntimeType" cannot be coverted to "System.IntPtr".
我还尝试将 AuditEnumerateCategories
定义输出从 IntPtr
更改为 Guid
。 ppAuditCategoriesArray
的输出是
A pointer to a single buffer that contains both an array of pointers to GUID structures and the structures themselves.
不幸的是,我不知道如何在 PowerShell 中处理它。
占用一个Marshal.PtrToStructure
Method (.NET
). For instance, PtrToStructure(IntPtr, Type)
将非托管内存块中的数据编组到新分配的指定类型的托管对象,参见以下评论代码片段:
### (unchanged)
### $MemberDefinition = …
### $Advapi32 = Add-Type …
$guid = [System.Int64]::MinValue ### or ### [System.Int64]0
$count = [System.Int32]::MaxValue ### or ### [System.Int64]0
$aux = [Win32.Advapi32]::AuditEnumerateCategories([ref]$guid, [ref]$count)
$guidArr = @() ### array to store GUIDs
$guidPtr = [int64]$guid ### pointer to next GUID
$guidOff = [System.Runtime.InteropServices.Marshal]::SizeOf([type][guid])
$ppszCategoryName = [System.Text.StringBuilder]::new()
for ( $i=0; $i -lt $count; $i++ ) {
$guidAux = [System.Runtime.InteropServices.Marshal]::
PtrToStructure( [System.IntPtr]$guidPtr,[type][guid] )
$guidArr += $guidAux ### update array of GUIDs for future use
$guidPtr += $guidOff ### shift pointer to next GUID
### debugging: try another method of [Win32.Advapi32] Runtime Type
$foo = [Win32.Advapi32]::AuditLookupCategoryName([ref]$guidAux,[ref]$ppszCategoryName)
### debugging: show partial results
Write-Host $('{0} {1,4} {2,4}' -f $guidAux.Guid,
$ppszCategoryName.Capacity, $ppszCategoryName.Length)
}