IT Diary (Jan 2021)

Windows upgrade fails because roaming.lock can’t be copied

The issue: Windows upgrades occasionally fail, the upgrade process rolls back to the original version. In setuperr.log, you find a message that the roaming.lock in the folder C:\Users\… \AppData\Local\Packages can’t be copied. The problem might be limited to environments with roaming profiles and/or folder encryption (advanced options: Encrypt contents to secure data) applied to the user folders. It seemed unpredictable under which circumstances and for which user and app it would occur.

The workaround: Delete all user profiles on the affected machines. In case you decide to use the code below, think twice about the damage it can potentially do when you delete user profiles including all data in them.

## Title: DeleteAllUserProfiles.ps1
## Deletes all user profiles – only use if you fully understand the consequences.
## Mind that you should adjust the log path in case you don't use ConfigMgr for deployment

function Write-log {




[ValidateSet("Info", "Warning", "Error")]

switch ($Type) {
"Info" { [int]$Type = 1 }
"Warning" { [int]$Type = 2 }
"Error" { [int]$Type = 3 }

# Create a log entry
$Content = "<![LOG[$Message]LOG]!>" +`
"<time=`"$(Get-Date -Format "HH:mm:ss.ffffff")`" " +`
"date=`"$(Get-Date -Format "M-d-yyyy")`" " +`
"component=`"$Component`" " +`
"context=`"$([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)`" " +`
"type=`"$Type`" " +`
"thread=`"$([Threading.Thread]::CurrentThread.ManagedThreadId)`" " +`

# Write the line to the log file
Add-Content -Path $Path -Value $Content

$logpath = 'c:\windows\ccm\logs\DeleteUserProfiles.log'
Write-Log -Message 'Starting to clean up' -Path $logpath -Component 'DeleteProfile' -Type Info

$profileFounds = 0

Try {
$profiles = Get-WmiObject -Class Win32_UserProfile -ComputerName $env:COMPUTERNAME -EnableAllPrivileges
} Catch {
Write-Log -Message 'Failed to retreive user profiles. Existing.' -Path $logpath -Component 'DeleteProfile' -Type Warning

ForEach ($profile in $profiles)
   $sid = New-Object System.Security.Principal.SecurityIdentifier($profile.SID)               
   $account = $sid.Translate([System.Security.Principal.NTAccount])
   $accountDomain = $account.value.split("\")[0]          
   $accountName = $account.value.split("\")[1]
   $profilePath = $profile.LocalPath
   $loaded = $profile.Loaded
  $special = $profile.Special

   Write-Log -Message "Start deleting profile ""$account"" on computer ""$computer"" ..." -Path $logpath -Component 'DeleteProfile' -Type Info
   Write-Log -Message "Account SID: $sid" -Path $logpath -Component 'DeleteProfile' -Type Info
   Write-Log -Message "Profile Path: $profilePath" -Path $logpath -Component 'DeleteProfile' -Type Info   
    Write-Log -Message "Loaded : $loaded" -Path $logpath -Component 'DeleteProfile' -Type Info   

   If ($loaded) {
       Write-Log -Message 'Cannot delete profile because is in use. Continuing to next profile.' -Path $logpath -Component 'DeleteProfile' -Type Warning

   Try {
       Write-Log -Message "Profile deleted successfully" -Path $logpath -Component 'DeleteProfile' -Type Info    
   } Catch {               
       Write-Log -Message "Error during delete the profile"-Path $logpath -Component 'DeleteProfile' -Type Error   

If($profileFounds -eq 0){
   Write-Log -Message "No profiles found on $ComputerName with Name $UserName" -Path $logpath -Component 'DeleteProfile' -Type Warning

Links: Remove-UserProfile.ps1