0

I am attempting to pass a number of variables processed by my batch file to a Powershell script. The problem I face is that firstly the entire results from the batch file come up in command prompt and next to the variables I intend to pass are not passed to the Powershell Script. Additionally, the variable I have to output the contents of the log file in just send the command back to the screen.

I have tried the following links and these links got me as far as I am now:

  1. Batch file to execute a Powershell script

  2. Pass variable from batch to powershell

  3. Pass parameter from a batch file to a PowerShell script

  4. Pass batch variables with spaces in them to powershell script?

Batch File side

set LOG_FILE = "GDGAGnklasj;oks;fk;dkf lkl;"
set oName = Name
set oStart = "%YYYY%%MM%%DD% %TIME%" 
set oStatus = 0
set oEnd = "%YYYY%%MM%%DD% %TIME%" 
set oDateRan = %YYYY%%MM%%DD%
set oLog =for /f "delims=" %%i in (%LOG_FILE%) do set content=%content% %%i
echo Updating Database >> %LOG_FILE% 2>&1
cmd /S powershell.exe -ExecutionPolicy Bypass -File "C:\Reporting\updateTool.ps1" "%oName%" "%DateRan%" "%oStart%" "%oEnd%" "%oStatus "%oLog%

PowerShell Script

param (
[string]$oName
)
"This is $oName"

My intent is to set the variables within the batch file then send them to Powershell for processing.

robdigm
  • 143
  • 2
  • 16
  • 4
    You have a basic Batch error: _you should not include any space besides the equal sign in a `set` command_: `set oName=Name`, because the spaces before the equal sign (and also after the equal sign) are included in the variable name (or value). The suggested form of `set` command is enclose in quotes both the variable and its value: `set "oName=Name"` – Aacini Jul 10 '19 at 00:37
  • 1
    `echo text >> file.ext` will also write the _space_ before `>>` into the file, so either remove it or better use `>> "file.ext" echo text`. And `cmd /S command` cannot work, it must read `cmd /S /C command` or `cmd /S /K command`; though I believe you do not need `cmd` at all here, just use `powershell ... -File ...`... – aschipfl Jul 10 '19 at 11:07

2 Answers2

2

Be very careful of spaces.

set oName=taco
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '.\ScriptName.ps1' -oName '%oName%' "
geek_01
  • 495
  • 4
  • 9
1

Oh Easy-Peasy, I do this for my Power shells that we need CMD wrappers for quite a bit.

I have to run to the train so this is going to be a bit meh at the moment I will firm it up in a bit, right now just going to paste in some example code so I can make it your code

Okay, what, umm, what did you intend for this Particular code to.l do ? I can't seem to figure out what you were intending with this, is it just some dummy code?

  set oLog =for /f "delims=" %%i in (%LOG_FILE%) do set content=%content% %%i
  echo Updating Database >> %LOG_FILE% 2>&1

Okay on further review I think you want to read the log into a couple of sttring variables in CMD, then use one of them in your call of the script..... but, why?

The strings will append to each other and you will be limited to 8191 characters max, and PowerShell can easily read the content of the log file because you pass the name to Powershell.

That seems like a better plan, no?

All your code where you have YYYY MM DD those are variables you will need to define before using, not sure if that is understood if so all good.

.CMD Script:

@(
   SETLOCAL ENABLEDELAYEDEXPANSION
   ECHO OFF

   SET "_PSScript=C:\Reporting\UpdateTool.ps1"
   REM SET "_DebugPreference=Continue"
   SET "_DebugPreference="SilentlyContinue"

   SET "_LOG_FILE=GDGAGnklasj;oks;fk;dkf lkl;"
   SET "_oName=Name."
   SET "_oStart=%YYYY%%MM%%DD% %TIME: =0%"
   SET /a "_Status=0"
   SET "_oEnd=%YYYY%%MM%%DD% %TIME: =0%" 
   SET "_oDateRan=%YYYY%%MM%%DD%"
)

SET "_PSCMD=Powershell "%_PSScript%" -DebugPreference "%_DebugPreference%" -LOG_FILE "%_LOG_FILE%" -oName "%_oName%" -oStart "%_oStart%" -Status %_Status% -oEnd "%_oEnd%" -oDateRan "%_oDateRan%" "


