2010-08-05 37 views
8

我希望标题简洁,但以防万一:从批处理调用PowerShell,并检索脚本中设置的临时环境变量的新值?

我从批处理文件调用PowerShell脚本。我希望PowerShell脚本设置环境变量的值,并且在PowerShell脚本完成时可以在批处理文件中使用该新值。

我知道可以在PowerShell中使用$ env设置一个环境变量,但该值在PowerShell脚本终止时不会持续。我想这可能是因为PowerShell在一个单独的过程中执行。

我知道我可以返回一个退出代码并使用%ErrorLevel%,但那只会给我数字,并且会有冲突,因为1表示PowerShell异常而不是有用的数字。

现在,请注意:我不希望环境变量持续存在。也就是说,我不希望为用户或系统定义它,因此,只要批处理文件退出,我就希望它不可用。最终,我只是想将结果从PowerShell脚本传回给调用批处理文件。

这可能吗?

感谢提前:)

尼克

回答

-1

从PowerShell中获取结果的最直接的方式是在PowerShell中使用标准输出。例如,这样可以节省在CMD.EXE的日期到d的环境变量

set d = powershell -noprofile "& { get-date }" 
+0

很好的解决方案。我怀疑有没有其他的那么简单直接。 – stej 2010-08-05 14:46:46

+2

感谢您的回复,但我不认为上述方法可行?我期望在这种情况下发生的事情是,环境变量'd'的值将是'powershell -noprofile“&{get-date}”'。 IE:不评估表达式右侧的内容。 – 2010-08-05 15:02:48

+0

@尼古拉斯,你是对的。我现在已经试过了,只有字符串存储在变量中。 – stej 2010-08-05 15:30:01

10

要获得使用标准输出的工作,你可以从你的批处理脚本这样调用的PowerShell Keith的想法:

FOR /F "usebackq delims=" %v IN (`powershell -noprofile "& { get-date }"`) DO set "d=%v" 

有点别扭,但它的工作原理:

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 
+1

此外,如果您在批处理文件中运行此代码而不是从命令行运行,则需要在变量名称前面使用双百分号(即,在上述示例中将%v更改为%% v )。 – deadlydog 2013-03-06 22:12:36

+0

如果您想了解更多详细信息,请访问https://blogs.msdn.microsoft.com/oldnewthing/20120731-00/?p=7003 – Arithmomaniac 2016-07-07 16:40:54

0

我知道它的晚来回答这个问题一点点,但我想尝试一下,以防万一任何一个需要更详细的解决方案。所以,在这里。

我创建了一个批处理功能将执行PS脚本,你并返回一个值,像这样:

:: 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 

现在,作为一个例子来使用它:

set psCmd="&{ Write-Host 'You got it';}" 
call :RunPS %psCmd% RetValue 
echo %RetValue% 

这将在控制台屏幕上显示你知道它

作为一个更复杂的例子,我会补充:

假设我们要检查一个VM是向上或向下,如果是开机还是关机的意思,所以我们可以做到以下几点:

: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 

现在,如何使用:CheckMachineUpOrDown功能?

只要按照这个例子:

set Workstation=MyVMName 
call :CheckMachineUpOrDown VMStatus %Workstation% 
echo %VMStatus% 

这将显示截至如果虚拟机启动或停机如果机器关闭。

希望这是有帮助的。

谢谢

相关问题