2010-08-05 42 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% 

這將顯示截至如果虛擬機啓動或停機如果機器關閉。

希望這是有幫助的。

謝謝

相關問題