Copy-Acl

PowerShell Team

Today my wife told me about a problem on the family PC.  There were a bunch of PDF files in a directory that had the wrong permissions so my son couldn’t access them.  She modified the ACL on one of them using Explorer and verified that that was the fix.  (This is from a test I ran)

image

She then selected them all and tried to do it all at once but when she brought up the Properties, it didn’t have the Security Page anymore:

image

She wanted to know if there was some trick to set the ACLs all at once.  I told her that PowerShell could do that.  I showed her how to use Get-Acl and Set-Acl and she gave me a look like, “you expect me to remember that?” and asked, “why don’t you just have a COPY-ACL’ cmdlet.  I told her her how “to ship is to choose” but she wasn’t having any of it.  She clearly thought I was an idiot for not having shipped Copy-Acl.  You know what – I totally get it.  As a user – who cares how tough it is to ship software at Microsoft?  All that matters is that you have a need and we either meet it or we don’t.  Sadly that doesn’t change the reality of what it takes to ship things at Microsoft but it does provide some energy to write/share scripts.

As such, I spent a few minutes and wrote Copy-Acl.  I hope you enjoy it.  I’ve also attached it as a file to this blog. 

Enjoy!

Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

 

——————————————————————————————-

 

<#
.SYNOPSIS
Copy the ACL from one file to other files

.DESCRIPTION
Takes a file and copies its ACL to one or more other files.

.PARAMETER FromPath
Path of the File to get the ACL from.

.PARAMETER Destination
Path to one or more files to copy the ACL to.

.PARAMETER Passthru
Returns an object representing the security descriptor.  By default, this cmdlet does not generate any output.

.INPUTS
You can Pipeline any object with a Property named "PSPath", "FullName" or "Destination".

.EXAMPLE
PS> Copy-Acl Referencefile.txt (dir c:\temp\*xml)

.EXAMPLE
PS> dir c:\files *.xml -recurse | Copy-Acl ReferenceFile.txt

.LINK
Get-Acl
Set-Acl

.NOTES
Author:  Jeffrey Snover

#>
#requires -Version 2.0
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[Parameter(position=0,Mandatory=$true)]
[String]$FromPath,

[Parameter(Position=1,Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
[Alias("PSpath","fullname")]
[String[]]$Destination,

[Parameter(Mandatory=$false)]
[Switch]$PassThru
)
Begin
{
    if (! (Test-Path $FromPath))
    {
        $ErrorRecord = New-Object System.Management.Automation.ErrorRecord  (
            (New-Object Exception "FromPath ($fromPath) does not point to an existing object"),
            "Copy-Acl.TestPath",
            "ObjectNotFound",
            $FromPath
         )

        $PSCmdlet.ThrowTerminatingError($ErrorRecord)
    }
    $acl = Get-Acl $FromPath
}
Process
{
    foreach ($Dest in @($Destination))
    {
        if ($pscmdlet.ShouldProcess($Dest))
        {
            Set-Acl -Path $Dest -AclObject $acl -Passthru:$PassThru
        }
    }
}

Copy-Acl.ps1

0 comments

Discussion is closed.

Feedback usabilla icon