<#
.SYNOPSIS
    <Overview of script>

.NOTES
    Version        : 1.0
    Author         : Hubert CORNET
    Creation Date  : <Date>
    Purpose/Change : <Initial script development>

.LINK
    https://www.tips-of-mine.fr

.EXEMPLE
    <Example goes here. Repeat this attribute for more than one example>

.DESCRIPTION
    <Brief description of script>

.PARAMETER <Parameter_Name>
    <Brief description of parameter input required. Repeat this attribute if required>

.INPUTS
    <Inputs if any, otherwise state None>

.OUTPUTS
    <Outputs if any, otherwise state None - example: Log file stored in C:\Windows\Temp\<name>.log>
#>

#---------------------------------------------------------[Initialisations]--------------------------------------------------------

# Définir l'action d'erreur pour continuer silencieusement
$ErrorActionPreference = "SilentlyContinue"

Param
(
	[Parameter(Mandatory=$false)]
	[Alias('Computer')][String[]]$ComputerName=$Env:COMPUTERNAME,

	[Parameter(Mandatory=$false)]
	[Alias('NTFS')][Switch]$NTFSPermission,
	
	[Parameter(Mandatory=$false)]
	[Alias('Cred')][System.Management.Automation.PsCredential]$Credential
)

$Database = @()
$DatabaseNTFS = @()

$RecordErrorAction = $ErrorActionPreference

# Définir l'action d'erreur pour continuer silencieusement
$ErrorActionPreference = "SilentlyContinue"

# Bibliothèques de fonctions requises

#----------------------------------------------------------[Declarations]----------------------------------------------------------
# Version Script
$sScriptVersion = "1.0"

#Log File Info
$sLogPath = "C:\Tmp"
$sLogName = "<script_name>.log"
$sLogFile = Join-Path -Path $sLogPath -ChildPath $sLogName

Start-Transcript -Path $sLogFile -NoClobber
#-----------------------------------------------------------[Functions]------------------------------------------------------------

Function GetSharedFolderPermission($ComputerName) {
	#test server connectivity
	$PingResult = Test-Connection -ComputerName $ComputerName -Count 1 -Quiet
	If($PingResult) {
		#check the credential whether trigger
		If($Credential) {
			$SharedFolderSecs = Get-WmiObject -Class Win32_LogicalShareSecuritySetting  -ComputerName $ComputerName -Credential $Credential -ErrorAction SilentlyContinue
		}
		Else {
			$SharedFolderSecs = Get-WmiObject -Class Win32_LogicalShareSecuritySetting  -ComputerName $ComputerName -ErrorAction SilentlyContinue
		}
		
		Foreach ($SharedFolderSec in $SharedFolderSecs)  { 
		    $Objs = @() #define the empty array
			
	        $SecDescriptor = $SharedFolderSec.GetSecurityDescriptor()
	        Foreach($DACL in $SecDescriptor.Descriptor.DACL) {  
				$DACLDomain = $DACL.Trustee.Domain
				$DACLName = $DACL.Trustee.Name
				
                If($DACLDomain -ne $null) {
	           		$UserName = "$DACLDomain\$DACLName"
				}
				Else {
					$UserName = "$DACLName"
				}
				
				#customize the property
				$Properties = @{'ComputerName' = $ComputerName
								'ConnectionStatus'  = "Success"
								'SharedFolderName'  = $SharedFolderSec.Name
								'SharedFolderPath'  = $SharedFolder.Path
								'SecurityPrincipal' = $UserName
								'FileSystemRights'  = [Security.AccessControl.FileSystemRights]$($DACL.AccessMask -as [Security.AccessControl.FileSystemRights])
								'AccessControlType' = [Security.AccessControl.AceType]$DACL.AceType}
				$SharedACLs = New-Object -TypeName PSObject -Property $Properties
				$Objs += $SharedACLs
	        }
			$Objs|Select-Object ComputerName,ConnectionStatus,SharedFolderName,SharedFolderPath,SecurityPrincipal, FileSystemRights,AccessControlType
	    }  
	}
	Else {
		$Properties = @{'ComputerName' = $ComputerName
						'ConnectionStatus'  = "Fail"
						'SharedFolderName'  = "Not Available"
						'SecurityPrincipal' = "Not Available"
						'FileSystemRights'  = "Not Available"
						'AccessControlType' = "Not Available"}
		$SharedACLs = New-Object -TypeName PSObject -Property $Properties
		$Objs += $SharedACLs
		$Objs|Select-Object ComputerName,ConnectionStatus,SharedFolderName,SharedFolderPath,SecurityPrincipal, FileSystemRights,AccessControlType
	}
}

