Avatar of Albert Widjaja
Albert WidjajaFlag for Australia

asked on 

Modifying Powershell script to list the SYSVOL NTFS & Share permission directory from all Domain controllers ?

Hi All,

Can anyone here please assist me in modifying the PowerShell script below to list all domain controllers SYSVOL directory NTFS and Share security ?

Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))" | ForEach-Object {
    "Processing $($_.DNSHostName) ..." | Write-Host
	....................
	
} | Export-Csv -Path C:\TEMP\Result.csv -NoTypeInformation -UseCulture

Open in new window


and this one:

################################################################################
# AUDIT FILE & FOLDER PERMISSIONS v1.1
# by Roman Zarka | Microsoft Services
################################################################################

$ErrorActionPreference = "Continue" 
$strComputer = $env:ComputerName 
$colDrives = Get-PSDrive -PSProvider Filesystem 
ForEach ($DriveLetter in $colDrives) { 
    $StartPath = "$DriveLetter`:\" 
    # Get-ChildItem -LiteralPath $StartPath -Recurse | 
	# Folder only not including the files
	 Get-ChildItem -LiteralPath $StartPath -Recurse | ?{ $_.PSIsContainer } |
    ForEach { 
      $FullPath = Get-Item -LiteralPath (Get-Item -LiteralPath $_.PSPath) 
      (Get-Item -LiteralPath $FullPath).GetAccessControl() | 
      Select * -Expand Access | 
      Select @{N='Server Name';E={$strComputer}}, 
             @{N='Full Path';E={$FullPath}}, 
             @{N='Type';E={If($FullPath.PSIsContainer -eq $True) {'D'} Else {'F'}}}, 
             @{N='Owner';E={$_.Owner}}, 
             @{N='Trustee';E={$_.IdentityReference}}, 
             @{N='Inherited';E={$_.IsInherited}}, 
             @{N='Inheritance Flags';E={$_.InheritanceFlags}}, 
             @{N='Ace Flags';E={$_.PropagationFlags}}, 
             @{N='Ace Type';E={$_.AccessControlType}}, 
             @{N='Access Masks';E={$_.FileSystemRights}} } | 
      Export-CSV -NoTypeInformation -Delimiter "|" –Path C:\TEMP\"$strComputer`_$DriveLetter.csv" }

Open in new window


Thanks in advance,
PowershellActive DirectorySecurity

Avatar of undefined
Last Comment
Ben Personick (Previously QCubed)
Avatar of Ben Personick (Previously QCubed)
Ben Personick (Previously QCubed)
Flag of United States of America image

Here you go:

## Script Name: DCSysVol_ACLs.ps1
## Version: 1.0.0
#

# =================================== #
# = Define Parameters				= #

param(
	$DebugPreference="SilentlyContinue"
	# $DebugPreference="Continue"
) 
# Set Debug Level, Continue shows debug messages, SilentlyContinue is Default
Write-Debug "Debug-Preferences:"
Write-Debug "DebugPreference = $DebugPreference"

# =================================== #
# = Begin Functions					= #

## Function: Get-IsISE
function Get-IsISE {
# Tests whether the current environment contains the $psISE Variable which is normally only set when running in ISE
    try {    
        return $psISE -ne $null;
    }
    catch {
        return $false;
    }
}

# =================================== #
# = Initialize Variables			= #

## 0.1: Set the script Path (If in ISE, set it to a manual value, otherwise use script location value)
$scriptPath = 'C:\Admin\Scripts\Experts-Exchange\29015623_Modifying-Powershell-script-to-list-the-SYSVOL-NTFS-Share-permission-directory-from-all-Domain-controllers'
if ( -not ( Get-IsISE ) ) {
	# Get Path for this script File and set it to a variable
	$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
}

## 0.2: Set CSV Output name
$CSV_Path = "$ScriptPath\All_Domain_Controllers_ACLs.csv"

## 0.3: Set Group Search base to check specific groups for thier users.
$Group_SearchBase = "OU=Groups,OU=Root,DC=Domain,DC=com"

