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

发布于 2024-11-07 12:49:39 字数 475 浏览 0 评论 0原文

我有一个 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命令(或语句)?

I have a PowerShell script to add a website to a Trusted Sites in 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

I want to execute these PowerShell commands from a batch file. It seems simple when I have to run a single command, BUT in this case I have a sequence of related commands. I want to avoid creating a separate file for the PS script to be called from the batch - everything must be in the batch file.

The question is: How to execute PowerShell commands (or statements) from a batch file?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

饭团 2024-11-14 12:49:39

这就是批处理文件中的代码的样子(经过测试,有效):

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/

This is what the code would look like in a batch file(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;}"

Based on the information from:

http://dmitrysotnikov.wordpress.com/2008/06/27/powershell-script-in-a-bat-file/

热血少△年 2024-11-14 12:49:39

此解决方案类似于 walid2mi(感谢您的灵感),但允许通过 Read-Host cmdlet 进行标准控制台输入。

优点:

  • 可以像标准.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...

This solution is similar to walid2mi (thank you for inspiration), but allows the standard console input by the Read-Host cmdlet.

pros:

  • can be run like standard .cmd file
  • only one file for batch and powershell script
  • powershell script may be multi-line (easy to read script)
  • allows the standard console input (use the Read-Host cmdlet by standard way)

cons:

  • requires powershell version 2.0+

Commented and runable example of 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 .

Snippet for .cmd file:

<# : 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...
撩发小公举 2024-11-14 12:49:39

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

Type in cmd.exe Powershell -Help and see the examples.

影子是时光的心 2024-11-14 12:49:39

未经测试的.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

untested.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
无妨# 2024-11-14 12:49:39

从批处理文件调用多行 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))

When calling multiline PowerShell statements from a batch file, end each line with a caret, except the last line. You don't have to have the extra spacing at the beginning of the line, that's my convention.

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

If you are piping into a cmdlet like Select-Object, you need to terminate with a semicolon to end the command, otherwise it will include the next line.

Powershell $disk = Get-WmiObject Win32_LogicalDisk -Filter """"DeviceID='D:'"""" ^| Select-Object Freespace; ^
           Exit ([math]::truncate($disk.freespace / 1GB))
樱&纷飞 2024-11-14 12:49:39

