1

I was trying to use the return from myPowershellScript.ps1 to use as a variable in my batch file.

myPowershellScript.ps1

function GetLatestText
{
    return "Hello World"
}

I was trying to use the For /F function. There may be a better way.

myBatch.bat

for /f "delims=" %%a in (' powershell -command "\\Rossi2\Shared\myPowershellScript.ps1" ') do set "var=%%a"

echo %var%

Desired output, would be to have 'Hello World' output in the cmd window.

I was trying to use the batch file as some old processes use them. For newer processes I do everything in PowerShell and it works fine.

The current output is blank.

Rossi
  • 13
  • 2
  • I noticed that if I just create a new .ps1; and on line 1 I type ''Hello World'' it works. But it won't return my function return string. If my Powershell Script had more than one function in it, how would I call the correct function in the batch file? – Rossi Feb 01 '23 at 20:23

2 Answers2

1
  • Your syntax for trying to capture output from a PowerShell script from a batch file is correct (assuming single-line output from the script),[1] except that it it is more robust to use the -File parameter of powershell.exe, the Windows PowerShell CLI than the -Command parameter.

  • Your problem is with the PowerShell script itself:

    • You're defining function Get-LatestText, but you're not calling it, so your script produces no output.

    • There are three possible solutions:

      • Place an explicit call to Get-LatestText after the function definition; if you want to pass any arguments received by the script through, use Get-LatestText @args

      • Don't define a function at all, and make the function body the script body.

      • If your script contains multiple functions, and you want to call one of them, selectively: in your PowerShell CLI call, dot-source the script file (. <script>), and invoke the function afterwards (this does require -Command):

         for /f "delims=" %%a in (' powershell -Command ". \"\\Rossi2\Shared\myPowershellScript.ps1\"; Get-LatestText" ') do set "var=%%a"
        
         echo %var%
        

[1] for /f loops over a command's output line by line (ignoring empty lines), so with multiline output only the last line would be stored in %var% - more effort is needed to handle multiline output.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Thank you for explaining in so much detail. I will probably use the 3rd of your solutions. – Rossi Feb 01 '23 at 21:02
0

You can combine the batch and the powershell in single file (save this as .bat ):

<# : batch portion
@echo off & setlocal

    for /f "tokens=*" %%a in ('powershell -noprofile "iex (${%~f0} | out-string)"') do set "result=%%a"
    echo PS RESULT: %result%

endlocal
goto :EOF

: end batch / begin powershell #>

function GetLatestText
{
    return "Hello World"
}

write-host GetLatestText
npocmaka
  • 55,367
  • 18
  • 148
  • 187
  • Thanks for the response. The issue I'm trying to avoid is if I need to update the PowerShell script in the future, I don't want to update the .bat. – Rossi Feb 01 '23 at 20:48
  • This hybrid batch-file/PowerShell-script solution is interesting, but, generally speaking, if (robust) argument-passing must also be supported, an `iex` (`Invoke-Expression`)-based solution falls short - see [this answer](https://stackoverflow.com/a/49063524/45375) for a robust alternative (it doesn't capture the PowerShell script output on the batch-file side, but it could be adapted to do that). As an aside: `write-host GetLatestText` treats `GetLatestText` as a _string literal_. To call function `GetLatestText` and output its result, just use it by itself (no output command needed). – mklement0 Feb 01 '23 at 21:22