Script to cleanup old backup files permission denied

This topic contains 9 replies, has 2 voices, and was last updated by  Don Jones 4 years, 6 months ago.

  • Author
  • #11879

    Jonathon Olson

    I am getting an error trying to automatically remove old vhd files. These are owned by the system account and I have tried multiple ways to take ownership. This is what I have so far:

    #Remove the old backups
    $limit = (Get-Date).AddDays(-10)
    $path = "\\backup\sbs01_backup\"
    # Delete files older than the $limit.
    $files = Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit }
    Foreach ($file in $files) {
         $objUser = [Environment]::UserName
         $objFile = Get-Acl
         $objFile = $objFile.SetOwner($objUser)
         Set-Acl -aclobject $objFile -path $file.FullName
    Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
    # Delete any empty directories left behind after deleting the old files.
    Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse

    This is the error:

    Cannot convert argument "0", with value: "Administrator", for "SetOwner" to type "System.Security.Principal.IdentityReference": "Cannot convert the "Administrator" value of type "System.String"
    to type "System.Security.Principal.IdentityReference"."
    At C:\BackupScripts\Cleanup.ps1:11 char:34
    + $objFile = $objFile.SetOwner < <<< ($objUser) + CategoryInfo : NotSpecified: (:) [], MethodException + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument Set-Acl : Attempted to perform an unauthorized operation. At C:\BackupScripts\Cleanup.ps1:12 char:13 + Set-Acl <<<< -aclobject $objFile -path $file.FullName + CategoryInfo : PermissionDenied: (\\backup\sbs01_...06e6f6e6963.vhd:String) [Set-Acl], UnauthorizedAccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.SetAclCommand

    I've tried entering the username as domain\administrator, but that fails as well. There must be a better way to remove the files, it does work interactively and I can delete the files with explorer. The remote share is on a Buffalo NAS with no access restrictions set.

  • #11881

    Don Jones

    Welcome to .NET. Ugh.

    According to that error, it doesn't want a username at all. It wants an object of the type System.Security.Principal.IdentityReference (, and you're giving it a string, which is ticking it off. That's actually a base class, you probably want a System.Security.Principal.NTAccount.

    $account = New-Object -Type System.Security.Principal.NTAccount -Arg "DOMAIN","User"

    I'm guessing. Based on

  • #11882

    Don Jones

    You could also just use CACLS from your script.

  • #11884

    Don Jones

    Well, I don't know what you're doing interactively at the command line. There's a lot of ways a given tool can work; the Cmd.exe "Del" command uses some fairly low-level OS APIs. The PowerShell "Remove-Item" goes through .NET. So the behavior between the two isn't going to be identical.

    There isn't necessarily a difference in "how Windows applies permissions in script vs interactively." What's different are the tools you're using. In PowerShell, you're nearly always going through the .NET Framework unless using an external executable (like Cacls.exe). When you use the Explorer dialog box, there's entirely different code running. It isn't like Explorer is just running PowerShell under the hood ;). So the differences between a PowerShell command and the GUI dialog are probably massive. It isn't like there's one single "delete a file" mechanism in Windows that everything just calls into – unfortunately.

    It isn't how you're enumerating the objects, either.

    Think of it this way: I told you that, interactively riding a bike, I was able to get to the store. But when I got in my car, I couldn't get there. Massively different mechanisms to accomplish the same task. Maybe my car was out of gas. Maybe my garage door was closed. There's an entirely different thing happening with one mechanism vs the other.

  • #11885

    Jonathon Olson

    Thank you for the explanation, let me clarify.

    Remove-item works from the shell.
    PS C:\> remove-item '\\backup\SBS01_backup\Friday20131129\d\WindowsImageBackup\server\Backup 2013-11-30 002622\2d398a8b-7954-11de-9c9a-806e6f6e6963.vhd'
    PS C:\>

    But the script gets this error

    PS C:\Users\wgtadmin> C:\BackupScripts\Cleanup.ps1
    Remove-Item : Cannot remove item \\backup\sbs01_backup\Friday20131129\c\WindowsImageBackup\server\Backup 2013-11-30 000002\2d398a8a-7954-11de-9c9a-806e6f6e6963.vhd: Access to the path is denied.
    At C:\BackupScripts\Cleanup.ps1:14 char:125
    + Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item < <<< -Force + CategoryInfo : InvalidArgument: (\\backup\sbs01_...06e6f6e6963.vhd:FileInfo) [Remove-Item], ArgumentException + FullyQualifiedErrorId : RemoveFileSystemItemArgumentError,Microsoft.PowerShell.Commands.RemoveItemCommand Remove-Item : Cannot remove item \\backup\sbs01_backup\Saturday20131130\c\WindowsImageBackup\server\Backup 2013-12-01 000002\2d398a8a-7954-11de-9c9a-806e6f6e6963.vhd: Access to the path is denied.

    So I was wondering if I would be able to use remove-item in a different way in the script would it work?

  • #11886

    Don Jones

    You know those are two different paths, right? I'm not sure if that was supposed to be the case or not. One is point in to "D" and the other to "C." The error you're getting isn't about file ownership, I don't think. That's "Access Denied," not "Access to the Path Denied." What you're getting suggests that the path is inaccessible.

  • #11887

    Jonathon Olson

    Yes the script wouldn't get the "d" path after I had deleted the file. That's what I'm stuck on, I suspected ownership of the vhd file.

    PSMessageDetails :
    Exception : System.IO.DirectoryNotFoundException: Could not find a part of the path '\\backup\sbs01_backup\Sunday20131201\c\WindowsImageBackup\server\Catalog'.
    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.Directory.InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOpti
    on searchOption)
    at System.IO.DirectoryInfo.GetDirectories(String searchPattern, SearchOption searchOption)
    at Microsoft.PowerShell.Commands.FileSystemProvider.Dir(DirectoryInfo directory, Boolean recurse, Boolean nameOnly, ReturnContainers returnContainers)
    TargetObject : \\backup\sbs01_backup\Sunday20131201\c\WindowsImageBackup\server\Catalog
    CategoryInfo : ReadError: (\\backup\sbs01_...C-SBS01\Catalog:String) [Get-ChildItem], DirectoryNotFoundException
    FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChildItemCommand
    ErrorDetails :
    InvocationInfo : System.Management.Automation.InvocationInfo
    PipelineIterationInfo : {0, 1, 26, 1}

    Looks like it might just be a space. Backup Exec is getting put in soon 🙂 I'm using this challenge to practice PowerShell so I really do appreciate the help.

  • #11889

    Don Jones

    Yeah, don't know what to tell you but this isn't a permissions issue, I don't think. I mean, if Remove-Item deletes it manually, then Remove-Item should work the same from a script. No difference. It's something in the value the script is working with.

    So you try to access each successive piece of the path, one at a time, to see when it fails. Can you delete a file from \\backup\sbs01_backup? Just make a little text file, and try to delete it from within a script.

    In your existing script, can you – again, as a test – paste a manually typed, hardcoded path? Does it work then? Maybe copy-and-paste the path from a console session that WORKS, so you KNOW you've got a valid path.

    Tests like that help tell us what's going wrong.

  • #11883

    Jonathon Olson

    I tried subinacl but was having a tough time passing the objects in the loop as the path parameter. It also didn't like the /subdirectories being used with a UNC path. I'll look into the CACLS option. Why does the script fail to delete the object when I can delete it from the command line interactively? Maybe I don't need to set permissions. What is the difference in how windows applies the permissions in script vs interactively? Or is it the object that is different? Is there a better way to enumerate the objects that will pass them to remove-item and work?

  • #11888

    Jonathon Olson

    No, this error shows full path.

    PSMessageDetails      : 
    Exception             : System.ArgumentException: Access to the path is denied.
                               at System.IO.FileSystemInfo.set_Attributes(FileAttributes value)
                               at Microsoft.PowerShell.Commands.FileSystemProvider.RemoveFileSystemItem(FileSystemInfo fileSystemInfo, Boolean force)
    TargetObject          : \\backup\sbs01_backup\Sunday20131201\c\WindowsImageBackup\server\Backup 2013-12-02 000002\2d398a8a-7954-11de-9c9a-806e6f6e6963.vhd
    CategoryInfo          : InvalidArgument: (\\backup\sbs01_...06e6f6e6963.vhd:FileInfo) [Remove-Item], ArgumentException
    FullyQualifiedErrorId : RemoveFileSystemItemArgumentError,Microsoft.PowerShell.Commands.RemoveItemCommand
    ErrorDetails          : Cannot remove item \\backup\sbs01_backup\Sunday20131201\c\WindowsImageBackup\server\Backup 2013-12-02 000002\2d398a8a-7954-11de-9c9a-806e6f6e6963.vhd: Access to the 
                            path is denied.
    InvocationInfo        : System.Management.Automation.InvocationInfo
    PipelineIterationInfo : {0, 1, 26, 3}

    So a mapped drive? That didn't work either.

You must be logged in to reply to this topic.