## 0.4: Initialize Results variable
$Results = @()

# =================================== #
# = Begin Main						= #

$Domain_Controllers = Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))"
$Domain_Controllers | ForEach-Object {
	$ServerName = $($_.DNSHostName)
	Write-Host "Processing $($_.DNSHostName) "
	$StartPath = "\\$($_.DNSHostName)\Sysvol\"
	Write-Host " Start Path: $StartPath "
	$DC_SysVol_Paths = Get-ChildItem -LiteralPath $StartPath -Recurse |  where-object { $_.PSIsContainer } 
	foreach ($D_S_P in $DC_SysVol_Paths ){
		$Fullpath = $(Get-Item -LiteralPath (Get-Item -LiteralPath  $D_S_P.PSPath))
		Write-Host "Fullpath:  $Fullpath"
		$Path_ACLs = (Get-Item -LiteralPath $FullPath).GetAccessControl()| Select * -Expand Access
		foreach ($P_ACL in $Path_ACLs) {
			$Results += New-Object PSObject -Property @{
				ServerName = $ServerName
				FullPath = $Fullpath
				Type = 'Folder'
				Owner = $P_ACL.Owner
				Trustee = $P_ACL.IdentityReference
				Inherited = $P_ACL.IsInherited 
				Inheritance_Flags = $P_ACL.InheritanceFlags 
				Ace_Flags = $P_ACL.PropagationFlags 
				Ace_Type = $P_ACL.AccessControlType
				Access_Masks = $P_ACL.FileSystemRights
			}
		}
	}
}
$Results | Export-CSV $CSV_Path -NoTypeInformation

Open in new window

Just updated with the cleaned up version of the code with customary commenting and putting the output in the directory of the script.

Here is example output from my domain:

ServerName	Trustee	Type	FullPath	Owner	Ace_Flags	Inherited	Inheritance_Flags	Ace_Type	Access_Masks
DC01.Domain.Com	NT AUTHORITY\Authenticated Users	Folder	\\DC01.Domain.Com\Sysvol\Domain.Com	BUILTIN\Administrators	None	TRUE	None	Allow	ReadAndExecute, Synchronize
DC01.Domain.Com	NT AUTHORITY\Authenticated Users	Folder	\\DC01.Domain.Com\Sysvol\Domain.Com	BUILTIN\Administrators	InheritOnly	TRUE	ContainerInherit, ObjectInherit	Allow	-1610612736
DC01.Domain.Com	S-1-5-32-549	Folder	\\DC01.Domain.Com\Sysvol\Domain.Com	BUILTIN\Administrators	None	TRUE	None	Allow	ReadAndExecute, Synchronize
DC01.Domain.Com	S-1-5-32-549	Folder	\\DC01.Domain.Com\Sysvol\Domain.Com	BUILTIN\Administrators	InheritOnly	TRUE	ContainerInherit, ObjectInherit	Allow	-1610612736
DC01.Domain.Com	BUILTIN\Administrators	Folder	\\DC01.Domain.Com\Sysvol\Domain.Com	BUILTIN\Administrators	None	TRUE	None	Allow	Write, ReadAndExecute, ChangePermissions, TakeOwnership, Synchronize

Open in new window

I literally just noticed you wanted to see the share permissions as well as the NTFS permissions.  However the scripts you provided only find the DCs and give you the NTFS Permissions.

  Share permissions are tricky remotely, you need to use WMIC (Yuck) but there is a script available from Microsoft that just does this.

Link to MS Original Script: https://gallery.technet.microsoft.com/scriptcenter/List-Share-Permissions-83f8c419

The following is the above script built loops through all the domain controllers and executes against each of them to also give you the share permissions on every DC as a separate list for you:

$Domain_Controllers = Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))"

$Domain_Controllers | ForEach-Object {
	$computer  = $($_.DNSHostName)
	Write-Host "Processing $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)  
				} #end foreach ACE            
			} # end try  
		catch  
			{ Write-Host "Unable to obtain permissions for $share" }  
		$ACL  
		Write-Host $('=' * 50)  
	} # end foreach $share
}