Function GetSharedFolderNTFSPermission($ComputerName) {
	#test server connectivity
	$PingResult = Test-Connection -ComputerName $ComputerName -Count 1 -Quiet
	If($PingResult) {
		#check the credential whether trigger
		If($Credential) {
			$SharedFolders = Get-WmiObject -Class Win32_Share -ComputerName $ComputerName -Credential $Credential -ErrorAction SilentlyContinue
		}
		Else {
			$SharedFolders = Get-WmiObject -Class Win32_Share -ComputerName $ComputerName -ErrorAction SilentlyContinue
		}

		Foreach($SharedFolder in $SharedFolders) {
			$Objs = @()
			
			$SharedFolderPath = [regex]::Escape($SharedFolder.Path)
			If($Credential) {	
				$SharedNTFSSecs = Get-WmiObject -Class Win32_LogicalFileSecuritySetting  -Filter "Path='$SharedFolderPath'" -ComputerName $ComputerName  -Credential $Credential
			}
			Else {
				$SharedNTFSSecs = Get-WmiObject -Class Win32_LogicalFileSecuritySetting -Filter "Path='$SharedFolderPath'" -ComputerName $ComputerName
			}
			
			$SecDescriptor = $SharedNTFSSecs.GetSecurityDescriptor()
			Foreach($DACL in $SecDescriptor.Descriptor.DACL) {  
				$DACLDomain = $DACL.Trustee.Domain
				$DACLName = $DACL.Trustee.Name
				If($DACLDomain -ne $null) {
	           		$UserName = "$DACLDomain\$DACLName"
				}
				Else {
					$UserName = "$DACLName"
				}
				
				#customize the property
				$Properties = @{'ComputerName' = $ComputerName
								'ConnectionStatus'   = "Success"
								'SharedFolderName'   = $SharedFolder.Name
								'SharedFolderPath'   = $SharedFolder.Path
								'SecurityPrincipal'  = $UserName
								'FileSystemRights'   = [Security.AccessControl.FileSystemRights]$($DACL.AccessMask -as [Security.AccessControl.FileSystemRights])
								'AccessControlType'  = [Security.AccessControl.AceType]$DACL.AceType
								'AccessControlFalgs' = [Security.AccessControl.AceFlags]$DACL.AceFlags }
								
				$SharedNTFSACL = New-Object -TypeName PSObject -Property $Properties
	            $Objs += $SharedNTFSACL
	        }
			$Objs |Select-Object ComputerName,ConnectionStatus,SharedFolderName,SharedFolderPath,SecurityPrincipal,FileSystemRights, `
			AccessControlType,AccessControlFalgs -Unique
		}
	}
	Else {
		$Properties = @{'ComputerName' = $ComputerName
						'ConnectionStatus'   = "Fail"
						'SharedFolderName'   = "Not Available"
						'SecurityPrincipal'  = "Not Available"
						'FileSystemRights'   = "Not Available"
						'AccessControlType'  = "Not Available"
						'AccessControlFalgs' = "Not Available" }
					
		$SharedNTFSACL = New-Object -TypeName PSObject -Property $Properties
	    $Objs += $SharedNTFSACL
		$Objs |Select-Object ComputerName,ConnectionStatus,SharedFolderName,SharedFolderPath,SecurityPrincipal,FileSystemRights, `
		AccessControlType,AccessControlFalgs -Unique
	}
} 

#--------------------------------------------------------[Debut Du Script]---------------------------------------------------------

Clear-Host

$Table = New-Object 'System.Collections.Generic.List[System.Object]'

$ListServeur = Get-ADComputer -Filter { OperatingSystem -Like '*Windows Server*'}

Foreach ($Serveur in $ListServeur) {
    Try {
        Test-Connection -computername $Serveur.DNSHostName -Count 1 -ErrorAction stop | Out-Null
        Write-host $Serveur.DNSHostName

        $ListePartage = GetSharedFolderPermission -ComputerName $Serveur.DNSHostName

        #$ListePartageNFTS = GetSharedFolderNTFSPermission -ComputerName $Serveur.DNSHostName

        If (($ListePartage).Count -eq 0) {

        }
        Else {
            $Database += $ListePartage
        }

        #If (($ListePartageNFTS).Count -eq 0) {
#
        #}
        #Else {
        #    $DatabaseNFTS += $ListePartageNFTS
        #}
    }
    Catch [System.Net.NetworkInformation.PingException] {
        Write-Warning "$Serveur.DNSHostName ne répond pas"
    }
}

$Database | Out-GridView
#$DatabaseNFTS | Out-GridView

#restore the error action
$ErrorActionPreference = $RecordErrorAction

#---------------------------------------------------------[Fin Du Script]----------------------------------------------------------

Stop-Transcriptg