Office 365

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

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.

This post was last modified on March 5, 2022 09:59

Przemyslaw Klys

System Architect with over 14 years of experience in the IT field. Skilled, among others, in Active Directory, Microsoft Exchange and Office 365. Profoundly interested in PowerShell. Software geek.

Share
Published by
Przemyslaw Klys

Recent Posts

Upgrade Azure Active Directory Connect fails with unexpected error

Today, I made the decision to upgrade my test environment and update the version of…

2 days ago

Mastering Active Directory Hygiene: Automating Stale Computer Cleanup with CleanupMonster

Have you ever looked at your Active Directory and wondered, "Why do I still have…

4 months ago

Active Directory Replication Summary to your Email or Microsoft Teams

Active Directory replication is a critical process that ensures the consistent and up-to-date state of…

8 months ago

Syncing Global Address List (GAL) to personal contacts and between Office 365 tenants with PowerShell

Hey there! Today, I wanted to introduce you to one of the small but excellent…

1 year ago

Active Directory Health Check using Microsoft Entra Connect Health Service

Active Directory (AD) is crucial in managing identities and resources within an organization. Ensuring its…

1 year ago

Seamless HTML Report Creation: Harness the Power of Markdown with PSWriteHTML PowerShell Module

In today's digital age, the ability to create compelling and informative HTML reports and documents…

1 year ago