We help IT Professionals succeed at work.

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

733 Views
Last Modified: 2017-04-27
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,
Comment
Watch Question

Ben Personick (Previously QCubed)Lead SaaS Infrastructure Engineer
CERTIFIED EXPERT

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

Ben Personick (Previously QCubed)Lead SaaS Infrastructure Engineer
CERTIFIED EXPERT

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

Ben Personick (Previously QCubed)Lead SaaS Infrastructure Engineer
CERTIFIED EXPERT

Commented:
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
Senior IT System EngineerSenior Systems Engineer
CERTIFIED EXPERT

Author

Commented:
Thanks Ben,

The script is running longer than I thought :-)
Can I still run it just for the SYSVOL directory?
Ben Personick (Previously QCubed)Lead SaaS Infrastructure Engineer
CERTIFIED EXPERT

Commented:
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
Ben Personick (Previously QCubed)Lead SaaS Infrastructure Engineer
CERTIFIED EXPERT

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

Senior IT System EngineerSenior Systems Engineer
CERTIFIED EXPERT

Author

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

Ben Personick (Previously QCubed)Lead SaaS Infrastructure Engineer
CERTIFIED EXPERT

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

Senior IT System EngineerSenior Systems Engineer
CERTIFIED EXPERT

Author

Commented:
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.
Ben Personick (Previously QCubed)Lead SaaS Infrastructure Engineer
CERTIFIED EXPERT

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

Senior IT System EngineerSenior Systems Engineer
CERTIFIED EXPERT

Author

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

Lead SaaS Infrastructure Engineer
CERTIFIED EXPERT
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION
Senior IT System EngineerSenior Systems Engineer
CERTIFIED EXPERT

Author

Commented:
Many thanks Ben !
Ben Personick (Previously QCubed)Lead SaaS Infrastructure Engineer
CERTIFIED EXPERT

Commented:
Very Welcome!  Glad to help :)

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions