#Requires -Version 5.1 <# JbTecWiz Support Centre -- generated fix script Fault : A document always opens read-only Fix : Check write access to the folder Source: https://jbtecwiz.com/support/win-office-read-only Run as : PowerShell as the affected user Expect : 20 minutes Risk : low Reversible : yes WHEN THIS IS THE RIGHT FIX Everything in one folder or share opens read-only. HOW TO UNDO IT No client-side change was made. Any permission change on the server should be reversed by whoever applied it if it turns out to be wrong. This script walks the fix one step at a time and asks before each one. Steps with no command are things you do yourself -- it prints those and waits. Run with -DryRun to print without executing. #> [CmdletBinding()] param( # Print every step and command without running anything. [switch]$DryRun, # Do not ask before each step. Read the script first if you use this. [switch]$Unattended ) $ErrorActionPreference = 'Stop' $script:Failed = 0 # - THIS SCRIPT WILL NOT RUN UNTIL YOU EDIT IT - # The commands below contain values only you can supply. Search the # script for each one, replace it, then delete this block. $script:MustEdit = @( '\\server\share\folder' # a placeholder network path ) if ($script:MustEdit.Count) { Write-Host "" Write-Host ' This script needs editing before it can run.' -ForegroundColor Yellow Write-Host ' Replace each of these with a real value:' -ForegroundColor Yellow $script:MustEdit | ForEach-Object { Write-Host (" " + $_) -ForegroundColor Yellow } Write-Host "" Write-Host ' Then delete the $script:MustEdit block near the top.' Write-Host "" exit 2 } function Write-Rule { param([string]$Text) Write-Host '' Write-Host ('-' * 70) -ForegroundColor DarkGray if ($Text) { Write-Host $Text -ForegroundColor Cyan } } function Show-Prose { param([string]$Text, [string]$Colour = "Gray") if (-not $Text) { return } $words = $Text -split "\s+"; $line = " " foreach ($w in $words) { if (($line.Length + $w.Length) -gt 74) { Write-Host $line -ForegroundColor $Colour; $line = " " } $line += "$w " } if ($line.Trim()) { Write-Host $line -ForegroundColor $Colour } } function Invoke-Step { param( [int]$Number, [string]$Do, [string]$Why, [scriptblock]$Command, [switch]$Manual, [string]$Shell = "powershell" ) Write-Rule " Step $Number of 5" Show-Prose $Do "White" if ($Why) { Write-Host ""; Show-Prose $Why "DarkGray" } if ($Manual) { Write-Host '' Write-Host ' -> Do this yourself, then press Enter to carry on.' -ForegroundColor Yellow if (-not $Unattended -and -not $DryRun) { [void](Read-Host) } return } Write-Host '' foreach ($l in ($Command.ToString().Trim() -split "`n")) { Write-Host (" " + $l.Trim()) -ForegroundColor Green } Write-Host '' if ($DryRun) { Write-Host " (dry run -- not executed)" -ForegroundColor DarkGray; return } if (-not $Unattended) { $a = Read-Host " Run this step? [Y]es / [S]kip / [Q]uit" if ($a -match "^[Qq]") { Write-Host " Stopped at your request."; exit 0 } if ($a -match "^[Ss]") { Write-Host " Skipped." -ForegroundColor DarkGray; return } } try { & $Command } catch { $script:Failed++ Write-Host (" Step $Number failed: " + $_.Exception.Message) -ForegroundColor Red Show-Prose "The rest of the fix may depend on this. Read the write-up before carrying on." "Red" if (-not $Unattended) { $c = Read-Host " Carry on anyway? [y/N]" if ($c -notmatch "^[Yy]") { exit 1 } } } } Write-Rule Write-Host ' A document always opens read-only' -ForegroundColor White Write-Host ' Check write access to the folder' -ForegroundColor Cyan Write-Host '' Write-Host ' Risk: low Reversible 20 minutes' Write-Rule if (-not $Unattended -and -not $DryRun) { $go = Read-Host ' Ready? [y/N]' if ($go -notmatch "^[Yy]") { Write-Host " Nothing was changed."; exit 0 } } Invoke-Step -Number 1 -Do 'Test whether the user can actually write there, rather than reading the permissions and inferring it.' -Why 'Effective access on a share is the intersection of the share permission and the NTFS permission, and reading either one alone routinely gives the wrong answer. Writing a file is the only test that accounts for both.' -Command { try { $t = Join-Path '\\server\share\folder' ('wtest_' + [guid]::NewGuid() + '.tmp'); [IO.File]::WriteAllText($t,'x'); Remove-Item $t; 'WRITE OK' } catch { 'WRITE DENIED: ' + $_.Exception.Message } } Invoke-Step -Number 2 -Do 'If the write fails, look at both layers.' -Command { (Get-Acl '\\server\share\folder').Access | Select-Object IdentityReference, FileSystemRights, AccessControlType } Invoke-Step -Number 3 -Do 'On the file server, check the share-level permission as well.' -Command { Get-SmbShareAccess -Name 'share' | Select-Object AccountName, AccessRight } Invoke-Step -Number 4 -Do 'Have the permission corrected by whoever owns the share. Granting it locally on the client is not possible and attempting it wastes time.' -Manual Invoke-Step -Number 5 -Do 'If the write test succeeds and files still open read-only, go back to the attribute and document-protection fixes -- the share is not the cause.' -Manual Write-Rule " Confirm it worked" Show-Prose 'The write test succeeds and documents in the folder open for editing.' 'White' Write-Rule if ($script:Failed -gt 0) { Write-Host (" Finished with " + $script:Failed + " failed step(s).") -ForegroundColor Yellow Show-Prose 'Read the full write-up at https://jbtecwiz.com/support/win-office-read-only' 'Yellow' } else { Write-Host ' Finished.' -ForegroundColor Green } Write-Host '' Show-Prose 'To undo: No client-side change was made. Any permission change on the server should be reversed by whoever applied it if it turns out to be wrong.' 'DarkGray' Write-Rule