header
header Register : : Login header
header
divider
menuleft
menuright
submenu
left

We have a new sponsor!  Introducting Pragma Systems.  See the home page for details.

Stamp ACL onto Directory Tree
Last Post 03 Apr 2008 04:54 AM by radagenais. 11 Replies.
Printer Friendly
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
AythUser is Offline
Basic Member
Basic Member
Posts:173
Avatar

--
18 Oct 2007 09:37 PM  
Hello,

I have a problem I've ran into regarding get-acl. What I'm trying to do is essentially stamp a directory structure with a particular ACL. I attempted to "push" the appropriate permissions down through Explorer, as I normally would, but it's not working. I'm a domain admin, admin on the local box etc, but it's causing me headaches. I also took ownership of all the files, then tried to push them down, not working for me.

So basically, I thought, hey I can do this via Powershell. I recently stumbled onto the PowerScripting Podcast by Jonathan Walz, and he had a "one-liner" of:

get-childitem -recurse | get-acl | where-object {$_.AccessToString -notlike “*SYSTEM Allow  FullCon*”}

I changed things around slightly, created a variable containing the ACL of a folder I knew was correct, then ran the following code:

get-childitem -recurse | get-acl | where-object {$_.AccessToString -notlike “Domain\User Allow  FullCon*”} | set-acl -ACLObject $HRAcl

However, I got an error as well, so I just decided to stamp the entire structure, like so:

get-childitem -recurse | get-acl | set-acl -ACLObject $HRAcl

Still no luck, the error message I get with all these commands is:

Get-Acl : The specified wildcard pattern is not valid: TRANSPARENCY -CONCLUSION [ ORGANIZATIONAL CULTURE.doc
At line:1 char:33
+ get-childitem -recurse | get-acl  <<<< | set-acl -AclObject $HRAcl

Interesting thing to note is the ACL gets plastered onto the current directory, but when it tries to do the sub-directories, is where the problem starts. Any ideas?

BTW, Marco if you read this, when is the next Virtual User group meeting? I'm in HFX, and waiting. Thanks.
My Blog about Powershell http://poweroftheshell.blogspot.com/ Follow me on twitter @darrinhenshaw
marco.shawUser is Offline
Site Moderator
Advanced Member
Advanced Member
Posts:653
Avatar

--
19 Oct 2007 01:42 AM  

Possible that the special characters are causing issues?  Try a "-whatif" just for fun.

Next PSH virtual user group is likely going to be Dec 4th.  I hope to "see" you there.

Marco

*Microsoft MVP - Windows PowerShell
https://mvp.support.microsoft.com/profile/Marco.Shaw
*Co-Author - Sams Windows PowerShell Unleashed 2nd Edition
*Blog - http://marcoshaw.blogspot.com
DonJUser is Offline
PowerShell MVP
Basic Member
Basic Member
Posts:134
Avatar

--
19 Oct 2007 02:45 PM  
Looking at your last one-liner, I'm not sure I follow... You're getting all the child items, got it. For each one, you're getting their ACLs. But then you're passing all those ACLs to Set-ACL... and setting them where? E.g., all Set-ACL is getting is a collection of ACLs... not files or folders... no?
- Don Jones
www.ConcentratedTech.com
Subscribe (RSS) or visit for weekly PowerShell tips and lessons
marco.shawUser is Offline
Site Moderator
Advanced Member
Advanced Member
Posts:653
Avatar

--
19 Oct 2007 03:59 PM  
Don is right...

You want to push the same ACL down the entire tree?

First, get an ACL object:
$aclobj=get-acl some_file
Then, apply that ACL
get-childitem -recurse|set-acl -aclobject $aclobj

I lack a place to test playing with ACLs right now.
Marco

*Microsoft MVP - Windows PowerShell
https://mvp.support.microsoft.com/profile/Marco.Shaw
*Co-Author - Sams Windows PowerShell Unleashed 2nd Edition
*Blog - http://marcoshaw.blogspot.com
AythUser is Offline
Basic Member
Basic Member
Posts:173
Avatar

--
19 Oct 2007 04:44 PM  
Bah, I knew it was something stupid like that. However, I just tried marco's suggestion and the same error comes back, so I tried his other suggestion, using the -whatif parameter, and the error happens, but I have more to go on see the following:

What if: Performing operation "Set-Acl" on Target "Microsoft.PowerShell.Core\FileSystem::Z:\OTHER ATTORNEYS\Karen\KWS\PE
RSONAL\WEBSTER UNIVERSITY\TRANSPARENCIES-ORGANIZATIONAL CULTURE.doc".
Then it tries the next file and generates the error:
Set-Acl : The specified wildcard pattern is not valid: TRANSPARENCY -CONCLUSION [ ORGANIZATIONAL CULTURE.doc
At line:1 char:31
+ get-childitem -recurse|set-acl <<<< -aclobject $hracl -whatif

Seems to me that the path "Z:\OTHER ATTORNEYS\Karen\KWS\PE
RSONAL\WEBSTER UNIVERSITY\TRANSPARENCY -CONCLUSION [ ORGANIZATIONAL CULTURE.doc", is being passed down, but powershell is interpreting the "[" in the file name as a wildcard patternof sorts, and is therefore failing. I'm not sure, anyone know how to I can get powershell to escape all the characters that are piped from get-childitem? Thanks.
My Blog about Powershell http://poweroftheshell.blogspot.com/ Follow me on twitter @darrinhenshaw
jonwalzUser is Offline
New Member
New Member
Posts:1
Avatar

--
21 Oct 2007 04:00 AM  

I’ve been playing with this and it’s a strange problem. Every cmdlet I have tried to use on a file named test[.doc has failed with this same error which is a terminating error. The thing that’s odd is that it’s a terminating error even when I set $ErrorActionPreference to “silentlycontinue.”  I have not found a way to output information about these “bad file names” without having the statement break at the first bad file name and stop.

Here’s what you can do to get around this error. The problem with this method is that your ACL will not get pushed to any files that have problematic characters in them. It will also not tell you what which files were skipped. It will however bypass the problematic files and push the ACL to all the other files (or at least that’s what I saw during my testing.

get-childitem -recurse | Where-Object {Test-Path $_.fullpath} | get-acl | where-object {$_.AccessToString -notlike “Domain\User Allow  FullCon*”} | set-acl -ACLObject $HRAcl

I have found that Test-Path will not return $True for my test[.doc file so that file does not get passed to get-acl to trigger the error. As I said, the downside is you don’t get to see the files that were skipped.

Hope this helps,

Jonathan Walz

http://PowerScripting.net

jdelatorreUser is Offline
New Member
New Member
Posts:18
Avatar

--
23 Oct 2007 10:29 PM  
You can also use the Parameter "LiteralPath" when using the Test-path cmdlet.  This does not suffer from this problem

 ls -Recurse -Include *.* | % {test-path -literalpath $_.fullname}
Joel D.
DonJUser is Offline
PowerShell MVP
Basic Member
Basic Member
Posts:134
Avatar

--
25 Oct 2007 02:57 PM  
Posted By jonwalz on 10/20/2007 8:00 PM

The thing that’s odd is that it’s a terminating error even when I set $ErrorActionPreference to “silentlycontinue.”


The $ErrorActionPreference just controls whether or not objects in the Error pipeline are displayed - e.g., it suppresses error messages, but doesn't stop errors from occurring. You'd need to set the cmdlet's -ErrorAction (-EA) parameter - setting IT to "SilentlyContinue" will usually make it ignore errors and continue. However, in the event of a truly terminal error, you'd set -EA to "Stop" and build a trap to deal with the error.
- Don Jones
www.ConcentratedTech.com
Subscribe (RSS) or visit for weekly PowerShell tips and lessons
AythUser is Offline
Basic Member
Basic Member
Posts:173
Avatar

--
29 Oct 2007 04:11 PM  
Thanks for all the help guys, I originally used Jonathan's work around, then manually found the files it missed and set them right. However, I then went back and used jdelatorre's fix, because I was unsure as to whether it really hit all files.

Thanks.
My Blog about Powershell http://poweroftheshell.blogspot.com/ Follow me on twitter @darrinhenshaw
PoshoholicUser is Offline
PowerShell MVP
New Member
New Member
Posts:94
Avatar

--
29 Oct 2007 08:13 PM  

Hi guys,

I just wanted to follow-up on this.  Did anyone log this issue on the MS Connect site so that Microsoft knows about it and can fix it in the future?

-
Kirk Munro
Poshoholic
http://poshoholic.com

Kirk Munro [MVP]
Poshoholic

My blog: http://poshoholic.com
Follow me on Twitter: http://twitter.com/poshoholic
SAPIENScripterUser is Offline
New Member
New Member
Posts:47

--
30 Oct 2007 05:00 PM  
There is a known problem when working with filenames that have a [ or ] in the name, plus probably a few others. The literalpath parameter is the best way around them now. As far as I know this has been posted as an official issue.
Jeffery Hicks
Microsoft PowerShell MVP
http://blog.sapien.com
http://www.scriptinganswers.com

"Those who forget to script are doomed to repeat their work."
radagenaisUser is Offline
New Member
New Member
Posts:1
Avatar

--
03 Apr 2008 04:54 AM  

I had a similar problem with set-acl and square brackets. I tried converting the path to a string first and then passed it as a variable to set-acl, with the path wrapped in quotes.

$itempath = $item.FullName.ToString()
Set-Acl -path "$itempath" -aclObject $acl

The behavior changed to no errors, but upon closer inspection items with special characters had everything but the ownership changed(!?)

set-acl bug?  :-/

I tested with a directory with 10 subdirectories. 8 of them had the same name as valid domain users, and the other two had names that didn't match users, including one with funky characters.

In the valid user folders were tons of files and subdirectories. Of these, 3 contained both directories and files with funky characters at various levels of the hierarchy.

I put quite a bit of data in these to get an idea of ps resource usage before I set the script loose on a whole terabyte of data.

My script leans on the PowerShell Community Extensions.

Last thoughts before I go home to sleep - regex the string and insert ticks before the illegal chars. Embedded .replace() would suck. What a hack.


This is my first script, so please give me feedback. Any in-the-box ideas how to handle the special characters?

I'm hoping someone might find this useful too..


Full script:

$workdir = "Z:\TEST\"
$workdom = "domain.dom"
$workdomshort = "DOMAIN"

# we skip directories beginning with underscore character
$paths = ( Get-ChildItem $workdir -Exclude "_*" )

# validate before we begin
# todo: test domain, test path
Write-Host "Working directory is: $workdir"
Write-Host "Working domain is:    $workdom"
$bail = Read-Host -Prompt "Continue? [y/n]"
if ( $bail -ne "y" ) { exit 0 }

Set-Location -path $workdir

#PSCX trick to allow change ownership to different user
$SeRestore = New-Object Pscx.Interop.TokenPrivilege "SeRestorePrivilege", $true
Set-Privilege $SeRestore

# scan profile directories and set ownership for each
foreach ( $path in $paths )
    {
    Write-Host "** Examining " -NoNewline
    Write-Host -backgroundcolor red "[ $path ]" -nonewline
    Write-Host " and contents...**"
   
    # extract the short name of the path

    # which should be the same as the owner
    $ownedby = ( Split-Path -leaf $path.Name )

    if ( ( get-adobject -value $ownedby ) -ne $null )
        {
        Write-Host "User: " -nonewline
        Write-Host -backgroundcolor red $ownedby -nonewline
        Write-Host " exists!"
        #
        ## set up acl
        Write-Host "Building ACL... " -NoNewline
        $acl = Get-Acl -path $path # start with existing ACL
        #
        ## define user access, inheritance, propagation
        $principal = "$workdomshort\$ownedby"
        $inheritance = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
        $propagation=[System.Security.AccessControl.PropagationFlags]::None
        $args = $principal, "Modify", $inheritance, $propagation, "Allow"
        $accessrule = New-Object System.Security.AccessControl.FileSystemAccessRule $args
        $acl.SetAccessRule($accessrule)
        #
        ## define ownership
        $account = New-Object System.Security.Principal.NTAccount("$workdomshort","$ownedby")
        $acl.SetOwner($account)
        #
        Write-Host "done."
        #
        # do it to parent first
        Write-Host "Applying ACL to profile directory... " -NoNewline
        Set-Acl -Path $path -AclObject $acl
        Write-Host " done."
        #
        # now do it, all recursive-like
        $items = ( Get-ChildItem -Recurse -Path $path )
        Write-Host "Applying ACL to profile directory contents..." -NoNewline
        if ( $items -ne $null )
            {
            foreach ( $item in $items )
                {
                $itempath = $item.FullName.ToString()
                Set-Acl -path "$itempath" -aclObject $acl
                Write-Host "." -nonewline
                }

            Write-Host " done!"
            Write-Host ( $items.count ) " items modified."
            Write-Host
            }
            else
            {
            # in case of empty profile   
            Write-Host "n/a"
            Write-Host
            }
        }
        else
        {
        # bogus user, rename directory   
        Write-Host "User: $owndedby does not exist! `a"
        $pathbad = ( "_" + "$ownedby" )
        Write-Host -backgroundcolor RED  "Renaming $path to $pathbad"
        ren $path $pathbad
        Write-Host
        }
}

You are not authorized to post a reply.

Active Forums 4.1
right
   
footer Sponsored by Quest Software • SAPIEN Technologies • Compellent • Microsoft Windows Server 2008 footer
footer