Open in new window


That should cover the other half of your request
Avatar of Albert Widjaja

ASKER

Thanks Ben,

The script is running longer than I thought :-)
Can I still run it just for the SYSVOL directory?
I literally just noticed you wanted to see the share permissions as well as the NTFS permissions.  However the scripts you provided only find the DCs and give you the NTFS Permissions.

  Share permissions are tricky remotely, you need to use WMIC (Yuck) but there is a script available from Microsoft that just does this.

Link to MS Original Script: https://gallery.technet.microsoft.com/scriptcenter/List-Share-Permissions-83f8c419

The following code is the script from MS I just linked to, but I amended it to loop through your domain controllers to also give you the share permissions on every DC as a separate list in a separate CSV for you.

## Script Name: DCSysVol_ACLs.ps1
## Version: 1.0.0
#

# =================================== #
# = Define Parameters				= #

param(
	$DebugPreference="SilentlyContinue"
	# $DebugPreference="Continue"
) 
# Set Debug Level, Continue shows debug messages, SilentlyContinue is Default
Write-Debug "Debug-Preferences:"
Write-Debug "DebugPreference = $DebugPreference"

# =================================== #
# = Begin Functions					= #

## Function: Get-IsISE
function Get-IsISE {
# Tests whether the current environment contains the $psISE Variable which is normally only set when running in ISE
    try {    
        return $psISE -ne $null;
    }
    catch {
        return $false;
    }
}

# =================================== #
# = Initialize Variables			= #

## 0.1: Set the script Path (If in ISE, set it to a manual value, otherwise use script location value)
$scriptPath = 'C:\Admin\Scripts\Experts-Exchange\29015623_Modifying-Powershell-script-to-list-the-SYSVOL-NTFS-Share-permission-directory-from-all-Domain-controllers'
if ( -not ( Get-IsISE ) ) {
	# Get Path for this script File and set it to a variable
	$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
}

## 0.2: Set CSV Output name
$CSV_Path = "$ScriptPath\All_Domain_Controllers_Shares.csv"

## 0.3: Initialize Results variable
$Results = @()

# =================================== #
# = Begin Main						= #

$Domain_Controllers = Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))"

$Domain_Controllers | ForEach-Object {
	$computer  = $($_.DNSHostName)
	Write-Host "Processing $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)  
				} #end foreach ACE            
			} # end try  
		catch  
			{ Write-Host "Unable to obtain permissions for $share" }  
		$Results +=$ACL
                $ACL | Out-String | Write-Debug
		Write-Debug "$('=' * 50)"
	} # end foreach $share
}
Write-Debug ""
Write-Debug "Results:"
$Results | Out-String | Write-Debug
$Results | Export-CSV $CSV_Path -NoTypeInformation

Open in new window

That should cover the other half of your request
Did you only want it for the root directory "Sysvol"?  It seemed you wanted all the permissions based off the scripts.

If so here is the simplified ACL script which only returns the info for the Sysvol directories

## Script Name: DCSysVolOnly_ACLs.ps1
## Version: 1.0.0
#

# =================================== #
# = Define Parameters				= #

param(
	$DebugPreference="SilentlyContinue"
	# $DebugPreference="Continue"
) 
# Set Debug Level, Continue shows debug messages, SilentlyContinue is Default
Write-Debug "Debug-Preferences:"
Write-Debug "DebugPreference = $DebugPreference"

# =================================== #
# = Begin Functions					= #

## Function: Get-IsISE
function Get-IsISE {
# Tests whether the current environment contains the $psISE Variable which is normally only set when running in ISE
    try {    
        return $psISE -ne $null;
    }
    catch {
        return $false;
    }
}

# =================================== #
# = Initialize Variables			= #

## 0.1: Set the script Path (If in ISE, set it to a manual value, otherwise use script location value)
$scriptPath = 'C:\Admin\Scripts\Experts-Exchange\29015623_Modifying-Powershell-script-to-list-the-SYSVOL-NTFS-Share-permission-directory-from-all-Domain-controllers'
if ( -not ( Get-IsISE ) ) {
	# Get Path for this script File and set it to a variable
	$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
}

