Powershell自提升回路



我是我们公司的IT管理员。最近,网络安全部门希望对用户在u盘和外部大容量存储器上读取和/或写入数据的容易程度进行更严格的限制。此外,所有获得新的Windows笔记本电脑的新用户将只有"非管理员"。权限。所有安装软件等的请求都必须通过IT台。

已创建Active Directory OU,并为其分配了一些测试笔记本。我的老板想让我编写和测试一些Powershell脚本,这些脚本将允许我和我的同事(在与用户的屏幕共享会话中)临时删除控制USB存储访问的注册表项(直到下一个组策略更新出现)。困难的部分已经解决了。目的是脚本将被存储为一个Nal-Object在ZenWorks,所以用户将无法看到源代码(有点类似于一个exe文件,只是双击)。

引起麻烦的代码…

# self-elevate to admin user - code at the very top of the PS file..
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`"";
exit;}
# all the main code follows..

在这里,如果我运行脚本(在非管理帐户中),我被UAC提示输入本地(或域)管理帐户的名称和密码,在PS中打开一个新的窗口/会话,我可以运行任何需要运行的主命令。

然而,问题是,当提示凭据,然后为本地非管理员帐户输入正确的密码(因为一些用户不可避免地要这样做!)一个新的空PS窗口/会话只是以周期性的方式无限期地打开。

我还尝试在if语句中添加一个'else子句'(向用户显示警告和/或强制退出Powershell,但它似乎从未被执行过)。

当我在电脑上测试这是不是任何域名的一部分时,我只是得到一个"用户未经授权"。在UAC中有一种警告,没有错误有机会传播。

有什么解决方法吗?如果UAC提示符默认名称为"ROOTinstall",那就太好了。除了IT管理员,没有人知道这个帐户的密码。

我也运行了Get-ExecutionPolicy -List…MachinePolicy和LocalMachine是"RemoteSigned",其他都是"Undefined"

我不认为执行策略在这个奇怪的循环中起作用,但我很可能是错的。我正在测试的脚本没有经过任何签名程序等,只是在一台测试计算机的本地桌面上。

谢谢。

您的症状很神秘;它的含义如下:

  • Start-Process-Verb RunAs触发的UAC提示错误地接受了NON-admin用户的凭据。

  • 在重新进入脚本时,测试会话是否被提升(!([Security.Principal.WindowsPrincipal] ...)然后失败,并且Start-Process -Verb RunAs再次运行,此时没有UAC提示显示,因为Start-Process确实认为会话被提升并且立即生成一个新窗口。

    • 结果是打开新窗口的无限循环。

我不知道是什么原因造成这种差异,如果你发现了,请告诉我们。


解决方案,您可以尝试以下方法:

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
$passThruArgs = "-NoProfile -ExecutionPolicy Bypass -NoExit -Command `"cd `"$pwd`"; & `"$PSCommandPath`""
if ([Environment]::CommandLine -match [regex]::Escape($passThruArgs)) {
throw "You entered non-admin credentials. Please try again with admin credentials."
}
Start-Process -Verb RunAs PowerShell $passThruArgs
exit
}
# all the main code follows..
'Now running elevated...'

也就是说,在重新进入流程命令行时检查是否包含在提升的重新调用时传递的相同参数。如果是这样,则意味着即使UAC提示符接受了凭据,新会话仍然没有提升,并且会抛出错误。

请注意,我已经将-NoExit添加到重新调用中,以便新窗口保持打开状态,从而允许检查结果。

最新更新