【问题标题】:How to execute PowerShell commands from a batch file?如何从批处理文件执行 PowerShell 命令?
【发布时间】:2011-08-27 14:04:12
【问题描述】:

我有一个 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 命令。当我必须运行单个命令时,这似乎很简单,BUT 在这种情况下,我有一系列相关的命令。我想避免为要从批处理中调用的 PS 脚本创建单独的文件 - 所有内容都必须在批处理文件中。

问题是:如何从批处理文件中执行 PowerShell 命令(或语句)?

【问题讨论】:

标签: powershell command-line batch-file powershell-2.0


【解决方案1】:

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

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/

【讨论】:

  • 如何分割长线?与您的示例类似的行。
  • @JuanPablo 很抱歉回复很晚,但直到今天才承诺审查我的 stackoverflow 使用情况并更加活跃。你得到这个答案了吗?
  • 是否可以传递多个.ps1文件?
  • 你能举个例子吗?听起来像是另一个问题。
  • 为了好玩,#!/bin/bash powershell <<<'run this string' 有效,但确实如此。慢。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    此解决方案类似于 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...
    

    【讨论】:

    • 使用说明:在某些极端情况下cd %~dp0 不起作用,这种调用方式会将$PSScriptRoot 设置为null,因为我们作为一系列命令运行,而不是作为脚本。我已经删除了 cd %~dp0 并将调用的表达式更改为 $($ScriptHome = '%~dp0'; [System.IO.File]::ReadAllText('%~dpf0')) 来处理这个问题。
    • 我是否在我的 powershell 命令中包含 #
    • @JustinGoldberg - - 在此注释块中是用于 powershell 运行的 .bat/.cmd 命令,在该注释块之后,您可以使用任何带有 # 的 powershell 语法: )
    【解决方案4】:

    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
    

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-12-25
          • 2013-07-23
          • 2019-11-15
          • 1970-01-01
          • 1970-01-01
          • 2015-01-06
          • 1970-01-01
          相关资源
          最近更新 更多