4
votes

I'm new to PowerShell.

I'm trying to automate the deployment of dll components from a folder on a source server to multiple folders on the destination server. This seems like it should be simple enough: copy components from source (deployment) folder on source server to folders on destination server, verify copies and finally delete components from deployment folder on source server.

The copying of the files from the source server to the destination server is working without issue. However, when the script moves on to delete the components from the source server, I'm intermittently confronted with the error: "Remove-Item error: Cannot remove item [item path & name]: Access to the path '[item path & name]' is denied."

I've run this script several times; sometimes it completes with no problems, sometimes with the error. The error does not occur for every file to be deleted and seems to occur on different components each time it presents.

Below is the function I have written to remove components and verify deletions:

function DeleteSourceFiles($srcPath) {
    # Announce delete
    OutputToHostAndLog ("Files will be removed from "+$srcPath+"...")
    OutputToHostAndLog "Removing files..."

    # Deletes all file items (i.e. all except folders) in source folder
    $filesToDelete=Get-ChildItem $srcPath | Where-Object {$_ -is [IO.FileInfo]}
    ForEach($item in $filesToDelete) {
        Remove-Item $srcPath\$item -force

        # Verify deletions       
        if(Test-Path($srcPath+"\"+$item)) {
            OutputToHostAndLog ("Delete failed: "+$item.Name)        
            $fail++
        }
        else {
            OutputToHostAndLog ($item.Name+" deleted successfully...")
        }
    }
 }

The use of the -force parameter with the Remove-Item cmdlet does not appear to have any effect on the issue. The files (again, different files with each failure) don't appear to be isReadOnly anyway.

Similarly, running PowerShell as Administrator seems to have no effect, although Get-Acl for the source folder indicates that Administrator should have FullControl.

Is this a permissions issue that I am missing? Any suggestions very much appreciated...

EDIT: I updated my script thus:

function DeleteSourceFiles($srcPath) {
    # Announce delete
    OutputToHostAndLog ("Files will be removed from "+$srcPath+"...")
    OutputToHostAndLog "Removing files..."
    OutputToHostAndLog $gap

    # Delete all file items (i.e. all except folders) in source folder
    $filesToDelete=Get-ChildItem $srcPath | Where-Object {$_ -is [IO.FileInfo]} | ForEach {
        Remove-Item $_.FullName -Force

        # Verify deletions
        if(Test-Path($srcPath+"\"+$_)) {
            OutputToHostAndLog ("Delete failed: "+$_.Name)        
            $fail++
        }
        else {
            OutputToHostAndLog ($_.Name+" deleted successfully...")
        }
    }
}

This seems to work OK although I'm still not sure why this arrangement should produce different results. In the interest of learning, any insights would be greatly appreciated...

3
I have a similar error (PSv3). I have a hunch that it is the script itself that is maintaining the lock. Your original script stores the files in a variable (creating a lock?). The second one deletes the file before storing in the variable. I'm having difficulty rearranging my script to prove this out.Jefferey Cave

3 Answers

6
votes

Intermittent access denied errors likely indicate that one or more of the files you're trying to remove has been locked by another application. It's a really common problem when you're trying to clean up log directories.

The only thing I'd recommend to do is wait for the application with the lock to release the file.

1
votes

I fixed this problem by setting the security permissions for users to have 'Modify' and 'Full Control' added for the folder I was trying to delete from

0
votes

I had this issue while running PowerShell in a Scheduled Task. I did a few things and it worked on the last one:

  1. Gave the user Full Control over the files in the folder.

  2. Made my group a principal

    a) e.g. New-ScheduledTaskPrincipal -GroupId "BUILTIN\Administrators" -RunLevel Highest

  3. Set the Task to use Highest Privileges:

scheduled task highest privileges