## 0.2: Set CSV Output name
$CSV_Path = "$ScriptPath\All_Domain_Controllers_ACLs.csv"

## 0.3: Set Group Search base to check specific groups for thier users.
$Group_SearchBase = "OU=Groups,OU=Root,DC=Domain,DC=com"

## 0.4: Initialize Results variable
$Results = @()

# =================================== #
# = Begin Main						= #

$Domain_Controllers = Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))"
$Domain_Controllers | ForEach-Object {
	$ServerName = $($_.DNSHostName)
	Write-Host "Processing $($_.DNSHostName) "
	$StartPath = "\\$($_.DNSHostName)\Sysvol\"
	Write-Host " Start Path: $StartPath "
	$DC_SysVol_Paths = Get-ChildItem -LiteralPath $StartPath |  where-object { $_.PSIsContainer } 
	foreach ($D_S_P in $DC_SysVol_Paths ){
		$Fullpath = $(Get-Item -LiteralPath (Get-Item -LiteralPath  $D_S_P.PSPath))
		Write-Host "Fullpath:  $Fullpath"
		$Path_ACLs = (Get-Item -LiteralPath $FullPath).GetAccessControl()| Select * -Expand Access
		foreach ($P_ACL in $Path_ACLs) {
			$Results += New-Object PSObject -Property @{
				ServerName = $ServerName
				FullPath = $Fullpath
				Type = 'Folder'
				Owner = $P_ACL.Owner
				Trustee = $P_ACL.IdentityReference
				Inherited = $P_ACL.IsInherited 
				Inheritance_Flags = $P_ACL.InheritanceFlags 
				Ace_Flags = $P_ACL.PropagationFlags 
				Ace_Type = $P_ACL.AccessControlType
				Access_Masks = $P_ACL.FileSystemRights
			}
		}
	}
}
$Results | Export-CSV $CSV_Path -NoTypeInformation
$Results | Format-Table -Auto

Open in new window

Avatar of Albert Widjaja

ASKER

Hi Ben,

Thanks for the Share Permission script as well, however, the script that you share does not show the Server name in the first column ?

## Script Name: DCSysVol_ACLs.ps1
## Version: 1.0.0
#

# =================================== #
# = Define Parameters				= #

param(
	$DebugPreference="SilentlyContinue"
	# $DebugPreference="Continue"
) 
# Set Debug Level, Continue shows debug messages, SilentlyContinue is Default
Write-Debug "Debug-Preferences:"
Write-Debug "DebugPreference = $DebugPreference"

# =================================== #
# = Begin Functions					= #

## Function: Get-IsISE
function Get-IsISE {
# Tests whether the current environment contains the $psISE Variable which is normally only set when running in ISE
    try {    
        return $psISE -ne $null;
    }
    catch {
        return $false;
    }
}

# =================================== #
# = Initialize Variables			= #

## 0.1: Set the script Path (If in ISE, set it to a manual value, otherwise use script location value)
$scriptPath = 'C:\Admin\Scripts\Experts-Exchange\29015623_Modifying-Powershell-script-to-list-the-SYSVOL-NTFS-Share-permission-directory-from-all-Domain-controllers'
if ( -not ( Get-IsISE ) ) {
	# Get Path for this script File and set it to a variable
	$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
}

## 0.2: Set CSV Output name
$CSV_Path = "$ScriptPath\All_Domain_Controllers_Shares.csv"

## 0.3: Initialize Results variable
$Results = @()

# =================================== #
# = Begin Main						= #

$Domain_Controllers = Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))"

$Domain_Controllers | ForEach-Object {
	$computer  = $($_.DNSHostName)
	Write-Host "Processing $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)  
				} #end foreach ACE            
			} # end try  
		catch  
			{ Write-Host "Unable to obtain permissions for $share" }  
		$Results +=$ACL
                $ACL | Out-String | Write-Debug
		Write-Debug "$('=' * 50)"
	} # end foreach $share
}
Write-Debug ""
Write-Debug "Results:"
$Results | Out-String | Write-Debug
$Results | Export-CSV $CSV_Path -NoTypeInformation

