Windows获取所有权、批量添加用户权限

介绍了如何自己输入命令来实现这些功能。

Windows获取所有权、批量添加用户权限

By img Microanswer Create at:Mar 8, 2024, 11:30:28 AM 
介绍了如何自己输入命令来实现这些功能。


请注意,本文内容均仅在Windows操作系统环境下使用,不适用于MacOS和Linux等非Windows系统。

一、管理员获取所有权

管理员获取所有权,其实就是执行 takeown 这个命令来进行获取,比如说,打开一个CMD命令行窗口,当然这个CMD命令行窗口需要以管理员权限运行,然后执行下面的命令:

takeown /r /f D:\dir1

这个命令就可以将 D:\dir1 目录及其子目录下的所有文件的所有权获取到。/f 表示指定目录, /r 表示递归设置给子目录。

二、批量添加用户权限

当我们获取到文件的所有权之后,可能仍然不能操作某些文件,假设你重装了操作系统,以前的D盘下的文件在现在装好的系统里面再打开可能就会提示你没有权限,即使你获取了所有权,你也没有办法打开或者执行。那么针对这种情况,极有可能是因为该文件当前的写入读取权限列表中没有当前登录Windows的用户,我们只需要手动给文件添加权限就可以了。右击文件点击【属性】→【安全】→【编辑】→【添加】让后将当前登录的用户添加进去,你就可以正常使用该文件了。

但是我们如果想为整个目录或者整个磁盘进行这个操作,那每个文件都这样点击一边简直要人命。其实有一个命令 icacls 可以帮助我们完成这件事情,同样的用管理员权限打开一个CMD窗口,使用命令:

icacls "D:" /grant "username":(oi)(ci)(f) /t /c

就可以将整个D盘及其子目录下的文件全部都加上用户username(替换为你的电脑用户名)的全部控制权限(读取、写入、执行),/t 表示递归处理所有子目录文件,/c 表示遇到一些文件处理错误继续处理后续的文件。对于 (oi)(ci) 的作用解释如下:

(I) - 继承。 ACE 继承自父容器。
(OI) - 对象继承。 此容器中的对象将继承此 ACE。 仅适用于目录。
(CI) - 容器继承。 此父容器中的容器将继承此 ACE。 仅适用于目录。
(IO) - 仅继承。 ACE 继承自父容器,但不适用于对象本身。 仅适用于目录。
(NP) - 不传播继承。 ACE 由容器和对象从父容器继承,但不会传播到嵌套容器。 仅适用于目录。

对于(f)的作用解释如下:

F - 完全访问
M - 修改访问权限
RX -读取和执行访问权限
R - 只读访问
W - 只写访问

更多关于icacls命令的解释参考官网:https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/icacls

经过上面两个命令后,基本上我们新安装的系统就又可以快乐的使用之前的文件了。

一步到位

实际上,icacls 命令也可以修改文件的所有权,而不必使用 takeown 命令,而且takeown命令有一个弊端,那就是隐藏的文件夹或文件是不会被处理的,同时takeown 命令不支持静默处理,输出日志过程会导致程序执行十分缓慢。 为了使用方便,我直接使用powershell 结合 icacls 命令,实现了一个同时获取文件所有权和分配文件读写权限(完全控制)权限的脚本,如下:

// 管理员获取所有权.ps1

# 这个脚本可以将你指定的所有目录,及其这些所有子目录(及文件)的所有者修改为当前登录的电脑用户。
# 如果你的文件能多,那么这个脚本的执行可能会很久
#
# 这里将你要获取所的目录写上
# 如果有多个,那么可以写: @("D:\your\file\dir1", "D:\your\file\dir2")
$targetDir = @("D:\projects")

# 这个表示 在获取所有权时,要不要同时将文件的完全控制权限(读写权限)也获取。
# $true 表示要,$false 表示不要。
$Grant = $true

# 这个表示在运行过程中,要不要禁用日志输出,如果你有很多子目录或者文件(超过5k+才算多),那么不禁用可能要等很久才会全部处理完成。
# $true 表示禁用日志输出,$false 表示要输出日志
$Mute = $true

function TakeOwnOfDir{
    param([String]$DirPath, [Boolean]$Grant, [Boolean]$Mute)

    $dirContent =@(Get-ChildItem $DirPath -Force)
    for ($i = 0; $i -lt $dirContent.Count; $i++) {
        $fileItem = $dirContent.Get($i)
        $fullPath = "$DirPath\$($fileItem.Name)"
        $TypeName = $fileItem.GetType().Name
        if ($null -ne $TypeName -and 'DirectoryInfo' -eq $TypeName) {
            TakeOwnOfDir -DirPath $fullPath -Grant $Grant -Mute $Mute
        }
        $log = ""
        icacls $fullPath /setowner $env:USERNAME /c /q *> $null
        if ($Grant -eq $true) {
            icacls $fullPath /grant "`"$($env:USERNAME)`":(oi)(ci)(f)" /c /q *> $null
            $log = $log + " GRANTED"
        }
        if($Mute -ne $true) {
            $log = $log + " SUCCESS: " + $fullPath
            Write-Output $log
        }
    }
}

Write-Output "Starting ..."
for ($i = 0; $i -lt $targetDir.Count; $i++) {
    Write-Output "Processing $($targetDir.Get($i))"
    TakeOwnOfDir -DirPath $targetDir.Get($i) -Grant $Grant -Mute $Mute
}
Write-Output "All Processed"

把上面的代码保存到一个 管理员获取所有权.ps1 文件中,然后执行,就可以啦。如果提示不允许执行脚本,可以在powershell中先输入:

# 如果提示不允许执行脚本, 可以使用命令:
Set-ExecutionPolicy Unrestricted

然后再执行保存的脚本。

Full text complete, Reproduction please indicate the source. Help you? Not as good as one:
Comment(Comments need to be logged in. You are not logged in.)
You need to log in before you can comment.

Comments (0 Comments)