2010-08-05 7 views
8

Tôi hy vọng tựa đề ngắn gọn, nhưng chỉ trong trường hợp:Gọi PowerShell từ lô và truy xuất giá trị mới của biến môi trường tạm thời được đặt trong tập lệnh?

Tôi đang gọi tập lệnh PowerShell từ một tệp lô. Tôi muốn kịch bản PowerShell để thiết lập giá trị của một biến môi trường, và cho rằng giá trị mới có sẵn trong tập tin thực thi khi kịch bản PowerShell kết thúc.

Tôi biết rằng có thể đặt biến môi trường bằng $ env trong PowerShell, nhưng giá trị không tồn tại khi tập lệnh PowerShell chấm dứt. Tôi tưởng tượng điều này có lẽ là do PowerShell được thực hiện trong một quá trình riêng biệt.

Tôi biết rằng tôi có thể trả lại mã thoát và sử dụng% ErrorLevel%, nhưng điều đó sẽ chỉ cho tôi số và sẽ có xung đột vì 1 cho biết ngoại lệ PowerShell thay vì số hữu ích.

Bây giờ, đây là thông báo trước: Tôi không muốn biến môi trường tồn tại. Đó là, tôi không muốn nó được xác định cho người dùng hoặc hệ thống, và do đó tôi muốn nó không có sẵn ngay sau khi các tập tin batch thoát. Cuối cùng, tôi chỉ muốn giao tiếp kết quả từ một kịch bản PowerShell đến tập tin batch gọi.

Điều này có khả thi không?

Cảm ơn trước :)

Nick

Trả lời

-1

Con đường phía trước thẳng nhất để nắm bắt kết quả từ PowerShell là sử dụng thiết bị xuất chuẩn trong PowerShell. Ví dụ, điều này giúp tiết kiệm từ ngày đến var d env trong cmd.exe

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

Giải pháp tốt. Tôi nghi ngờ có bất kỳ khác mà là như vậy dễ dàng và đơn giản. – stej

+2

Cảm ơn bạn đã phản hồi, nhưng tôi không nghĩ rằng những điều trên sẽ hiệu quả? Điều tôi mong đợi xảy ra trong trường hợp này là giá trị của biến môi trường 'd' sẽ là 'powershell -noprofile' & {get-date} ''. IE: Nội dung của phía bên phải của biểu thức không được đánh giá. –

+0

@Nicholas, bạn nói đúng. Tôi đã thử nó ngay bây giờ và thực sự chỉ có chuỗi được lưu trữ trong biến. – stej

10

Để có được ý tưởng của việc sử dụng thiết bị xuất chuẩn để làm việc, bạn có thể gọi PowerShell từ kịch bản hàng loạt của bạn như thế này Keith:

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

một chút lúng túng, nhưng nó hoạt động:

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

Ngoài ra, nếu bạn đang chạy mã này trong một tệp lô và không phải từ dòng lệnh, bạn sẽ cần phải sử dụng dấu hai phần trăm ở phía trước tên biến của bạn (ví dụ: thay đổi% v thành %% v ở cả hai vị trí trong ví dụ trên). – deadlydog

+0

Nếu bạn muốn biết thêm chi tiết, bạn có thể xem chúng tại https://blogs.msdn.microsoft.com/oldnewthing/20120731-00/?p=7003 – Arithmomaniac

0

tôi biết đó là một chút muộn để trả lời câu hỏi này, nhưng tôi muốn cung cấp cho nó một thử chỉ trong trường hợp bất kỳ một giải pháp cần chi tiết hơn. Vì vậy, ở đây nó đi.

Tôi tạo ra một chức năng hàng loạt mà sẽ thực hiện ps kịch bản cho bạn và trả về một giá trị, một cái gì đó như thế này:

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

Bây giờ, làm ví dụ để sử dụng nó:

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

chí này hiển thị trên màn hình điều khiển Bạn đã nhận được nó

Như một ví dụ phức tạp hơn, tôi sẽ thêm:

Giả sử rằng chúng ta muốn kiểm tra xem một máy ảo là lên hoặc xuống, có nghĩa là nếu nó được hỗ trợ hoặc tắt, vì vậy chúng ta có thể làm như sau:

: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 

Bây giờ, làm thế nào để sử dụng: CheckMachineUpOrDown chức năng?

chỉ cần làm theo ví dụ này:

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

này sẽ hiển thị lên nếu VM được Powered On hoặc xuống nếu máy đang Tắt.

Hy vọng điều này hữu ích.

Cảm ơn