Помощь оказана [CMD/Powershell] Восстановить права доступа к файлам после переустановки Windows

kww

Новый пользователь
Сообщения
16
Реакции
2
Во время переустановки винды, я удалил только старые разделы винды (системный раздел, зарезервированный раздел и раздел ESP). То есть остальные остались как есть. Теперь, впрочем, как и обычно, я стал для тех дисков никем, какие-то файлы принадлежат группе администраторов, поэтому я вроде как могу с ними чё-то делать, а какие-то принадлежат пользователю с прошлой установки.

Мне пришла "интересная" идея скриптом рекурсивно завладеть всеми файлами, которыми владеет S-1-5-21-449789199-987631865-2024635987-1001 (старый пользователь), и также выдать права на полный доступ. Я попросил чат гпт сделать для меня bat скрипт для этого, но потом я вспомнил одни случай и засомневался, поможет ли это мне...
[CODE lang="batch" title="Вот это он (я подправил его, так как там с синтаксисом takeown что-то не так было)"]@echo off
:: Если не закомментировать эту строку, то все файлы с восклицательным знаком кидают ошибку
::setlocal enabledelayedexpansion

rem Set the current user
set "currentuser=%USERNAME%"

rem Set the directory path
set "directory=%~dp0"

rem Cycle through all files recursively in the directory
for /r "%directory%" %%a in (*) do (
rem Check the owner of the file
for /f "tokens=2 delims=:" %%b in ('icacls "%%a" ^| findstr "S-1-5-21-449789199-987631865-2024635987-1001"') do (
rem Replace the owner with the current user
:: Это предложил гпт и оно не работает
::takeown /F "%%a" /U %currentuser% /A /R /D Y
:: А этого вроде как должно хватить
takeown /F "%%a"
icacls "%%a" /setowner %currentuser% /T
)
)

echo Ownership changed successfully.
pause[/CODE]


Была папка на рабочем столе, она принадлежала так же тому пользователю, я её пытался удалить - винда пишет "запросите разрешение от Администраторы". Я сделал себя её владельцем, выдал права на полный доступ и при повторной попытке удаления мне пишет "запросите разрешение от DESKTOP-NASRAL\kww" (моё имя пользователя). Не помню уже, как я с ней разобрался, может выключил наследование разрешений для этой папки и тогда смог удалить...

Так вот, правильно ли я придумал насчёт скрипта или есть вариант получше?

Ещё я пробовал на всякий случай сохранить права в файл командой
Код:
icacls D:\ /save d:\aclbkp.txt /T /C /Q
Но в таком случае мне выдавало ошибки на очень длинные имена, наподобие
Код:
D:\suction\ideaIU-2022.1.4.win\.IntelliJIdea\system\index\shared_indexes\shared.index.hashes.org.jetbrains.kotlin.idea.vfilefinder.KotlinPackageSourcesMemberNamesIndex\shared.index.hashes.org.jetbrains.kotlin.idea.vfilefinder.KotlinPackageSourcesMemberNamesIndex_storage.storage.keystream.len: Системе не удается найти указанный путь.
Это натолкнуло меня на мысль, что этот цикл может не сработать на супер-длинные пути...
 
Последнее редактирование:
По поводу фикса скрипта, то дождитесь ответа @Dragokas

++
 
@kww, через смену владельца ни в коем случае нельзя для всего диска. Вы этим отзовёте права у системы, там где они настроены через владельца, а не через список доступа. И кроме того понизите уровень безопасности в целом. Если речь идёт о системном диске, конечно. Для других не так плачевно.

Для подмены SID существует icacls /substitute
Подробнее как этим пользоваться можете почитать здесь: Is there an Icacls function similar to /replace in subinacl? (там нужно обязательно в две команды выполнять)
И затем сперва потренироваться на чём-то более скромном.
Чтобы затем не получать ошибки с правами доступа при попытке замены DACL, операцию нужно выполнять от имени пользователя Local System или Trusted Installer. Например, запустить батник через ExecTI.

