如何从批处理文件执行PowerShell命令?

gojuced7  于 2022-12-29  发布在  Shell
关注(0)|答案(7)|浏览(294)

我有一个PowerShell脚本,用于将网站添加到Internet Explorer中的受信任站点:

set-location "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
set-location ZoneMap\Domains
new-item TESTSERVERNAME
set-location TESTSERVERNAME
new-itemproperty . -Name http -Value 2 -Type DWORD

我想从批处理文件执行这些PowerShell命令。当我必须运行单个命令时,这看起来很简单,但是在本例中,我有一系列相关命令。我想避免为从批处理调用的PS脚本创建单独的文件-所有内容都必须在批处理文件中。
问题是:如何从批处理文件执行PowerShell命令(或语句)?

k97glaaz

k97glaaz1#

下面是批处理文件中的代码(tested,works):

powershell -Command "& {set-location 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings'; set-location ZoneMap\Domains; new-item SERVERNAME; set-location SERVERNAME; new-itemproperty . -Name http -Value 2 -Type DWORD;}"

根据以下信息:
http://dmitrysotnikov.wordpress.com/2008/06/27/powershell-script-in-a-bat-file/

6yoyoihd

6yoyoihd2#

键入cmd.exe Powershell -Help并查看示例。

jgwigjjp

jgwigjjp3#

这个解决方案类似于walid 2 mi(感谢您的启发),但是允许Read-Hostcmdlet的标准控制台输入。

优点:

  • 可以像标准.cmd文件一样运行
  • 批处理和powershell脚本只有一个文件
  • powershell脚本可以是多行的(易于阅读的脚本)
  • 允许标准控制台输入(通过标准方式使用Read-Host cmdlet)
    缺点:
  • 需要powershell版本2.0+
    batch-ps-script.cmd的注解和可运行示例:
<# : Begin batch (batch script is in commentary of powershell v2.0+)
@echo off
: Use local variables
setlocal
: Change current directory to script location - useful for including .ps1 files
cd %~dp0
: Invoke this file as powershell expression
powershell -executionpolicy remotesigned -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))"
: Restore environment variables present before setlocal and restore current directory
endlocal
: End batch - go to end of file
goto:eof
#>
# here start your powershell script

# example: include another .ps1 scripts (commented, for quick copy-paste and test run)
#. ".\anotherScript.ps1"

# example: standard input from console
$variableInput = Read-Host "Continue? [Y/N]"
if ($variableInput -ne "Y") {
    Write-Host "Exit script..."
    break
}

# example: call standard powershell command
Get-Item .

.cmd文件的代码段:

<# : batch script
@echo off
setlocal
cd %~dp0
powershell -executionpolicy remotesigned -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))"
endlocal
goto:eof
#>
# here write your powershell commands...
gkl3eglg

gkl3eglg4#

未测试.cmd

;@echo off
;Findstr -rbv ; %0 | powershell -c - 
;goto:sCode

set-location "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
set-location ZoneMap\Domains
new-item TESTSERVERNAME
set-location TESTSERVERNAME
new-itemproperty . -Name http -Value 2 -Type DWORD

;:sCode 
;echo done
;pause & goto :eof
exdqitrt

exdqitrt5#

当从批处理文件调用多行PowerShell语句时,除了最后一行之外,每行都以插入符号结尾。行首不必有额外的空格,这是我的约定。

PowerShell set-location "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" ^
           set-location ZoneMap\Domains ^
           new-item TESTSERVERNAME ^
           set-location TESTSERVERNAME ^
           new-itemproperty . -Name http -Value 2 -Type DWORD

如果您正在通过管道输入Select-Object之类的cmdlet,则需要以分号结束命令,否则它将包含下一行。

Powershell $disk = Get-WmiObject Win32_LogicalDisk -Filter """"DeviceID='D:'"""" ^| Select-Object Freespace; ^
           Exit ([math]::truncate($disk.freespace / 1GB))
qacovj5a

qacovj5a6#

