вторник, 11 января 2022 г.

Access. Не возможно открыть базу данных, файл уже используется

Посвящается бедолагам, кто любит ставить свежие обновления Office. В середине декабря, вышло обновление KB5002104 (Office 2013) и KB5002099 (Office 2016) которое закрывало уязвимость ядра при подключении к базе данных Microsoft Jet Red. Но имело одну известную проблему с совместным доступом к файлу базы данных Access на сетевом диске или DFS.
Microsoft выпустили заплатку для Office 2013 KB2965317 и Office 2016 KB4484211, но к несчастью, они решали проблему только для файлов расположенных в сети по UNC-путям. Статус выхода обновлений можно посмотреть тут.
Как счастливый обладатель файлового сервера на DFS, для меня единственным решением оказалось удалить обновления KB5002104 и KB5002099. 

Патчи для Office удаляются через msiexec с указанием GUID пакета самого офиса и GUID обновления. Выглядит так
# Office 2013 x32
"/package {90150000-0011-0000-0000-0000000FF1CE}"
# Office 2013 x64
"/package {90150000-0011-0000-1000-0000000FF1CE}"
# Office 2016 x32
"/package {90160000-0011-0000-0000-0000000FF1CE}"
# Office 2016 x64
"/package {90160000-0011-0000-1000-0000000FF1CE}"
# Office 2013 x32 KB5002104
"/uninstall {8FE4AEF3-DE32-4A09-9302-BB30F9088699}"
# Office 2013 x64 KB5002104
"/uninstall {AC593D32-2D34-48A1-82B5-52FC0CFDA409}"
# Office 2016 x32 KB5002099    
"/uninstall {BA36399C-CF0F-4368-8327-7D35302BF0BB}"
# Office 2016 x64 KB5002099
"/uninstall {127B2615-3D07-4189-B91C-44A04FB7A55F}"
Расшифровка GUID для Office, советую почитать. Чтобы узнать GUID обновления, необходимо его скачать, разархивировать и просмотреть в свойствах файла .MSP вкладку Подробно, строка Редакция

GUID установщика Office можно посмотреть в реестре для Office 2016
HKEY_LOCAL_MACHINE \Software\Microsoft\Windows\CurrentVersion\Uninstall
Для х32 разрядной Office 2016 на Windows x64
HKEY_LOCAL_MACHINE \Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
Для удаленного выполнения кода, можно использовать Invoke-Command. Например Office 2016 x64
Invoke-Command -ComputerName comp01 {msiexec.exe /package '{90160000-0011-0000-1000-0000000FF1CE}' /uninstall '{127B2615-3D07-4189-B91C-44A04FB7A55F}' /qn /l*v c:\office.log /norestart}
Смотрим в лог-файл, ищем строчки MSI (s) (18:14) [10:50:19:162]: Продукт: Microsoft Office Professional Plus 2016 - пакет обновлений "Security Update for Microsoft Office 2016 (KB5002099) 32-Bit Edition" успешно удален. MSI (s) (18:14) [10:50:19:163]: Установщик Windows выполнил удаление обновления. Продукт: Microsoft Office Professional Plus 2016. Версия: 16.0.4266.1001. Язык: 0. Изготовитель: Microsoft Corporation. Обновление: Security Update for Microsoft Office 2016 (KB5002099) 32-Bit Edition. Удаление завершено с состоянием: 0. Или смотрим системный журнал
Перезагружаем рабочую станцию и пробуем открыть файлы баз данных на файловом сервере.

Небольшая функция для удаления этих обновлений в зависимости от установленного пакета MS Office. Применимо для Office 2013, 2016 x32-x64
# Функция удаляет обновление для MS Office KB5002104, KB5002099 
# https://www.devhut.net/access-lock-file-issues/
# Example: Remove-OfficeKB -Computername Comp1 -Result