%_PSCMD% 2>&1 >> "_LOG_FILE"

PS1:

## Script: UpdateTool.ps1
# 

param(
    [String]$LOG_FILE = 'c:\admin\default.log',
    [String]$oName = 'default name'
    [String]$oStart = $(Get-date -F "yyyyMMdd HH:mm:ss.ms"),
    [Int]$oStatus = 0,
    [String]$oEnd = $(Get-date -F "yyyyMMdd HH:mm:ss.ms"),
    [String]$oDateRan = $(Get-date -F "yyyyMMdd"),
    $DebugPreference = "SilentlyContinue"
)
Ben Personick
  • 3,074
  • 1
  • 22
  • 29
  • Are the should the set be included in the ""? – robdigm Jul 10 '19 at 14:50
  • I meant the variable. i.e set "oStart=%YYYY%%MM%%DD% %TIME%" – robdigm Jul 10 '19 at 14:52
  • yes, you wrap the `"` around the Content to be `SET`, to ensure you don't include errant spaces, and you place the `=` directly next to the variable name to ensure the variable name itself doesn;t include a space, and then the content directly next to the = to make sure it doesnt include an errant space to the left either. This is a fairly standard methodology that uses an undocumented feature of SET which is available in Windows NT 4.x throuh Windows 2019 to facilitate cleaner variable assignment. – Ben Personick Jul 10 '19 at 15:01
  • Ok that makes sense. I ran it, but tried this line on the PS side : "Im in" | out-file -Encoding ascii -filepath $LOG_FILE -append to see if it worked. But nothing. I also removed the reset you did on the other side just so i am able to keep the values of each variable. – robdigm Jul 10 '19 at 15:23
  • Maybe a stupid question here but where is the PS script executed. I see it set but when does it execute. – robdigm Jul 10 '19 at 15:38
  • Those are not "Resets" those are default values, they are optional, but they do not "override" the values passed to the script – Ben Personick Jul 10 '19 at 16:37
  • Not a stupid question, I accidentally deleted the cmd being run, added that in again – Ben Personick Jul 10 '19 at 16:42
  • @robdigm see above – Ben Personick Jul 10 '19 at 16:43
  • oh the command is Call? – robdigm Jul 10 '19 at 16:55
  • I ended up using this :%_PSCMD% >>%_LOG_FILE% 2>&1 because I want to log what happens but the $oEnd comes through without the time portion on it. – robdigm Jul 10 '19 at 17:18
  • CALL isn't necessary, I'm super tired and writing while I fell asleep, you only need to call them if there was some expansion in them you needed to have occur, but there isn't in this case, but it also won't cause a problem either. – Ben Personick Jul 10 '19 at 20:07
  • Use `%_PSCMD% >> "%_LOG_FILE%" 2>&1` , good practice to always have the quotes on the file paths, or any variables passed as arguments that aren't int/float, that's actually the issue on the `_oEnd` variable as well, I simply forgot to surround it by quotes ` -oEnd "%_oEnd%"` , fixed above as well. Doing all of this on my phone and tired like whoa today, glad to help though :) – Ben Personick Jul 10 '19 at 20:12
  • lol, I was so tired I didn't even put the call int he code tags, that's pretty bad. – Ben Personick Jul 10 '19 at 20:16
  • I know this may be out of scope, but when the dates and datetimes get to the script converting them seem to be a problem. Any thoughts on that @BenPersonick? – robdigm Jul 10 '19 at 20:22
  • You need to tell Powershell you want it to interpret the String in the variable as a DateTime and how to convert it, by using `[DateTime]::ParseExact ()` Since you WANT Powershell to know it really is a DateTime you should change your CMD Script where you use `%Time%` to be `%Time: =0%` so that it is in propper `HH:MM:ss.ms` format as otherwise the morning will have a space instead of a leading 0. Then you can parse the received Date times that are in this format `yyyyMMdd HH:mm:ss.ms` using `$oStart = [DateTime]::ParseExact ($oStart, 'yyyyMMdd HH:mm:ss.ms', $Null )` to convert them. – Ben Personick Jul 10 '19 at 21:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/196288/discussion-between-ben-personick-and-robdigm). – Ben Personick Jul 10 '19 at 21:18