由于几个主要与安全相关的原因,PowerShell脚本不像批处理脚本那样易于移植和使用。但是,我们可以将批处理脚本与PowerShell脚本捆绑在一起,以解决这些问题。在这里,我们将向您展示一些问题领域,以及如何构建批处理脚本来解决这些问题。
除非目标系统已预先配置为允许以所需的权限运行任意脚本,并使用正确的设置,否则在尝试执行此操作时很可能会遇到一些问题。
让我们从解决第一个问题开始–.PS1文件关联。不能双击运行.PS1文件,但可以通过这种方式执行.BAT文件。因此,我们将编写一个批处理文件,从命令行调用PowerShell脚本。
因此,我们不必为每个脚本重新编写批处理文件,或者每次移动脚本时,它都将使用自引用变量为PowerShell脚本构建文件路径。要使此工作正常,批处理文件需要与PowerShell脚本放在同一文件夹中,并且具有相同的文件名。所以如果你的PowerShell脚本被调用“MyScript.ps1,您将要命名批处理文件MyScript.bat文件“并确保它在同一个文件夹中。然后,将这些行放入批处理脚本中:
@ECHO OFF PowerShell.exe -Command "& '%~dpn0.ps1'" PAUSE如果没有其他的安全限制,从批处理文件运行PowerShell脚本就只需要这些了。事实上,第一行和最后一行主要只是偏好的问题——第二行才是真正起作用的。具体情况如下:
@ECHO OFF关闭命令回显。这只会防止批处理文件运行时其他命令显示在屏幕上。这条线本身被前面的at(@)符号所隐藏。
PowerShell.exe-命令“&;'%~dpn0.ps1'”实际运行PowerShell脚本。PowerShell.exe当然,可以从任何CMD窗口或批处理文件调用,以便像往常一样将PowerShell启动到裸控制台。还可以使用它直接从批处理文件运行命令,方法是包含-Command参数和适当的参数。用于将.PS1文件作为目标的方法是使用特殊的dpn0变量。从批处理文件运行,%~dpn0计算为批处理文件的驱动器号、文件夹路径和文件名(不带扩展名)。由于批处理文件和PowerShell脚本将位于同一文件夹中并具有相同的名称,%~dpn0.ps1将转换为PowerShell脚本的完整文件路径。
PAUSE只是暂停批处理执行并等待用户输入。通常,在批处理文件的末尾有这样一个选项很有用,这样您就有机会在窗口消失之前查看任何命令输出。随着我们对每个步骤进行测试,这一点的有用性将变得更加明显。
因此,基本批处理文件被设置。出于演示目的,此文件另存为“D:\Script Lab”\MyScript.bat文件“还有一个”MyScript.ps1“在同一个文件夹中。让我们看看双击会发生什么MyScript.bat文件.
显然PowerShell脚本没有运行,但这是意料之中的——毕竟我们只解决了四个问题中的第一个。然而,这里展示了一些重要的信息:
在本例中,概要文件是一个简单的单行脚本,用于此演示,以便在概要文件处于活动状态时生成输出。如果您想自己测试这些脚本,也可以自定义自己的PowerShell配置文件来执行此操作。只需在配置文件脚本中添加以下行:
Write-Output 'Custom PowerShell profile in effect!'此处测试系统上的ExecutionPolicy设置为RemoteSigned。这允许执行本地创建的脚本(如profile脚本),同时阻止来自外部源的脚本,除非它们由可信机构签名。出于演示目的,以下命令用于标记MyScript.ps1从外部来源:
Add-Content -Path 'D:\Script Lab\MyScript.ps1' -Value "[ZoneTransfer]`nZoneId=3" -Stream 'Zone.Identifier'这就决定了区域标识符备用数据流打开MyScript.ps1所以Windows会认为文件来自互联网。可通过以下命令轻松反转:
Clear-Content -Path 'D:\Script Lab\MyScript.ps1' -Stream 'Zone.Identifier'从CMD或批处理脚本中绕过ExecutionPolicy设置实际上相当容易。我们只需修改脚本的第二行,向PowerShell.exe命令。
PowerShell.exe -ExecutionPolicy Bypass -Command "& '%~dpn0.ps1'"-ExecutionPolicy参数可用于修改生成新PowerShell会话时使用的ExecutionPolicy。这种情况不会持续到该会话之后,因此我们可以在需要时像这样运行PowerShell,而不会削弱系统的总体安全态势。既然我们已经解决了这个问题,让我们再来一次:
现在脚本已经正确执行了,我们可以看到它实际上做了什么。它让我们知道我们是以有限用户的身份运行脚本的。该脚本实际上是由具有管理员权限的帐户运行的,但是用户帐户控制正在妨碍它。尽管脚本如何检查管理员访问权限的详细信息超出了本文的范围,但下面是用于演示的代码:
if (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {Write-Output 'Running as Administrator!'} else {Write-Output 'Running Limited!'} Pause您还将注意到,现在在脚本输出中有两个“暂停”操作—一个来自PowerShell脚本,另一个来自批处理文件。其原因将在下一步更加明显。
如果您的脚本没有运行任何需要提升的命令,并且您确信不必担心任何人的自定义概要文件会妨碍您,那么您可以跳过其余部分。但是,如果您运行的是一些管理员级cmdlet,则需要这篇文章。
不幸的是,无法从批处理文件或CMD会话中触发UAC进行提升。不过,PowerShell确实允许我们使用Start进程来实现这一点。在参数中与“-Verb RunAs”一起使用时,启动进程将尝试启动具有管理员权限的应用程序。如果PowerShell会话尚未提升,这将触发UAC提示。要从批处理文件中使用它来启动脚本,我们将生成两个PowerShell进程—一个用于启动启动进程,另一个由启动进程启动以运行脚本。批处理文件的第二行需要更改为:
PowerShell.exe -Command "& {Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -Verb RunAs}"当批处理文件运行时,我们将看到的第一行输出来自PowerShell概要脚本。然后,当启动进程尝试启动时,将出现UAC提示MyScript.ps1.
单击UAC提示符后,将生成一个新的PowerShell实例。当然,因为这是一个新实例,我们将再次看到profile脚本通知。那么,MyScript.ps1运行,我们看到,我们确实在一个提升的会议。
这也是我们在这里有两次停顿的原因。如果不是PowerShell脚本中的一个,我们将永远看不到脚本的输出–一旦脚本运行完毕,PowerShell窗口将弹出并消失。如果批处理文件中没有暂停,我们就无法查看启动PowerShell时是否有任何错误。
我们现在就把那个讨厌的客户资料通知处理掉,好吗?在这里,这甚至不是什么麻烦事,但是如果用户的PowerShell概要文件以您在脚本中没有预料到的方式更改默认设置、变量或函数,那么它们可能会非常麻烦。完全不使用概要文件运行脚本要简单得多,所以您不必担心这个问题。为此,我们只需再次更改批处理文件的第二行:
PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -Verb RunAs}"将-NoProfile参数添加到脚本启动的两个PowerShell实例中,意味着在这两个步骤中都将完全绕过用户的配置文件脚本,并且我们的PowerShell脚本将在相当可预测的默认环境中运行。在这里,您可以看到在两个生成的shell中都没有自定义概要文件通知。
如果在PowerShell脚本中不需要管理员权限,并且跳过了步骤3,则可以不使用第二个PowerShell实例,批处理文件的第二行应该如下所示:
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '%~dpn0.ps1'"输出将如下所示:
(当然,对于非管理员脚本,此时也可以不在PowerShell脚本中暂停脚本结束,因为所有内容都捕获在同一控制台窗口中,并且无论如何都会被批处理文件结束时的暂停保留在那里。)
根据您的PowerShell脚本是否需要管理员权限(如果不需要,您确实不应该请求管理员权限),最终的批处理文件应该如下所示。
没有管理员权限:
@ECHO OFF PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '%~dpn0.ps1'" PAUSE具有管理员权限:
@ECHO OFF PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -Verb RunAs}" PAUSE请记住,将批处理文件与要使用它的PowerShell脚本放在同一文件夹中,并为其指定相同的名称。然后,无论您将这些文件带到哪个系统,您都可以运行PowerShell脚本,而不必在系统上乱搞任何安全设置。您当然可以每次手动进行这些更改,但这样可以省去这些麻烦,而且您不必担心以后恢复更改。
参考文献:
学习编程的关键第一步是使用循环。谢天谢地,PowerShell将随着您的技能不断增长。 ...
...”开始,即编写要在bashshell中运行的脚本。从技术上讲,Powershell等其他脚本语言也可以被称为“shell脚本”,但为什么首先要关注shell脚本,特别是Bash脚本呢? ...
Powershell是一个完美的方式,一个新的编码器开始在Windows上。Powershell是命令行工具和脚本语言的等价部分。它使您能够通过您用来管理计算机的相同命令使计算机自动化。如果您有一个现代的Windows系统,那么您已经有了Powershell...
文件加密和解密可以是一个工作位。但是,使用PowerShell扩展,可以将进程精简为一行命令。为此,我们需要安装Gpg4win和Powershell模块。使用脚本,我们可以自动化文件加密和解密过程。 ...
... 与批处理脚本一样,PowerShell脚本只是写入纯文本文件的指令行,只是该文件使用.PS1扩展名而不是.BAT或.CMD扩展名。但这就是相似之处的终结。 ...
Windows PowerShell是一个优秀的配置管理和自动化框架。它由命令行shell和基于.NET的脚本语言组成。管理员使用PowerShell作为管理Windows、Linux和网络客户端的一种手段。 ...
...去除。也有一些不同的删除选项:使用传统的卸载、使用PowerShell命令和第三方安装程序。 ...
微软于2020年3月4日宣布PowerShell 7.0。这是PowerShell、Microsoft跨平台命令行shell和脚本语言的最新主要更新。下面是什么新的,以及如何在Windows PC上安装它。 powershell 7有什么新功能? 最新版本PowerShell 7是在以前的PowerShell Core 6.1基...