function Remove-OfficeKB { # Удаление обновлений KB MS Office 2013-2016
        param(
          [parameter(Mandatory=$true)][string]$ComputerName,
          [switch]$Result
        )
# Версии Office 
$2013x32 = '{90150000-0011-0000-0000-0000000FF1CE}'
$2013x64 = '{90150000-0011-0000-1000-0000000FF1CE}'
$2016x32 = '{90160000-0011-0000-0000-0000000FF1CE}'
$2016x64 = '{90160000-0011-0000-1000-0000000FF1CE}'
# GUID обновлений
# Office 2013 x32 KB5002104
$KB5002104x32 = '{8FE4AEF3-DE32-4A09-9302-BB30F9088699}'
# Office 2013 x64 KB5002104
$KB5002104x64 = '{AC593D32-2D34-48A1-82B5-52FC0CFDA409}'
# Office 2016 x32 KB5002099    
$KB5002099x32 = '{BA36399C-CF0F-4368-8327-7D35302BF0BB}'
# Office 2016 x64 KB5002099    
$KB5002099x64 = '{127B2615-3D07-4189-B91C-44A04FB7A55F}'

# Собираем информацию об установленном пакете Office
$Session = New-PSSession -ComputerName $ComputerName
$OfficeVersion = Invoke-Command -Session $Session -ScriptBlock {
# Ищем 64х...
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\{901?0000-001?-0000-?000-0000000FF1CE}"
# ...или 32х
Get-ItemProperty "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{901?0000-001?-0000-?000-0000000FF1CE}"}
Remove-PSSession -Session $Session

if ($OfficeVersion.PSChildName -like $2013x32) {
    Write-Host "Office 2013 x32" $OfficeVersion.DisplayVersion
    $Session = New-PSSession -ComputerName $ComputerName
    Invoke-Command -Session $Session -ScriptBlock {
        Start-Process msiexec.exe -ArgumentList "/package $using:2013x32 /uninstall $using:KB5002104x32 /qn /l c:\office.log /norestart" -Wait -NoNewWindow
        if ($using:Result) {gc c:\office.log | ? {$_.trim() -ne "" }}}
        Remove-PSSession -Session $Session}

    elseif ($OfficeVersion.PSChildName -like $2013x64) {
        Write-Host "Office 2013 x64" $OfficeVersion.DisplayVersion
        $Session = New-PSSession -ComputerName $ComputerName
        Invoke-Command -Session $Session -ScriptBlock {
            Start-Process msiexec.exe "/package $using:2013x64 /uninstall $using:KB5002104x64 /qn /l c:\office.log /norestart" -Wait -NoNewWindow
            if ($using:Result) {gc c:\office.log | ? {$_.trim() -ne "" }}}
            Remove-PSSession -Session $Session}

        elseif ($OfficeVersion.PSChildName -like $2016x32) {
            Write-Host "Office 2016 x32" $OfficeVersion.DisplayVersion
            $Session = New-PSSession -ComputerName $ComputerName
            Invoke-Command -Session $Session -ScriptBlock {
                Start-Process msiexec.exe "/package $using:2016x32 /uninstall $using:KB5002099x32 /qn /l c:\office.log /norestart" -Wait -NoNewWindow
                if ($using:Result) {gc c:\office.log | ? {$_.trim() -ne "" }}}
                Remove-PSSession -Session $Session}

            elseif ($OfficeVersion.PSChildName -like $2016x64) {
                Write-host "Office 2016 x64" $OfficeVersion.DisplayVersion
                $Session = New-PSSession -ComputerName $ComputerName
                Invoke-Command -Session $Session -ScriptBlock {
                    Start-Process msiexec.exe "/package $using:2016x64 /uninstall $using:KB5002099x64 /qn /l c:\office.log /norestart" -Wait -NoNewWindow
                    if ($using:Result) {gc c:\office.log | ? {$_.trim() -ne "" }}}
                    Remove-PSSession -Session $Session}
        }
UPD! Ошибка может появиться снова в случае работы с файлами access на DFS, после установки куммулятивного обновления Office 2013 KB5002124 и Office 2016 KB5002115. В моём случае их тоже пришлось сносить. Вот GUID на всякий случай
# Office 2013 x32 KB5002124
$KB5002124x32 = '{C2EB2330-109A-41ED-BE10-A96B1070A71E}'
# Office 2013 x64 KB5002124
$KB5002124x64 = '{F9CEB20C-D32C-4A59-8860-AEF3F8B2CBC6}'
# Office 2016 x32 KB5002115
$KB5002115x32 = '{7D23F5C5-1019-4950-AF7D-C4418561302C}'
# Office 2016 x64 KB5002115
$KB5002115x64 = '{AB2C1CFF-4398-4F2F-AA8C-A39DA5A6F84B}'

Комментариев нет :

Отправить комментарий