Scroll Top
Evotec Services sp. z o.o., ul. Drozdów 6, Mikołów, 43-190, Poland

Remove-Item : Access to the cloud file is denied while deleting files from OneDrive

PowerShellBlack

I like OneDrive. It allows me to keep my data secure and always synchronized. If things go wrong, I can always get it back. I use it for almost everything. Even for my PowerShell projects, which are committed to GitHub, so in theory, I shouldn't need that. But every once in a while, I make some stupid mistake and delete a file that has yet not been committed to GitHub, and that's where the OneDrive comes in handy. Quick restore, and we're back. Unfortunately, sometimes things aren't as I would expect them to work. For example, let's have a look at this nice list of markdown files that are documentation for my module called GPOZaurr.

Every time I would like to delete that content or anything from PowerShell it would throw me an error

Remove-Item : Access to the cloud file is denied

While I could understand the error if it was a file that is stored in the cloud, it's actually fully available on my drive, just synchronized to OneDrive. It wasn't always like that. It started happening a few months ago, so most likely some update caused it – or maybe it's the great Files On-Demand feature causing this issue. I don't know and I don't even want to go deep and test every possible combination where this happens. All I know is this impacts my scripts, as anything that is supposed to get deleted automatically and, for some reason, is stored on OneDrive gets hit with this error.

Remove-Item - Workaround for Access to the cloud file is denied issue

It seems the error only happens when trying to delete folders that contain those files.

Remove-Item -LiteralPath "C:\Support\GitHub\GpoZaurr\Docs" -Force -Recurse

It seems the problem comes from a directory, not the files themselves, so using a small workaround using Get-ChildItem to list and then delete all files helps to get rid of all files.

$Items = Get-ChildItem -LiteralPath "C:\Support\GitHub\GpoZaurr\Docs" -Recurse
foreach ($Item in $Items) {
    Remove-Item -LiteralPath $Item.Fullname
}

However retrying again deletion of a folder, even without files, still gives an error when using Remove-Item.

Remove-Item -LiteralPath "C:\Support\GitHub\GpoZaurr\Docs" -Force -Recurse

Remove-Item : Access to the cloud file is denied
At C:\Support\GitHub\GpoZaurr\Examples\Test.ps1:10 char:1

Did you know Remove-Item is not the only way to delete files and folders in PowerShell? Using Get-Item or Get-ChildItem, you're able to use Delete() method

$Item = Get-Item -LiteralPath "C:\Support\GitHub\GpoZaurr\Docs"
$Item.Delete($true)

To my surprise, the following method worked without a problem. This means to fully delete the folder with all files in it, we can use:

$Items = Get-ChildItem -LiteralPath "C:\Support\GitHub\GpoZaurr\Docs" -Recurse
foreach ($Item in $Items) {
    Remove-Item -LiteralPath $Item.Fullname
}
$Items = Get-Item -LiteralPath "C:\Support\GitHub\GpoZaurr\Docs"
$Items.Delete($true)

Since we're already using the Delete() method for a folder, why not try to do the same for the whole thing?

$Items = Get-ChildItem -LiteralPath "C:\Support\GitHub\GpoZaurr\Docs" -Recurse
foreach ($Item in $Items) {
    $Item.Delete()
}
$Items = Get-Item -LiteralPath "C:\Support\GitHub\GpoZaurr\Docs"
$Items.Delete($true)

Finally, I wanted to have a quick and easy way to reuse my code

function Remove-ItemAlternative {
    <#
    .SYNOPSIS
    Removes all files and folders within given path

    .DESCRIPTION
    Removes all files and folders within given path. Workaround for Access to the cloud file is denied issue

    .PARAMETER Path
    Path to file/folder

    .PARAMETER SkipFolder
    Do not delete top level folder

    .EXAMPLE
    Remove-ItemAlternative -Path "C:\Support\GitHub\GpoZaurr\Docs"

    .EXAMPLE
    Remove-ItemAlternative -Path "C:\Support\GitHub\GpoZaurr\Docs"

    .NOTES
    General notes
    #>
    [cmdletbinding()]
    param(
        [alias('LiteralPath')][string] $Path,
        [switch] $SkipFolder
    )
    if ($Path -and (Test-Path -LiteralPath $Path)) {
        $Items = Get-ChildItem -LiteralPath $Path -Recurse
        foreach ($Item in $Items) {
            if ($Item.PSIsContainer -eq $false) {
                try {
                    $Item.Delete()
                } catch {
                    Write-Warning "Remove-ItemAlternative - Couldn't delete $($Item.FullName), error: $($_.Exception.Message)"
                }
            }
        }
        $Items = Get-ChildItem -LiteralPath $Path -Recurse
        foreach ($Item in $Items) {
            try {
                $Item.Delete()
            } catch {
                Write-Warning "Remove-ItemAlternative - Couldn't delete $($Item.FullName), error: $($_.Exception.Message)"
            }
        }
        if (-not $SkipFolder) {
            $Item = Get-Item -LiteralPath $Path
            try {
                $Item.Delete($true)
            } catch {
                Write-Warning "Remove-ItemAlternative - Couldn't delete $($Item.FullName), error: $($_.Exception.Message)"
            }
        }
    } else {
        Write-Warning "Remove-ItemAlternative - Path $Path doesn't exists. Skipping. "
    }
}function Remove-ItemAlternative {
    <#
    .SYNOPSIS
    Removes all files and folders within given path

    .DESCRIPTION
    Removes all files and folders within given path. Workaround for Access to the cloud file is denied issue

    .PARAMETER Path
    Path to file/folder

    .PARAMETER SkipFolder
    Do not delete top level folder

    .EXAMPLE
    Remove-ItemAlternative -Path "C:\Support\GitHub\GpoZaurr\Docs"

    .EXAMPLE
    Remove-ItemAlternative -Path "C:\Support\GitHub\GpoZaurr\Docs"

    .NOTES
    General notes
    #>
    [cmdletbinding()]
    param(
        [alias('LiteralPath')][string] $Path,
        [switch] $SkipFolder
    )
    if ($Path -and (Test-Path -LiteralPath $Path)) {
        $Items = Get-ChildItem -LiteralPath $Path -Recurse
        foreach ($Item in $Items) {
            if ($Item.PSIsContainer -eq $false) {
                try {
                    $Item.Delete()
                } catch {
                    Write-Warning "Remove-ItemAlternative - Couldn't delete $($Item.FullName), error: $($_.Exception.Message)"
                }
            }
        }
        $Items = Get-ChildItem -LiteralPath $Path -Recurse
        foreach ($Item in $Items) {
            try {
                $Item.Delete()
            } catch {
                Write-Warning "Remove-ItemAlternative - Couldn't delete $($Item.FullName), error: $($_.Exception.Message)"
            }
        }
        if (-not $SkipFolder) {
            $Item = Get-Item -LiteralPath $Path
            try {
                $Item.Delete($true)
            } catch {
                Write-Warning "Remove-ItemAlternative - Couldn't delete $($Item.FullName), error: $($_.Exception.Message)"
            }
        }
    } else {
        Write-Warning "Remove-ItemAlternative - Path $Path doesn't exists. Skipping. "
    }
}

It seems I have no other choice than use this alternative approach to delete files and folders from my OneDrive, at least until Microsoft fixes this issue. Hopefully, sooner rather than later. Keep in mind that this function above is fundamental, with minimal error handling. If you intend to use it, make sure to add some error handling yourself. It's supposed to be a workaround rather than a permanent solution.

Related Posts