我无法得到任何工作答案,但添加 @Hassan Voyeau-Command;@Ed 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 脚本宿主”)下一行可能有更多字符串输入。从我们的角度来看,CMD 通过 CR/LF 行结尾将多个命令行解析为一个命令行转义字符 ^ 以便 powershell.exe 看到单行命令行 -Command set-location ...;设置位置...; ... 相反。

  • 如果您想指定任何 powershell 参数,请在 -Command 之前执行此操作,因为 powershell.exe 将 -Command 后面的命令行解释为 >-Command 的单个代码块参数。使用大括号显式分隔代码块,例如 -Command {set-location ...; ...} 也不允许随后指定 powershell 参数,例如 -Command {...} -NoExit
  • 在此格式中,请勿使用 " 来分隔 -Command 的参数,例如 @Hassan Voyeau 的,因为 CMD 将未闭合的 " 内的 ^ 解释为文字插入符字符。
  • 使用 ^ 作为第一行之后任何行的第一个字符也会使 CMD 将其解释为文字插入符字符。在 1 之前使用空格 可以在语义上指定一个空行。
  • 如果要在代码之间添加注释,请使用 PowerShell 的块注释 <# .. #> (PowerShell 的内联注释 # 将所有后续字符表示为其注释的一部分无法转义,因为 ^ 将多个命令行解析为一个命令行。)但是,如果没有 ",如 @Hassan Voyeau的来封装<>,CMD会解析它们作为 I/O 重定向运算符,我们可以转义使用前缀插入符,如 ^<# COMMENT GOES HERE #^> 如果在空行上插入块注释,^ 将会。成为该行的第一个字符,并将被解释为文字插入符字符,因此我们像之前一样通过插入前缀空格来解决这个问题:
    <前><代码>⋮
    更多的?命令 ARG1 ARG2 ...; ^<# 行内块注释#^> ^
    更多的? ^<# 单独行块注释#^> ^
    更多的?命令 ARG1 ARG2 ...;^<# 不需要前缀/后缀空格 #^>^

  • 要转义参数中的字符,请使用 PowerShell 的转义字符 backtick/grave-accent `。由于反引号不是 其转义字符之一(^ 表示 I/ O 重定向运算符,\ 用于双引号,% 用于百分比),CMD 不会消耗反引号。
    • 如果您的参数包含空格但不包含转义字符,则可以使用单引号来分隔参数。 CMD 仍会将其解析为多个参数,因为空格未分隔,但 PowerShell 会正确地将其重新拼凑在一起并重新附加空格。
    • 如果您的参数包含转义字符,则可以使用双引号封装 CMD 转义双引号,或者对命令使用相反的方式。未转义的双引号告诉 CMD,不得将空格等特殊字符视为参数分隔符,而 CMD 转义的双引号将传递到 PowerShell 并由 PowerShell 作为普通双引号进行解析。双引号的转义字符是 \。 (引用/转义1/2) 例如:
    更多? write-output '这里有空格'; ^
    更多的?写输出 "\"新行`r`nhere\""; ^
    更多的?写输出\""也在这里"\"; ^
    

    将导致:

    这里有空格
    新线
    这里
    还
    这里
    

I couldn't get any answers to work, but adding @Hassan Voyeau's -Command and ;'s in tandem with @Ed Palmer's formatting made it work:

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

Here, ; tells powershell.exe being called that the current command-line ends there and more command-lines can be specified further while ^ tells CMD (for the sake of simplicity; it's actually called "Windows Script Host") that there may be more string input on the next line. From our perspective, CMD parses multiple command-lines into one command-line via CR/LF line-endings escape character ^ so that powershell.exe sees the one-line command-line -Command set-location ...; set-location ...; ... instead.

  • If you want to specify any powershell parameters, do so before -Command since powershell.exe interprets command-lines subsequent to -Command as -Command's single code-block argument. Using curly-braces to explicitly delimit the code block like -Command {set-location ...; ...} doesn't allow specifying powershell parameters afterward, e.g. -Command {...} -NoExit, either.
  • In this formatting, don't use " to delimit -Command's argument like @Hassan Voyeau's since CMD interprets ^ inside unclosed " as a literal caret character.
  • Using ^ as the first character on any line after the first line will also make CMD interpret it as a literal caret character. Use a whitespace before one to semantically designate an empty line instead.
  • If you want to include a comment between code, use PowerShell's block-comment <# .. #> (PowerShell's in-line comment # which denotes all subsequent characters as part of its comment can't be escaped since, again, ^ parses multiple command-lines into one command-line.) However, without " as in @Hassan Voyeau's to encapsulate < and >, CMD will parse them as I/O redirection operators which we can escape by using a prefixing-caret like ^<# COMMENT GOES HERE #^>. If you insert a block-comment on an empty line, ^ will become the first character of the line and will be interpreted as a literal caret character so we work around that like earlier by inserting a prefixing whitespace to get:
    ⋮
    More? COMMAND ARG1 ARG2 ...; ^<# IN-LINE BLOCK COMMENT #^> ^
    More?  ^<# SEPARATE-LINE BLOCK COMMENT #^> ^
    More? COMMAND ARG1 ARG2 ...;^<# NO PREFIXING/SUFFIXING SPACES REQUIRED #^>^
    ⋮
    
  • To escape characters in arguments, use PowerShell's escape character backtick/grave-accent `. Since backticks aren't one of its escape characters (^ for I/O redirection operators, \ for double-quotes, % for percent), CMD won't consume backticks.
    • If your arguments contains spaces but not escape characters, you can use single-quotes to delimit the argument. CMD will parse it as multiple arguments still since the spaces aren't delimited but PowerShell will correctly piece it back together with spaces reattached.
    • If your arguments contains escape characters, you can use double-quotes encapsulating CMD-escaped double-quotes or the other way around to commands. The unescaped double-quotes tell CMD that special characters within, e.g. spaces, mustn't be treated as argument separators while CMD-escaped double-quotes pass onto and are parsed by PowerShell as normal double-quotes. The escape character for double-quotes is \. (Quoting/Escaping 1/2) For instance:
    More? write-output 'there are spaces here'; ^
    More? write-output "\"new line`r`nhere\""; ^
    More? write-output \""also`r`nhere"\"; ^
    

    will result in:

    there are spaces here
    new line
    here
    also
    here
    
征﹌骨岁月お 2024-11-14 12:49:39

在寻找将 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
)

Looking for the possibility to put a powershell script into a batch file, I found this thread. The idea of walid2mi did not worked 100% for my script. But via a temporary file, containing the script it worked out. Here is the skeleton of the batch file:

;@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
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文