# Copy-SMB-Share-Permissions.ps1
# Set some SMB Share variables
$sourceSmbPath="\\FILESERVER002\Home"
$destinationSmbPath="\\FILESERVER002-n\Home"
$dateStamp = Get-Date -Format "yyyy-MM-dd-hhmmss"
$logFile="C:\copySmbPermissions-Log-$dateStamp.txt"
function copySmbPermissions{
param(
[string]$sourceSmbSharePath,
[string]$destinationSmbSharePath
)
# Set some variables
$sourceSmbServerName = $sourceSmbSharePath.split("\")[2];
$sourceSmbShareName = $sourceSmbSharePath.split("\")[3];
$destinationSmbServerName = $destinationSmbSharePath.split("\")[2];
$destinationSmbShareName = $destinationSmbSharePath.split("\")[3];
$GLOBAL:messages="";
# Legacy method to obtain SMB share permissions that would work with PowerShell 2.0 (Windows 2008)
function getSmbPermmissions{
param(
[string]$smbServerName,
[string]$smbPath
)
$smbShareName = $smbPath.split("\")[3]
$smbList = Get-WmiObject win32_LogicalShareSecuritySetting -ComputerName $smbServerName|?{$_.Name -notlike "*$"}
if($smbList){
$sample=$smbList.Name[0];
if($sample -match "^\\\\(.*)"){
# This accounts for Clustered File Server Role
$smbObject=$smbList|?{$_.Name -eq $smbPath};
}else{
# This accounts for Standalone File Server Role
$smbObject=$smbList|?{$_.Name -eq $smbShareName};
}
}else{
$message="Failed to retrieve SMB Permissions from $smbServerName";
$GLOBAL:messages+=$message+"`r`n";
write-host $message -ForegroundColor Yellow;
$smbObject=$false;
}
if($smbObject){
$message="Collecting share permissions for $smbPath...";
$GLOBAL:messages+=$message+"`r`n";
Write-Host $message;
$smbPermissions = @()
$acls = $smbObject.GetSecurityDescriptor().Descriptor.DACL
foreach($acl in $acls){
$user = $acl.Trustee.Name
if(!($user)){$user = $acl.Trustee.SID}
$domain = $acl.Trustee.Domain
switch($acl.AccessMask){
2032127 {$accessRight = "Full"}
1245631 {$accessRight = "Change"}
1179817 {$accessRight = "Read"}
}
$smbPermissions+=[PSCustomObject]@{IdentityReference="$domain\$user";AccessRight=$accessRight};
}
return $smbPermissions;
}else{
return $false;
}
}
# This function requires PowerShell 4.0 and higher
function setSmbPermissions{
param(
$smbName=$destinationSmbShareName,
$fileServerRole=$destinationSmbServerName,
$smbPermissions=$sourceSmbPermissions
)
# Locate the host for the file server role
$roleOwner=(Get-ClusterResource -Name $fileServerRole -ErrorAction SilentlyContinue).OwnerNode.Name
if ($roleOwner){
# Connect to host
$message="Connecting to remote computer $roleOwner...";
$GLOBAL:messages+=$message;
write-host $message;
$maxTime=10; $duration=0;
do{
$session = New-PSSession -ComputerName $roleOwner -ErrorAction SilentlyContinue;
if (!($session)){
write-host "." -NoNewline;
$duration++;
sleep -seconds 1;
}
if ($session){
$message=".. Connected in $duration seconds.";
$GLOBAL:messages+=$message+"`r`n";
write-host $message -NoNewline;
}
} until ($session.state -match "Opened" -or $duration -eq $maxTime)
if($session){
$message="Setting share permissions for $smbName of $fileServerRole, currently owned by $roleOwner...";
$GLOBAL:messages+=$message+"`r`n";
Write-Host $message;
$invokeCommandResult=Invoke-Command -Session $session -ScriptBlock{
param($smbName,$fileServerRole,$smbPermissions)
# Declare some variables;
[int]$successCount=0;
[int]$failuresCount=0;
[bool]$singleItem=$smbPermissions.Count -eq $null -or $smbPermissions.Count -eq 1;
[string]$sessionMessages="";
foreach ($permission in $smbPermissions){
$identityReference=$permission.IdentityReference;
# This accounts for non-domain accounts
if($identityReference -match "^\\[^\\]+$"){$identityReference=$identityReference.SubString(1,$identityReference.Length-1)}
$accessRight=$permission.AccessRight;
$expression="Grant-SmbShareAccess -Name $smbName -ScopeName $fileServerRole -AccountName '$identityReference' -AccessRight $accessRight -Force";
# Using self executing anonymous function to exit try-loop upon failures
.{
try{
$success=Invoke-Expression $expression;
if(!($success)) {
$failuresCount++;
$success=$false;
return; # Exit try-loop
}
$successCount++;
$success=$true;
}
catch{
write-host $Error;
}
}
if($success){
$message="$expression => Success";
$sessionMessages+=$message+"`r`n";
write-host $message;
}else{
$message="$expression => Failure"
$sessionMessages+=$message+"`r`n";
write-host $message -ForegroundColor Yellow;
}
}
if ($singleItem){
$message="$successCount of 1 permission set is successful.";
$sessionMessages+=$message+"`r`n";
write-host $message;
}else{
$message="$successCount of $($smbPermissions.Count) permission settings are successful.";
$sessionMessages+=$message+"`r`n";
write-host $message;
}
$overallResult=$failuresCount -eq 0;
$outputArray=@($overallResult,$sessionMessages)
return $outputArray;
} -Args $smbName,$fileServerRole,$smbPermissions
Remove-PSSession $session;
$GLOBAL:messages+=$invokeCommandResult[1]+"`r`n";
$result=$invokeCommandResult[0];
}else{
$message="Unable to connect to $roleOwner.";
$GLOBAL:messages+=$message+"`r`n";
write-host $message -ForegroundColor Red;
$result=$false;
}
}else{
$message="Unable to get owner node for $fileServerRole.";
$GLOBAL:messages+=$message+"`r`n";
write-host $message -ForegroundColor Red;
$result=$false;
}
return $result;
}
$sourceSmbPermissions=getSmbPermmissions -smbServerName $sourceSmbServerName -smbPath $sourceSmbSharePath
if ($sourceSmbPermissions){
$success=setSmbPermissions -smbName $destinationSmbShareName -fileServerRole $destinationSmbServerName -smbPermissions $sourceSmbPermissions
if ($success){
$message="Permissions from $sourceSmbSharePath have been successfully copied to $destinationSmbSharePath.";
$GLOBAL:messages+=$message+"`r`n";
write-host $message;
return $true;
}else{
$message="Unable to *SET* SMB Permissions to destination $destinationSmbSharePath.";
$GLOBAL:messages+=$message+"`r`n";
write-host $message -ForegroundColor Red;
return $false;
}
}else{
$message="Unable to *GET* SMB Permissions from $sourceSmbSharePath.";
$GLOBAL:messages+=$message+"`r`n";
write-host $message -ForegroundColor Yellow;
return $false;
}
}
copySmbPermissions -sourceSmbSharePath $sourceSmbPath -destinationSmbSharePath $destinationSmbPath
#Add-Content $logFile $messages;
Categories: