NTFSPermissionMigration.psm1
$errorsLogFilePath = 'C:\PermissionErrors.txt' function Save-Acl { <# .SYNOPSIS This function uses icacls to recursively retrieves all permissions from all files and folders in a particular folder path and saves them to a text file. .EXAMPLE PS> Save-Acl -FolderPath \\FILESERVER\FileShare -SaveFilePath C:\FileSharePermissions.txt .PARAMETER FolderPath A Mandatory string parameter representing a valid and accessible folder path. This can be a UNC path or a local path. .PARAMETER SaveFilePath A mandatory string parameter representing a path to save the text file full permissions to. This will be referenced with the Restore-Acl function later. #> [OutputType([void])] [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateScript({Test-Path -Path $_ -PathType Container})] [string]$FolderPath, [Parameter(Mandatory)] [string]$SaveFilePath ) begin { $ErrorActionPreference = 'Continue' } process { try { Invoke-ICacls @PSBoundParameters | ForEach-Object { Write-Output $_ } Get-Content -Path $errorsLogFilePath | foreach { Write-Error -Message $_ } } catch { $PSCmdlet.ThrowTerminatingError($_) } finally { Remove-Item -Path $errorsLogFilePath -ErrorAction SilentlyContinue } } } function Restore-Acl { <# .SYNOPSIS This function takes the file generated by Save-Acl and applies all permissions therein to a mirror of the folder structure that was originally read. For this to work, the folder structure originally read by Save-Acl must be exactly the same as the one you're pointing to here. .EXAMPLE PS> Restore-Acl -RestoreToFolderPath \\NEWFILESERVER\FileShare -PermissionFilePath C:\FileSharePermissions.txt .PARAMETER RestoreToFolderPath A mandatory string parameter representing the folder path that exactly mirrors the folder structure that was read with Save-Acl. .PARAMETER PermissionFilePath A mandatory string parameter representing the text file saved by Save-Acl. #> [OutputType()] [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateScript({Test-Path -Path $_ -PathType Container})] [string]$RestoreToFolderPath, [Parameter(Mandatory)] [ValidateScript({Test-Path -Path $_ -PathType Leaf})] [string]$PermissionFilePath ) try { Invoke-ICacls -FolderPath $RestoreToFolderPath -RestoreFilePath $PermissionFilePath | ForEach-Object { Write-Output $_ } Get-Content -Path $errorsLogFilePath | foreach { Write-Error -Message $_ } } catch { $PSCmdlet.ThrowTerminatingError($_) } finally { Remove-Item -Path $errorsLogFilePath -ErrorAction SilentlyContinue } } function Invoke-ICacls { [OutputType()] [CmdletBinding()] param ( [Parameter()] [ValidateScript({Test-Path -Path $_ -PathType Container})] [string]$FolderPath, [Parameter(ParameterSetName = 'Save')] [string]$SaveFilePath, [Parameter(ParameterSetName = 'Restore')] [ValidateScript({Test-Path -Path $_ -PathType Leaf})] [string]$RestoreFilePath ) if ($PSCmdlet.ParameterSetName -eq 'Save') { icacls "$FolderPath\*" /save $SaveFilePath /t /c 2>$errorsLogFilePath } elseif ($PSCmdlet.ParameterSetName -eq 'Restore') { icacls $FolderPath /restore $RestoreFilePath /c 2>$errorsLogFilePath } } |