在vbscript中使用icacls更改子文件夹的所有者

时间:2013-03-29 13:18:09

标签: vbscript

我有一个拥有700多个用户的网络,我想创建一个脚本,可以将主文件夹的所有者更改为域管理员,将子文件夹更改为用户自己。

这是我可以在我的大学的帮助下创建的,但是由于某些原因这不起作用。任何人都可以帮助我。感谢。

Set objFSO  = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.OpenTextFile("G:\Userhome\userdirlist.txt", 1)

Set oShell  = WScript.CreateObject("WSCript.shell")

Do Until objFile.AtEndOfStream

    struserfolder = objFile.ReadLine

    oshell.run ("icacls G:\userhome\"+ struserfolder +"\*.*  /setowner domainname\" + "struserfolder" + " /t")
    oshell.run ("icacls G:\userhome\"+ struserfolder +"\*.*  /setowner domainname\Domain Admins")
Loop

1 个答案:

答案 0 :(得分:0)

当您可能想要使用变量 "struserfolder"时,可以使用字符串 struserfolder。改变这个:

oshell.run ("icacls G:\userhome\"+ struserfolder +"\*.* /setowner domainname\" _
  + "struserfolder" + " /t")

进入这个:

oshell.run "icacls G:\userhome\"+ struserfolder +"\*.* /setowner domainname\" _
  + struserfolder + " /t"

此外,您必须使用空格引用参数。缺少引号可能是阻止第二个命令工作的原因,因为icacls尝试将所有者设置为domainname\Domain而不是domainname\Domain Admins。这应该做:

oshell.run "icacls G:\userhome\" + struserfolder _
  + "\*.* /setowner ""domainname\Domain Admins"""
顺便说一下,你为什么要两次更换主人?任何对象只能拥有一个所有者,如果您使域管理员组成为该文件夹中顶级对象的所有者,则您无法获得任何内容。

如果要授予域管理员访问用户主目录的权限,请将所有者更改为本地管理员组(域管理员自动成为该组的成员),并将该文件夹的完全控制权授予Administrators,SYSTEM和用户。然后在目录树中传播更改的权限:

path = Chr(34) & "G:\userhome\" & struserfolder & Chr(34)

oshell.run "icacls " & path & " /setowner Administrators /t /c"
oshell.run "icacls " & path & " /grant Administrators:(OI)(CI)F " _
  & "SYSTEM:(OI)(CI)F domainname\" & struserfolder & ":(OI)(CI)F"
oshell.run "icacls " & path & " /reset /t /c"

编辑: Run方法返回已执行命令的退出状态,当事情无法正常工作时,可能会给出一些指示:

rc = oshell.run("icacls " & path & " /setowner Administrators /t /c", 0, True)
WScript.Echo "icacls returned with exit code " & rc & "."

一个问题可能是默认情况下Run是异步的(参数bWaitOnReturn默认为False),即调用在命令(icacls)仍然存在时立即返回在后台运行。这可能会导致后续命令尝试更改尚未获取所有权的对象的权限。

通常比返回代码更有帮助的是命令的输出。但是,执行命令的方式不会显示命令窗口,即使是命令窗口,它也会在命令完成后自动关闭。但是,您可以强制命令窗口变为可见,并在命令完成后保持打开状态。

oshell.run "%COMSPEC% /k icacls " & path & " /setowner Administrators /t /c" _
  , 1, True

当然,您通常不希望在生产中使用它,但在调试脚本时它非常有用。

另一种选择是完全避免Run并通过Exec方法运行命令。这样您就可以访问已创建进程的StdOutStdErr

Set icacls = oshell.Exec("icacls " & path & " /setowner Administrators /t /c")
Do While icacls.Status = 0
  WScript.Sleep 100
Loop
WScript.Echo "icacls returned with exit code " & icacls.ExitCode & "."
WScript.Echo icacls.StdOut.ReadAll & icacls.StdErr.ReadAll