Calling PowerShell from batch, and retrieving the new value of a temporary environment variable set in the script?
I hope the title is concise, but just in case:
I am calling a PowerShell script from a batch file. I want the PowerShell script to set the value of an environment variable, and for that new value to be available in the batch file when the PowerShell script finishes.
I know that it is possible to set an environment variable using $env in PowerShell, but the value does not persist when the PowerShell script terminates. I imagine this is probably because PowerShell gets executed in a separate process.
I am aware that I can return an exit code and use %ErrorLeve开发者_开发问答l%, but that will only give me numbers, and there will be a conflict, since 1 indicates a PowerShell exception rather than a useful number.
Now, here's the caveat: I don't want the environment variable to persist. That is, I don't want it to be defined for the user or system, and therefore I want it to be unavailable as soon as the batch file exits. Ultimately, I simply want to communicate results back from a PowerShell script to the calling batch file.
Is this possible?
Thanks in advance :)
Nick
To get Keith's idea of using stdout to work, you can invoke powershell from your batch script like this:
FOR /F "usebackq delims=" %v IN (`powershell -noprofile "& { get-date }"`) DO set "d=%v"
A little awkward, but it works:
C:\>FOR /F "usebackq delims=" %v IN (`powershell -noprofile "& { get-date }"`) DO set "d=%v"
C:\>set d
d=August 5, 2010 11:04:36 AM
I know it's a little bit late to answer this question, but I would like to give it a try just in case any one needs more detailed solution. So, here it goes.
I created a batch function that would execute ps script for you and return a value, something like this:
:: A function that would execute powershell script and return a value from it.
:: <PassPSCMD> pass the powreshell command, notice that you need to add any returning value witth Write-Host
:: <RetValue> the returned value
:RunPS <PassPSCMD> <RetValue>
Powershell Set-ExecutionPolicy RemoteSigned -Force
for /F "usebackq tokens=1" %%i in (`Powershell %1`) do set returnValue=%%i
set "%2=%returnValue%"
Goto:eof
:: End of :RunPS function
Now, as an example to use it:
set psCmd="&{ Write-Host 'You got it';}"
call :RunPS %psCmd% RetValue
echo %RetValue%
This will display on console screen You got it
As a more complicated example, I would add:
Let's assume that we want to check if a VM is Up or Down, meaning if it's powered on or off, so we can do the following:
:CheckMachineUpOrDown <returnResult> <passedMachineName>
set userName=vCenterAdministratorAccount
set passWord=vCenterAdminPW
set vCenterName=vcenter.somedmain.whatever
set psCmd="&{Add-PSSnapin VMware.VimAutomation.Core; Connect-VIServer -server %%vCenterName%% -User %userName% -Password %passWord%; $vmServer = Get-VM %2;Write-Host ($vmServer.PowerState -eq 'PoweredOn')}"
call :RunPS %psCmd% RetValue
if "%RetValue%" EQU "True" (set "%1=Up") else (set "%1=Down")
Goto:eof
:: A function that would execute powershell script and return a value from it.
:: <PassPSCMD> pass the powreshell command, notice that you need to add any returning value witth Write-Host
:: <RetValue> the returned value
:RunPS <PassPSCMD> <RetValue>
Powershell Set-ExecutionPolicy RemoteSigned -Force
for /F "usebackq tokens=1" %%i in (`Powershell %1`) do set returnValue=%%i
set "%2=%returnValue%"
Goto:eof
:: End of :RunPS function
Now, how to use :CheckMachineUpOrDown function?
just follow this example:
set Workstation=MyVMName
call :CheckMachineUpOrDown VMStatus %Workstation%
echo %VMStatus%
This will display Up if the VM is Powered On or Down if the machine is Off.
Hope this is helpful.
Thanks
The most straight forward way to capture results from PowerShell is to use stdout in PowerShell. For example, this saves the date to the d env var in cmd.exe
set d = powershell -noprofile "& { get-date }"
精彩评论