从提升的脚本访问用户环境变量?



我有一个脚本,利用$env:appdata产生C:UsersusernameAppDataRoaming。如果我手动运行脚本,即使是在"管理"目录下,这也能很好地工作。提示。但是,当它作为"系统"下的计划任务的一部分运行时;如果有"Highest privileges ",则输出c:windowssystem32configsystem

我能够使用(Get-CimInstance CIM_ComputerSystem).Username获得登录的用户名。如何获取其他环境变量,尤其是AppData路径?

这里的问题是,在SYSTEM下运行,SYSTEM实际上是内置的机器帐户,具有您可以达到的最高权限。这个帐户甚至取代了内置的本地管理员。如果您以SYSTEM的身份运行某个程序,则其用户配置文件为C:WindowsSystem32configsystem

如果需要在另一个用户的上下文中运行,最好的解决方案是创建以该用户身份执行的任务,并将权限适当地委托给主体。事实上,作为SYSTEM运行某些东西几乎从来都不是正确的解决方案,除非您需要执行默认情况下它单独可以执行的特定功能之一(对于这些功能,通常不建议将这些权限委托出去)。

如果它需要在SYSTEM下运行,那么,您知道SYSTEM配置文件在哪里,因此适当地为其AppData播种,或者在任务完成后从那里检索工件。但是听起来你真的想要作为另一个用户来运行它,这就是你应该配置你的任务来运行的。


我不建议从SYSTEM用户这样做,但如果你需要查看其他用户的环境变量出于其他原因,你可以加载他们的注册表hive,只要另一个进程没有打开hive(比如如果该用户正在使用regedit.exe或已经加载了,就像我要展示给你自己一样):

两件事:

  1. 你需要知道他们的用户配置文件的位置才能做到这一点

  2. PowerShell不能自己加载其他用户的hive,所以我们必须使用reg.exe命令来完成这个操作

    • 注册表提供商仍然可以访问数据,只是不能加载它。
    reg load HKEY_Usersusername "C:UsersusernameNTUSER.DAT"
    # If we can't load it then no point continuing
    if( $? ) {
    try {
    # Read envvars into variable
    $uservars = Get-ItemProperty HKEY_Users:Environment
    } finally {
    reg unload HKEY_Usersusername
    if ( !$? ) {
    Write-Warning "Unable to unload userhive, see previous error message for details"
    }
    }
    # Do what you need here
    # $uservars is a `PSCustomObject` containing the other user's
    # environment variables.
    } else {
    throw "Unable to load userhive, logon script could not complete"
    }