Разумеется, это с учетом ограничений утилиты. Там у нее кроме максимального пути, есть еще баг с симлинками, если заюзаете ключ рекурсивного прохода.
На счёт обхода проблемы с макс. путями, можно попробовать добавить префикс \\?\ перед путём, например:
Код:
\\?\D:\путь

На счёт SetACL Studio, да там можно, но через ее консольную версию (setacl), а не графическую. См. параметр -trst

Код писать не буду. У меня от кодинга сегодня отдых. :)
 
@kww, через смену владельца ни в коем случае нельзя для всего диска. Вы этим отзовёте права у системы, там где они настроены через владельца, а не через список доступа. И кроме того понизите уровень безопасности в целом. Если речь идёт о системном диске, конечно. Для других не так плачевно.
Да, речь не о системном разделе. У меня так всё устроено, что рабочий стол, документы и загрузки я перенес на другой раздел и если при установке программы можно выбрать путь, я его тоже отсылаю туда же. Т.е. по возможности стараюсь не на системный диск устанавливать. Мне показалось, что как раз было бы достаточно заменить все упоминания того SID на свой (новый).

Разумеется, это с учетом ограничений утилиты. Там у нее кроме максимального пути, есть еще баг с симлинками, если заюзаете ключ рекурсивного прохода.
На счёт обхода проблемы с макс. путями, можно попробовать добавить префикс \\?\ перед путём, например:
Прописал команду для теста, ошибку не выдало, стал владельцем.
Код:
icacls "\\?\D:\suction\ideaIU-2022.1.4.win\.IntelliJIdea\system\index\shared_indexes\shared.index.hashes.org.jetbrains.kotlin.idea.vfilefinder.KotlinPackageSourcesMemberNamesIndex\shared.index.hashes.org.jetbrains.kotlin.idea.vfilefinder.KotlinPackageSourcesMemberNamesIndex_storage.storage.keystream.len" /setowner %username%
но это с ручной заменой, если на каждый файл в цикле вызывать. А как побороть это дело при использовании icacls /save - уже выше моего понимания

Баг с симлинками - это можно в бесконечный цикл попасть?
 
Последнее редактирование:
Да, речь не о системном разделе. У меня так всё устроено, что рабочий стол, документы и загрузки я перенес на другой раздел и если при установке программы можно выбрать путь, я его тоже отсылаю туда же. Т.е. по возможности стараюсь не на системный диск устанавливать. Мне показалось, что как раз было бы достаточно заменить все упоминания того SID на свой (новый).
Понятно. Тогда это норм, если для собственных папок юзера. А если речь уже о C:\ProgramData или %UserProfile%\AppData\Roaming то не норм.

Описание варианта icacls (не работает из-за бага, ибо: мы вообще-то маленькая фирма, у нас тут на носу выход Windows 12, нахрена нам чинить всякие консольные сикьюрити утилиты, вон PowerShell вышел, берите пользуйтесь)
А как побороть это дело при использовании icacls /save - уже выше моего понимания
по примеру выше:
Код:
icacls * /save acls.bak
icacls . /substitute oldsid newsid /restore acls.bak
Вместо * указываете путь. Первой командой всё сохраняется в файл acls.bak. Возможно, придется добавить флаг рекурсии /T
Во вторую команду подставляете вместе oldsid сид старого пользователя в формате: *SID
Взять его можно, вызвав:
Код:
icacls "папка"
Все SID-ы будут расшифрованы в известные имена, а для неизвестного юзера увидите запись в формате SID-а, вроде такого:
Код:
S-1-5-21-xxx
Вместо newsid подставляете сид нового юзера в формате *SID. Достать его можно, например через PsGetSid. Примеры. Или открыв regedit - там в HKEY_USERS самые длинные имена ключей и будет SID текущего загруженного юзера.