Open in new window

Hey, I just left off the Server name variable.

Here it includes it for you.

Thanks

## Script Name: DCS_Share_ACLs.ps1
## Version: 1.0.1
#

# =================================== #
# = Define Parameters				= #

param(
	$DebugPreference="SilentlyContinue"
	# $DebugPreference="Continue"
) 
# Set Debug Level, Continue shows debug messages, SilentlyContinue is Default
Write-Debug "Debug-Preferences:"
Write-Debug "DebugPreference = $DebugPreference"

# =================================== #
# = Begin Functions					= #

## Function: Get-IsISE
function Get-IsISE {
# Tests whether the current environment contains the $psISE Variable which is normally only set when running in ISE
    try {    
        return $psISE -ne $null;
    }
    catch {
        return $false;
    }
}

# =================================== #
# = Initialize Variables			= #

## 0.1: Set the script Path (If in ISE, set it to a manual value, otherwise use script location value)
$scriptPath = 'C:\Admin\Scripts\Experts-Exchange\29015623_Modifying-Powershell-script-to-list-the-SYSVOL-NTFS-Share-permission-directory-from-all-Domain-controllers'
if ( -not ( Get-IsISE ) ) {
	# Get Path for this script File and set it to a variable
	$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
}

## 0.2: Set CSV Output name
$CSV_Path = "$ScriptPath\All_Domain_Controllers_Shares.csv"

## 0.3: Initialize Results variable
$Results = @()

# =================================== #
# = Begin Main						= #

$Domain_Controllers = Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))"

$Domain_Controllers | ForEach-Object {
	$ServerName  = $($_.DNSHostName)
	Write-Host "Processing $ServerName"
	$shares = gwmi -Class win32_share -ComputerName $ServerName | 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 $ServerName 
		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($ServerName, $UserName, $ace.AccessMask, $ace.AceType)  
				} #end foreach ACE            
			} # end try  
		catch  
			{ Write-Host "Unable to obtain permissions for $share" }  
		$Results +=$ACL
                $ACL | Out-String | Write-Debug
		Write-Debug "$('=' * 50)"
	} # end foreach $share
}
Write-Debug ""
Write-Debug "Results:"
$Results | Out-String | Write-Debug
$Results | Export-CSV $CSV_Path -NoTypeInformation

Open in new window

Avatar of Albert Widjaja

ASKER

Hi Ben,

Thanks for the follow-up.
However, I got this error when I execute the script above for the share permission:

gwmi : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At H:\Powershell scripts\Get-SYSVOL-Share-permission.ps1:54 char:12
+ ...   $shares = gwmi -Class win32_share -ComputerName $ServerName | selec ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

Open in new window


The .CSV file is empty.
Hello OP,

  RPC errors are due to a whole host of issues not related to the script.

  Could be WMIC is not running on the remote servers, could be share and permissions or Firewall blocking ports for RPC/SM, could be the script runs an account without access right to the servers, could not make the process a little easier.

 Note: the access maps are a sum of permissions, that maps to the permissions I put into this version, but I  can;t easily calculate them on the fly.

 Sysvol has some basic standard positions and you should be able to see if they differ from one another in the results.

be the service on the remote machines been to be restarted, could be problems with DNS or NetBIOS, etc.

That said I did make a few typos and I have re-written the core of the script with testing to make sure we get results

## Script Name: DCS_Share_ACLs.ps1
## Version: 1.0.1
#

# =================================== #
# = Define Parameters				= #

param(
	#$DebugPreference="SilentlyContinue"
	 $DebugPreference="Continue"
) 
# Set Debug Level, Continue shows debug messages, SilentlyContinue is Default
Write-Debug "Debug-Preferences:"
Write-Debug "DebugPreference = $DebugPreference"