在寻找将powershell脚本放入批处理文件的可能性时,我发现了这个线索。walid2mi的想法并没有100%适用于我的脚本。而是通过一个临时文件,包含它所产生的脚本。下面是批处理文件的框架:

;@echo off
;setlocal ENABLEEXTENSIONS
;rem make from X.bat a X.ps1 by removing all lines starting with ';' 
;Findstr -rbv "^[;]" %0 > %~dpn0.ps1 
;powershell -ExecutionPolicy Unrestricted -File %~dpn0.ps1 %*
;del %~dpn0.ps1
;endlocal
;goto :EOF
;rem Here start your power shell script.
param(
    ,[switch]$help
)
evrscar2

evrscar27#

我无法得到任何有用的答案,但加上@哈桑Voyeau的-Command;,再加上@艾德Palmer的格式,就可以了:

powershell -Command ^
More? set-location "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"; ^
More? set-location ZoneMap\Domains; ^
More? new-item TESTSERVERNAME; ^
More? set-location TESTSERVERNAME; ^
More? new-itemproperty . -Name http -Value 2 -Type DWORD

这里,;告诉被调用的powershell.exe当前命令行到此结束,并且可以进一步指定更多命令行,而^告诉CMD(为了简单起见;它实际上被称为“Windows Script Host”),下一行可能会有更多的字符串输入。从我们的Angular 来看,CMD通过CR/LF line-endings escape character ^将多个命令行解析为一个命令行,以便powershell.exe看到的是单行命令行-Command set-location ...; set-location ...; ...

  • 如果你想指定任何powershell参数,在-Command之前指定,因为powershell.exe会将-Command之后的命令行解释为-Command的单个代码块参数。使用花括号来显式分隔代码块,如-Command {set-location ...; ...},也不允许在后面指定powershell参数,如-Command {...} -NoExit
  • 在这种格式中,不要像@哈桑Voyeau那样使用"来分隔-Command的参数,因为CMD会将未闭合的"中的^解释为文字插入字符。
  • 使用^作为第一行之后的任何一行的第一个字符也会使CMD将其解释为文字插入字符。使用空格``作为前面的空格,从语义上指定空行。
  • 如果要在代码之间包含注解,请使用PowerShell的块注解<# .. #>(PowerShell的行内注解#表示所有后续字符都是其注解的一部分,不能转义,因为^会将多个命令行解析为一个命令行。)但是,如果没有",如@哈桑Voyeau 's中那样封装<>,CMD会将它们解析为I/O redirection operators,我们可以像^<# COMMENT GOES HERE #^>一样执行escape by using a prefixing-caret。如果您在空行中插入块注解,^将成为该行的第一个字符,并将被解释为文字插入字符,因此我们像前面一样通过插入前缀空格来获得:
⋮
More? COMMAND ARG1 ARG2 ...; ^<# IN-LINE BLOCK COMMENT #^> ^
More?  ^<# SEPARATE-LINE BLOCK COMMENT #^> ^
More? COMMAND ARG1 ARG2 ...;^<# NO PREFIXING/SUFFIXING SPACES REQUIRED #^>^
⋮
  • 要对参数中的字符进行转义,请使用PowerShell's escape character backtick/grave-accent ```。因为反勾号不是its escape characters ( ^ for I/O redirection operators, \ for double-quotes, % for percent)中的一个,所以CMD不会使用反勾号。
  • 如果你的参数包含空格但不包含转义符,则可以使用单引号分隔参数。CMD仍会将其解析为多个参数,因为空格未分隔,但PowerShell会正确地将其重新组合在一起,并重新附加空格。
  • 如果你的参数包含转义字符,你可以使用双引号来封装CMD转义的双引号,或者相反。未转义的双引号告诉CMD其中的特殊字符,例如空格,当CMD转义双引号传递到PowerShell并由PowerShell作为普通双引号进行分析时,不能将视为参数分隔符。双引号的转义字符为\。(Quoting/Escaping 1/2)例如:
More? write-output 'there are spaces here'; ^
More? write-output "\"new line`r`nhere\""; ^
More? write-output \""also`r`nhere"\"; ^

将导致:

there are spaces here
new line
here
also
here

相关问题