Соответственно в команду нужно прописать что-то вроде:
Код:
cd /d "папка"
icacls * /save acls.bak /T
icacls . /substitute *S-1-5-21-old *S-1-5-21-new /restore acls.bak
при том, выполнять команды нужно обязательно предварительно перейдя в каталог, который является родительским по отношению к обрабатываемым объектам - через команду cd.
Правда, у меня не получилось, команда выдала такую багу:
Код:
what?  Flags == 10000000
Возможно, на Win10 починили. Я пробовал на Win7. Ещё аналогичный функционал предоставляет утилита subinacl из состава древнего набора Windows 2003 Resource Kit.
Ну а лучшим выбором наверное будет разобраться в ключах setacl, и сделать тоже самое через него.

Баг с симлинками - это можно в бесконечный цикл попасть?
ага.

Прописал команду для теста, ошибку не выдало, стал владельцем.
Вообще, если задача просто открыть полные дефолтовые права для всех папок и сделать это по-проще, то можно воспользоваться HiJackThis+ > меню Tools > Files > Unlock Files > в поле ввода вставляете путь к папке > Go.
Прим.:
Подробное описание инструмента.
Какие права будут установлены (спойлер "Примечание 2").
 
Последнее редактирование:
Ну а лучшим выбором наверное будет разобраться в ключах setacl, и сделать тоже самое через него.
Собственно вот вариант через SetACL (с рекурсивным обходом):

Код:
<путь1>\setacl.exe -on "<путь2>" -ot File -actn trustee -trst "n1:<sidold>;n2:<sidnew>;ta:repltrst" -ignoreerr -rec cont_obj
Но и тут не без греха. Нужно юзать конкретно эту версию setacl.

Вместо <путь1> указываете полный путь к утилите SetACL
Вместо <путь2> обрабатываемый путь.
<sidold> заменяете на сид старого юзера, <sidnew> на SID нового. Что откуда брать описал выше под спойлером (звездочку перед SID здесь ставить не нужно).

Примечание:
1) Для более быстрой работы, отключите подробный вывод в консоль, добавив ключик -silent
2) Для надежной обработки в обход привилегий, нужно запускать утилиту с правами Local System или Trusted Installer. Примеры:

- из ExecTI (вводим cmd.exe /k)
- из System Informer (запускаем его ПКМ - от админа) > System > Run as ... > User name "NT AUTHORITY\LOCAL SERVICE", Type "Service" (вводим cmd.exe /k), для проверки под каким юзером запустились, вводим whoami

Полный пример команды, заменяющий все вхождения в DACL группы Администраторы на группу Пользователи для пути C:\temp:
Код:
setacl.exe -on "C:\temp" -ot File -actn trustee -trst "n1:S-1-5-32-544;n2:S-1-5-32-545;ta:repltrst" -ignoreerr -rec cont_obj
SID-ы хорошо известных групп также можно узнать из этой статьи: Well-known SIDs - Win32 apps
 
Последнее редактирование:
Извините, я тупанул, когда сейвил, надо было тоже чудо-префикс дописать и тогда он сохранит остальные файлы
Код:
icacls \\?\D:\* /save C:\acls.bak /T /C /Q
Не подскажете простыми словами, в чём его суть?

Спасибо, что всё так расписали, буду пробовать
 
Почитайте выше, я дополнил пост и добавил еще один с нормальным решением.

Не подскажете простыми словами, в чём его суть?
Суть /save не шибко крутая, сохранить весь список прав доступа в файл в формате SDDL. Если откроете его блокнотом, то поймёте. Просто /substitute иначе (без него) видимо не работает, ну она, и так вообще не работает ;) А если у кого-то и получится сделать, чтобы /substitute заработал, поделитесь решением.
 
Последнее редактирование:
Если кратко, префикс \\?\ позволяет пропустить один из уровней проверок безопасности при анализе пути.
Более полно можно почитать тут:
 
Полный пример команды, заменяющий все вхождения в DACL группы Администраторы на группу Пользователи для пути C:\temp:
Код:
setacl.exe -on "C:\temp" -ot File -actn trustee -trst "n1:S-1-5-32-544;n2:S-1-5-32-545;ta:repltrst" -ignoreerr -rec cont_obj
Я, наверное, с ума скоро сойду, но хоть ошибок и не выводится, но и ничего не происходит.
Я запустил от имени администратора
Код:
SetACL.exe -on E:\studio -ot File -actn trustee -trst "n1:S-1-5-21-449789199-987631865-2024635987-1001;n2:S-1-5-21-394638696-868904724-2398818833-1001;ta:repltrst" -rec cont_obj > E:out.txt
И в выводе увидел
Код:
Processing ACL of: <\\?\E:\studio>
Processing ACL of: <\\?\E:\studio\Sdk>
Processing ACL of: <\\?\E:\studio\Sdk\.downloadIntermediates>
Processing ACL of: <\\?\E:\studio\Sdk\.knownPackages>
Processing ACL of: <\\?\E:\studio\Sdk\.temp>
Processing ACL of: <\\?\E:\studio\Sdk\build-tools>
Processing ACL of: <\\?\E:\studio\Sdk\build-tools\20.0.0>
Processing ACL of: <\\?\E:\studio\Sdk\build-tools\20.0.0\aapt.exe>
Processing ACL of: <\\?\E:\studio\Sdk\build-tools\20.0.0\aidl.exe>
Processing ACL of: <\\?\E:\studio\Sdk\build-tools\20.0.0\arm-linux-androideabi-ld.exe>
Processing ACL of: <\\?\E:\studio\Sdk\build-tools\20.0.0\bcc_compat.exe>
Processing ACL of: <\\?\E:\studio\Sdk\build-tools\20.0.0\dexdump.exe>
Processing ACL of: <\\?\E:\studio\Sdk\build-tools\20.0.0\dx.bat>
Processing ACL of: <\\?\E:\studio\Sdk\build-tools\20.0.0\i686-linux-android-ld.exe>
Processing ACL of: <\\?\E:\studio\Sdk\build-tools\20.0.0\lib>
и так далее...
Но при проверке я увидел простую и понятную картину маслом: image hosted at ImgBB.
SIDы несколько раз перепроверил, в чём дело? Может, я что-то не так сделал?
 
Последнее редактирование:
Владелец унаследован от диска E:\ - в этом дело? Хотя я не уверен, даже так ничего не меняется:
Код:
D:\Users\kww\Desktop\setacl>SetACL.exe -on E:\ -ot File -actn trustee -trst "n1:S-1-5-21-899911517-1191738758-66162731-1001;n2:S-1-5-21-394638696-868904724-2398818833-1001;ta:repltrst"
Processing ACL of: <\\?\E:\>
Он же вроде как должен поменять один sid на другой именно у диска, не рекурсивно?
 
Последнее редактирование:
У меня успешно заменило. См. скриншот.

Возможно, все дело в наследовании от корня диска E:\ и менять надо там, либо индивидуально отключать наследование и менять только тем папкам, где нужно.

Он же вроде как должен поменять один sid на другой именно у диска, не рекурсивно?
да, попробуйте эту команду, но на всякий случай ключик добавьте: -rec no
Это должно гарантировать, что работает без рекурсии, но даже если с ней так будет даже лучше.

Единственное, что у вас SID почему-то "гуляют". В последнем посте вы указываете, что надо заменить:

S-1-5-21-899911517-1191738758-66162731-1001

а постом ранее:

S-1-5-21-449789199-987631865-2024635987-1001
 

Вложения

  • 1714395750282.webp
    1714395750282.webp
    61 KB · Просмотры: 19
Единственное, что у вас SID почему-то "гуляют". В последнем посте вы указываете, что надо заменить:
S-1-5-21-899911517-1191738758-66162731-1001
а постом ранее:
S-1-5-21-449789199-987631865-2024635987-1001
Да, я это тоже недавно заметил. Может от позапрошлой установки осталось, но непонятно, почему владелец не группа администраторов. А тот SID, что я писал постами ранее - это владелец файлов и папок сейчас. По-моему я раньше делал через robocopy. Какой-то гайд в инете нашел, типо просто через robocopy скопировать файлы без разрешений и всё. А сейчас у меня нет места на такие выкрутасы.

Я просто не понимаю что идёт не так. Руками-то точно можно поменять права или там, через icacls, но setacl почему-то не справляется

А ещё icacls не выводит этот SID...

Upd. Ладно, сделал группу администраторов владельцем через takeown. Но многого это не поменяет :(
 
Последнее редактирование:
Простите, я вас изначально неправильно понял. Команды, которые выше давал, предназначены для замены SID в DACL (список прав). Владелец объекта это из другой иерархии, он относится к Security Descriptor, и соответственно его замена будет выглядеть иначе.

К сожалению, setacl не предоставляет такого функционала, на сколько я могу судить из документации (замена owner по условию).

Могу предложить вариант со скриптом Powershell:
PowerShell:
# Define the folder path
$folderPath = "E:\studio"

# Define old SID
$oldSID = "S-1-5-21-449789199-987631865-2024635987-1001"

# Define new SID
$newSID = "S-1-5-21-394638696-868904724-2398818833-1001"

function Get-OwnerSid {
    param (
        [Parameter(Position=0, ParameterSetName="Path")]
        [string]$Path,
        [Parameter(Position=0, ParameterSetName="Acl")]
        [System.Security.AccessControl.FileSystemSecurity]$Acl
    )
    if ($PSCmdlet.ParameterSetName -eq "Path")
    {
        $Acl = Get-Acl -Path $Path
    }
    $owner = $Acl.Owner
    if (-Not $owner.StartsWith("O:S"))
    {
        $user = New-Object System.Security.Principal.NTAccount $owner
        $owner = $user.Translate([System.Security.Principal.SecurityIdentifier]).Value
        return $owner
    }
    else {
        return $owner.Substring(2)
    }
}

# Function to replace owner SID of a folder (recursively)
function Set-OwnerRecursively {
    param (
        [string]$FolderPath,
        [string]$BadSid,
        [System.Security.Principal.SecurityIdentifier]$NewOwnerSID
    )

    # Set owner for the folder itself
    $acl = Get-Acl -Path $FolderPath
    $owner = Get-OwnerSid -Acl $acl
    if ($owner -eq $BadSid) {
        $acl.SetOwner($NewOwnerSID)
        Set-Acl -Path $FolderPath -AclObject $acl
        Write-Host "Success change owner of:" $FolderPath
    }

    # Set owner for all subfolders and files recursively
    $items = Get-ChildItem -Path $FolderPath
    foreach ($item in $items) {
        # Set owner for subfolders recursively
        if ($item.PSIsContainer) {
            Set-OwnerRecursively -FolderPath $item.FullName -BadSid $BadSid -NewOwnerSID $NewOwnerSID
        }
        
        # Set owner for files
        $acl = Get-Acl -Path $item.FullName
        $owner = Get-OwnerSid -Acl $acl

        if ($owner -eq $BadSid) {
            $acl.SetOwner($NewOwnerSID)
            Set-Acl -Path $item.FullName -AclObject $acl
            Write-Host "Success change owner of:" $item.FullName
        }
    }
}

$newOwnerSID = New-Object System.Security.Principal.SecurityIdentifier($newSID)

Set-OwnerRecursively -FolderPath $folderPath -BadSid $oldSID -NewOwnerSID $newOwnerSID

Здесь с рекурсией. Сиды пропишите в самом начале нужные. Сейчас прописал, те, что у вас на папке E:\studio

Если Powershell ни разу не запускали, то первым действием необходимо разрешить запуск скриптов командой:
PowerShell:
Set-ExecutionPolicy Bypass
 
Извините, может, изначально я сам недостаточно информации дал.

Только сейчас руки дошли попробовать скрипт. Попробовал на одной папке, всё вроде как отлично. Попробовал на папке с музыкой - выдало кучку ошибок. Подкорректировал код, чтобы выводить пути при ошибках и увидел, что их объединяет наличие квадратных скобок. Что-нибудь посоветуете на этот счёт?

Такую ошибку выводит на каждый файл:
Код:
Невозможно вызвать метод для выражения со значением NULL.
D:\suction\_Installers\tweaks\replace old owner - EDIT BEFORE USE.ps1:24 знак:9
+     if (-Not $owner.StartsWith("O:S"))
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

PS C:\Windows\system32> D:\suction\_Installers\tweaks\replace old owner - EDIT BEFORE USE.ps1
Error: D:\Users\kww\Desktop\moosiks\bizzyn - [8kbps] ОМСКИЙ АРТУР ПИРОЖКОВ - ШКОЛОБЛОГЕРЫ.mp3
Error: D:\Users\kww\Desktop\moosiks\Cartoon & Coleman Trapp - Why We Lose [NCS Release].mp3
Error: D:\Users\kww\Desktop\moosiks\Clarx - H.A.Y [NCS Release].mp3
Error: D:\Users\kww\Desktop\moosiks\GUMI - Jinsei Reset Button [off vocal].mp3
Error: D:\Users\kww\Desktop\moosiks\Infected Mushroom - Walking On The Moon (Bad Computer Remix) [Monstercat Release].mp3
Error: D:\Users\kww\Desktop\moosiks\Infected Mushroom - Walking On The Moon [Monstercat Release].mp3
Error: D:\Users\kww\Desktop\moosiks\pavleastmashups - руки на стол x paper planes [mashup].mp3
Error: D:\Users\kww\Desktop\moosiks\Radioinactive feat. 2Mex, La Caution - Mint Tea (feat. La Caution & 2Mex) [Explicit].mp3
Error: D:\Users\kww\Desktop\moosiks\SawanoHiroyuki[nZk] feat. mizuki - aLIEz.mp3
Error: D:\Users\kww\Desktop\moosiks\SawanoHiroyuki[nZk] feat. mizuki - CRY.mp3
Error: D:\Users\kww\Desktop\moosiks\SawanoHiroyuki[nZk] Tielle&Gemie - gravityWall (Remastered).mp3
Error: D:\Users\kww\Desktop\moosiks\[BLDINA] - LOST 1.KLA$.mp3
Error: D:\Users\kww\Desktop\moosiks\кто такой руеблосе - WE DON'T PLAY [УЛЬТРАNASRAL].mp3
Error: D:\Users\kww\Desktop\moosiks\キネマ106 (Kinema106) - 【隼鷹】N・M・W _ [Junyou] N・M・W.mp3
Error: D:\Users\kww\Desktop\moosiks\角巻わため (Tsunomaki Watame) - [A]ddiction.mp3

Ещё не хватает, чтобы мне права на полный доступ выдавало к файлам и папкам, а то вот я сейчас стал владельцем этой злополучной папки с музыкой, а в ней я могу создавать только папки и их владельцем становится группа администраторов.
И убрать старого пользователя... Попробую сам пока что

1715090046286.png

1715090523511.png
 
Последнее редактирование:
Отредактировать уже не получается... Чат гпт подсказал мне на счёт полного доступа вот так сделать в итоге. Оно вроде как работает.
PowerShell:
if ($owner -eq $BadSid) {
    $acl.SetOwner($NewOwnerSID)

    #by chatgpt
    $acl.Access | Where-Object {$_.IdentityReference -eq $BadSid} | ForEach-Object {
        # Remove access rule for BadSid
        $acl.RemoveAccessRule($_)
        # Add access rule for NewOwnerSid
        $acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule($NewOwnerSID, $_.FileSystemRights, $_.InheritanceFlags, $_.PropagationFlags, $_.AccessControlType)))
    }

    Set-Acl -Path $FolderPath -AclObject $acl
    Write-Host "Success:" $FolderPath
}

Теперь бы порешать квадратные скобки
Заменил везде -Path на -LiteralPath. Думаю, вопрос решен?
 
Последнее редактирование:
@kww, если это не какие-то специфические системные файлы, выдайте права через HiJackThis+. Инструкцию давал тут, и не морочьтесь со скриптами.

Ошибку пока некогда починить. На выходных посмотрю.
 
Назад
Сверху Снизу