# =================================== #
# = Begin Functions					= #

## Function: Get-IsISE
function Get-IsISE {
# Tests whether the current environment contains the $psISE Variable which is normally only set when running in ISE
    try {    
        return $psISE -ne $null;
    }
    catch {
        return $false;
    }
}

# =================================== #
# = Initialize Variables			= #

## 0.1: Set the script Path (If in ISE, set it to a manual value, otherwise use script location value)
$scriptPath = 'C:\Admin\Scripts\Experts-Exchange\29015623_Modifying-Powershell-script-to-list-the-SYSVOL-NTFS-Share-permission-directory-from-all-Domain-controllers'
if ( -not ( Get-IsISE ) ) {
	# Get Path for this script File and set it to a variable
	$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
}

## 0.2: Set CSV Output name
$CSV_Path = "$ScriptPath\All_Domain_Controllers_Shares.csv"

## 0.3: Initialize Results variable
$Results = @()
$acmsk = DATA {
ConvertFrom-StringData -StringData @’
1 = Read/List
2 = Write/Create File
4 = Append/Create Subdirectory
8 = Read extended attributes.
16 = Write extended attributes.
32 = Execute file/Traverse directory
64 = Delete directory
128 = Read file attributes.
256 = Change file attributes.
65536 = Delete
131072 = Read access to the security descriptor and owner.
262144 = Write access to the discretionary access control list (DACL).
524288 = Assigns the write owner.
1048576 = Synchronizes access, allows a process to wait
for an object to enter the signaled state.
‘@
}
$flags = @(1,2,4,8,16,32,64,128,256,65536,131072,262144,524288,1048576)



# =================================== #
# = Begin Main						= #

$Domain_Controllers = Get-ADComputer -LDAPFilter "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))"

$Domain_Controllers | ForEach-Object {
	$ServerName  = $($_.DNSHostName)
	Write-Host "Processing $ServerName"
	$shares = gwmi -Class win32_share -ComputerName $ServerName | select -ExpandProperty Name
	
	foreach ($share in $shares) {  
		#$ACL = @( )
		Write-Host $share -ForegroundColor Green  
		Write-Host $('-' * $share.Length) -ForegroundColor Green  
		$objShareSec = Get-WMIObject -Class Win32_LogicalShareSecuritySetting -Filter "name='$Share'"  -ComputerName $ServerName
       # $Results += 
       IF ($objShareSec -ne $null) {
       $Results += foreach ($DACL IN $objShareSec.GetSecurityDescriptor().Descriptor.DACL) {

        New-Object PSObject -Property @{
           ServerName = $ServerName
           #UserName = $UserName
           Share_Name = $Share
           Domain = $($DACL.trustee.Domain)
           UserName = $($DACL.trustee.Name)
           Access_Mask = $($DACL.AccessMask)
           ACE_Type = $($DACL.AceType)
        }
            
        } 
        }
		#$Results +=$ACL
        #$ACL | Out-String | Write-Debug
	} # end foreach $share
}
Write-Debug ""
Write-Debug "Results:"
$Results | Out-String | Write-Debug
$Results | Export-CSV $CSV_Path -NoTypeInformation

Open in new window

Avatar of Albert Widjaja

ASKER

Hi Ben,

Is the typo located in line 62 on your code above:

	1048576 = Synchronizes access, allows a process to wait for an object to enter the signaled state.
	‘@

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Ben Personick (Previously QCubed)
Ben Personick (Previously QCubed)
Flag of United States of America image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
Avatar of Albert Widjaja

ASKER

Many thanks Ben !
Very Welcome!  Glad to help :)
Active Directory
Active Directory

Active Directory (AD) is a Microsoft brand for identity-related capabilities. In the on-premises world, Windows Server AD provides a set of identity capabilities and services, and is hugely popular (88% of Fortune 1000 and 95% of enterprises use AD). This topic includes all things Active Directory including DNS, Group Policy, DFS, troubleshooting, ADFS, and all other topics under the Microsoft AD and identity umbrella.

85K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo