How to run a PowerShell script within a Windows batch file

前端 未结 10 1932
半阙折子戏
半阙折子戏 2020-11-27 16:22

How do I have a PowerShell script embedded within the same file as a Windows batch script?

I know this kind of thing is possible in other scenarios:

  • Em
10条回答
  •  春和景丽
    2020-11-27 17:05

    Another sample batch+PowerShell script... It's simpler than the other proposed solution, and has characteristics that none of them can match:

    • No creation of a temporary file => Better performance, and no risk of overwriting anything.
    • No special prefixing of the batch code. This is just normal batch. And same thing for the PowerShell code.
    • Passes all batch arguments to PowerShell correctly, even quoted strings with tricky characters like ! % < > ' $
    • Double quotes can be passed by doubling them.
    • Standard input is usable in PowerShell. (Contrary to all versions that pipe the batch itself to PowerShell.)

    This sample displays the language transitions, and the PowerShell side displays the list of arguments it received from the batch side.

    <# :# PowerShell comment protecting the Batch section
    @echo off
    :# Disabling argument expansion avoids issues with ! in arguments.
    setlocal EnableExtensions DisableDelayedExpansion
    
    :# Prepare the batch arguments, so that PowerShell parses them correctly
    set ARGS=%*
    if defined ARGS set ARGS=%ARGS:"=\"%
    if defined ARGS set ARGS=%ARGS:'=''%
    
    :# The ^ before the first " ensures that the Batch parser does not enter quoted mode
    :# there, but that it enters and exits quoted mode for every subsequent pair of ".
    :# This in turn protects the possible special chars & | < > within quoted arguments.
    :# Then the \ before each pair of " ensures that PowerShell's C command line parser 
    :# considers these pairs as part of the first and only argument following -c.
    :# Cherry on the cake, it's possible to pass a " to PS by entering two "" in the bat args.
    echo In Batch
    PowerShell -c ^"Invoke-Expression ('^& {' + [io.file]::ReadAllText(\"%~f0\") + '} %ARGS%')"
    echo Back in Batch. PowerShell exit code = %ERRORLEVEL%
    exit /b
    
    ###############################################################################
    End of the PS comment around the Batch section; Begin the PowerShell section #>
    
    echo "In PowerShell"
    $Args | % { "PowerShell Args[{0}] = '$_'" -f $i++ }
    exit 0
    

    Note that I use :# for batch comments, instead of :: as most other people do, as this actually makes them look like PowerShell comments. (Or like most other scripting languages comments actually.)

提交回复
热议问题