我希望将所有具有共享和NTFS权限的Windows共享(不包括系统共享(如C $,D%等))导出到Excel文件中。
我编写了这段代码,需要帮助来添加NTFS权限,然后将其导出为易于阅读的excel格式。
[cmdletbinding()]
param([Parameter(ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True)]$Computer = '.')
$shares = gwmi -Class win32_share -ComputerName $computer | where {$_.name -notlike "*$"} | 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)
} #end foreach ACE
} # end try
catch
{ Write-Host "Unable to obtain permissions for $share" }
$ACL
Write-Host $('=' * 50)
} # end foreach $share
答案 0 :(得分:0)
下面的注释代码段可以完成此任务:
-Credential
对非本地计算机来说Get-WmiObject
所必需的参数(但是用户凭据不能用于本地连接); NTFS
属性的含义(分别将原始0
或1
更改为新的''
和$ShareResource
)。 / li>
Try-Catch
会在部分获得NTFS权限的位置(请根据需要添加)。GetFileSystemRightsExtended
尤其是Access Mask对待可能的通用访问权限。我在文件系统中遇到了这些错误,然后将AccessMask
属性转换为[Security.AccessControl.FileSystemRights]
以及New-Object Security.AccessControl.FileSystemAccessRule(…
方法失败。更新的脚本 HTH :
param([Parameter(ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True)]$Computer = $env:COMPUTERNAME)
Function GetFileSystemRightsExtended ( [uint32]$access )
{
$accessMaskBase = [ordered]@{
[uint32]'0x80000000' = '+GenericRead' ### generic access rights
[uint32]'0x40000000' = '+GenericWrite'
[uint32]'0x20000000' = '+GenericExecute'
[uint32]'0x10000000' = '+GenericAll'
[uint32]'0x02000000' = '+MaximumAllowed' ### unclear: reserved
[uint32]'0x01000000' = '+AccessSystemSecurity'
# ↑↑↑ ↑
# ||| ╘══════ bits 0..15 Object specific access rights
# ||╘════════ bits 16..23 Standard access rights
# |╘═════════ bits 24..27 Reserved (bit 24 = AccessSystemSecurity)
# ╘══════════ bits 28..31 Generic access rights
#
### see also MSDN article "Access Mask Format"
### https://docs.microsoft.com/en-gb/windows/desktop/SecAuthZ/access-mask-format
###
}
$accessAux = $access
$accessGeneric = @()
foreach ($accessMaskKey in $accessMaskBase.Keys ) {
if ( $access -band $accessMaskKey) {
$accessGeneric += $accessMaskBase.$accessMaskKey
$accessAux = $accessAux -bxor $accessMaskKey
}
}
if ( $accessAux -ne 0 ) {
$accessFS = [array]($accessAux -as [Security.AccessControl.FileSystemRights])
} else {
$accessFS = @()
}
($accessGeneric + $accessFS) -join ', '
}
$shares = Get-WmiObject -Class win32_share -ComputerName $computer |
Where-Object {$_.name -notlike "*$"} |
Select-Object -Property Name, Path, Type
$acl = foreach ($shareObj in $shares) {
$share = $shareObj.Name
$ShareResource = $ShareObj.Path
Write-Host $share, $ShareResource -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 }
## convert [FileSystemAccessRule] object
## to an auxiliary object of [PSCustomObject] type:
$aux = New-Object Security.AccessControl.FileSystemAccessRule(
$UserName, $ace.AccessMask, $ace.AceType) |
ConvertTo-Csv -NoTypeInformation | ConvertFrom-Csv
## add desired properties (at least `Computer` and `Share`):
$aux | Add-Member -MemberType NoteProperty -Name Computer -Value $objShareSec.PSComputerName
$aux | Add-Member -MemberType NoteProperty -Name Share -Value $share
$aux | Add-Member -MemberType NoteProperty -Name NTFS -Value ''
## return `$aux` object using desired order of properties:
$aux | Select-Object Computer, Share, NTFS, FileSystemRights,
AccessControlType, IdentityReference,
IsInherited, InheritanceFlags, PropagationFlags
} #end foreach ACE
} # end try
catch
{ Write-Host "Unable to obtain permissions for $share" }
# NTFS permissions
if ( $shareObj.Type -eq 0 ) {
$FolderPathEsc = $ShareObj.Path.Replace('\','\\')
#$FolderPath = [regex]::Escape($SharedFolder.Path) ### this fails
$SharedNTFSSecs = Get-WmiObject -Class Win32_LogicalFileSecuritySetting `
-Filter "Path='$FolderPathEsc'" -ComputerName $Computer
$SecDescriptor = $SharedNTFSSecs.GetSecurityDescriptor()
$Objs = foreach( $DACL in $SecDescriptor.Descriptor.DACL )
{
$DACLDomain = $DACL.Trustee.Domain
$DACLName = $DACL.Trustee.Name
if( $null -ne $DACLDomain ) { $UserName = "$DACLDomain\$DACLName" }
else { $UserName = "$DACLName" }
$fsr = GetFileSystemRightsExtended -access $DACL.AccessMask
#customize the property
$Properties = @{
'Computer' = $objShareSec.PSComputerName
'Share' = $share
'NTFS' = $ShareResource
'FileSystemRights' = $fsr
'AccessControlType' = [System.Security.AccessControl.AccessControlType]$DACL.AceType
'IdentityReference' = $UserName
'IsInherited' = [bool]$($DACL.AceFlags -band [System.Security.AccessControl.AceFlags]::Inherited)
'InheritanceFlags' = [System.Security.AccessControl.AceFlags]$DACL.AceFlags
'PropagationFlags' = '' ### ???
}
$SharedNTFSACL = New-Object -TypeName PSObject -Property $Properties
$SharedNTFSACL
}
$Objs | Select-Object Computer, Share, NTFS, FileSystemRights,
AccessControlType, IdentityReference,
IsInherited, InheritanceFlags, PropagationFlags
} # end # NTFS permissions
} # end foreach $shareObj
$ACL | ConvertTo-Csv -NoTypeInformation -UseCulture
## for import to Excel, create a CSV file as follows ():
#$ACL | Export-Csv -NoTypeInformation -UseCulture -Encoding UTF8 <# -Append <##> -Path 'D:\PShell\DataFiles\55785608.csv'