2009-07-31 21 views
15

Tôi đang sử dụng "lệnh gọi" để thực thi tập lệnh trên máy từ xa.bắt mã trả về của lệnh bằng "lệnh gọi" - Powershell 2

invoke-command -computername <server_name> -scriptblock {command to execute the script} 

Tập lệnh của tôi trả về "-1" khi có bất kỳ lỗi nào. Vì vậy, tôi muốn đảm bảo rằng tập lệnh đã thực hiện thành công bằng cách kiểm tra mã trả lại.

Tôi đã thử như sau.

$code = invoke-command -computername .... 

Nhưng nó không trả về gì cả.

Không Invoke-command mã trả lại của khối tập lệnh?

Có cách nào khác để giải quyết vấn đề này không?

Trả lời

10

Tôi nghĩ rằng nếu bạn chạy một lệnh theo cách đó trên máy chủ khác thì không có cách nào bạn có thể nhận được ở mã trả về của tập lệnh tại đó. Điều này là do Invoke-Command chỉ cần chạy một lệnh trên máy từ xa, có thể trong một phiên tạm thời và bạn không thể kết nối lại với phiên đó.

Điều bạn có thể làm, tuy nhiên, là tạo phiên trên máy tính từ xa và gọi tập lệnh của bạn trong phiên đó. Sau đó bạn chỉ có thể kiểm tra giá trị trả về trong phiên đó một lần nữa. Vì vậy, một cái gì đó dọc theo dòng:

$s = New-PSSession -ComputerName <server_name> 
Invoke-Command -Session $s -ScriptBlock { ... } 
Invoke-Command -Session $s -ScriptBlock { $? } 

có thể hoạt động. Bằng cách này, bạn có thể truy cập vào cùng một trạng thái và các biến như Invoke-Command đầu tiên trên máy từ xa.

Ngoài ra Invoke-Command rất khó vượt qua giá trị trả về của lệnh từ xa. Làm thế nào bạn sẽ tìm ra sau đó rằng Invoke-Command chính nó không thành công?

ETA: Ok, tôi đã hiểu sai bạn về "mã trả lại". Tôi đã giả sử bạn có nghĩa là $?. Dù sao, theo các tài liệu bạn có thể chạy một kịch bản trên một máy tính từ xa như sau:

Để chạy một kịch bản cục bộ trên máy tính từ xa, sử dụng FilePath tham số của Invoke-Command.

Ví dụ, lệnh sau chạy Sample.ps1 kịch bản trên các máy tính S1S2:

invoke-command -computername S1, S2 -filepath C:\Test\Sample.ps1 

Kết quả của kịch bản được trả lại cho máy tính cục bộ. Bạn không cần sao chép bất kỳ tệp nào.

+0

điều lạ trong lệnh Gọi khi chạy trong ngữ cảnh Jenkins, mã trả về như $ returnCode = Invoke-command -file somescript.ps1 này sẽ trả về mọi từ somescript.ps1. nếu chạy trong một cửa sổ lệnh, giá trị trả lại được trả về đúng. bất cứ ai có bất kỳ ý tưởng? – koo9

+0

@ koo9: '$ returnCode' sẽ nhận được _pipeline output_ của tệp tập lệnh. Không phải là mã thoát. – Joey

+0

được cho là nhưng khi chạy tập lệnh trong công việc Jenkins, bằng cách nào đó $ returncode bắt tất cả đầu ra từ tập lệnh ps1 – koo9

3

Đây là ví dụ ...

kịch bản từ xa:

try { 
    ... go do stuff ... 
} catch { 
    return 1 
    exit 
} 
return 2 
exit 

script địa phương:

function RunRemote { 
    param ([string]$remoteIp, [string]$localScriptName) 
    $res = Invoke-Command -computername $remoteIp -UseSSL -Credential $mycreds -SessionOption $so -FilePath $localScriptName 
    return $res 
} 

$status = RunRemote $ip_name ".\Scripts\myRemoteScript.ps1" 
echo "Return status was $status" 

$ vậy, -UseSSL và $ mycreds không cần thiết nếu bạn hoàn toàn bên trong một nhóm tin cậy. Điều này dường như làm việc cho tôi ... chúc may mắn!

2

Nếu một tập lệnh chặn từ xa trả về mã thoát, lệnh psession sẽ bị đóng. Tôi chỉ kiểm tra trạng thái của sự thất vọng. Nếu nó đóng, tôi giả định một lỗi. Loại hacky, nhưng nó hoạt động cho mục đích của tôi.

$session = new-pssession $env:COMPUTERNAME 
Invoke-Command -ScriptBlock {try { ErrorHere } Catch [system.exception] {exit 1}} -Session $session 

if ($session.State -eq "Closed") 
{ 
    "Remote Script Errored out" 
} 

Remove-PSSession $session 

$session = new-pssession $env:COMPUTERNAME 
Invoke-Command -ScriptBlock {"no exitcodes here"} -Session $session 

if ($session.State -ne "Closed") 
{ 
    "Remote Script ran succesfully" 
} 

Remove-PSSession $session 
0

Tôi đang tìm cách lấy mã lỗi trả về bởi tập lệnh lô được gọi thông qua lệnh gọi. Không phải là một nhiệm vụ dễ dàng nhưng tôi đã tìm thấy một cách tốt đẹp và dễ dàng để làm điều đó.

Bạn PowerShell script là $res=invoke-command -Computername %computer% {C:\TEST\BATCH.CMD} write-host $res Bạn sẽ tìm ra $ res là đầu ra hàng loạt, biết điều này bằng cách sử dụng @echo off,> nul và echo "những gì bạn muốn trả lại" là có thể!

Bạn batch script

@echo off 
echo "Start Script, do not return" > nul 
echo 2 

Bây giờ $ res sẽ = 2! Sau đó, bạn có thể áp dụng bất kỳ lôgic nào trong lô của bạn.

Bạn thậm chí có thể sử dụng lệnh gọi -AsJob Sử dụng công việc Nhận để nhận kết quả! Trong trường hợp này bạn không cần phải sử dụng $ res.

Chúc mừng, Julien

0

Nếu bạn cần đầu ra từ khối kịch bản mã lối ra, bạn có thể ném mã thoát khỏi khối và chuyển đổi nếu trở lại vào một số nguyên ở phía bên gọi.

$session = new-pssession $env:COMPUTERNAME 
try { 
    Invoke-Command -ScriptBlock {Write-Host "This is output that should not be lost"; $exitCode = 99; throw $exitCode} -Session $session 
} catch { 
    $exceptionExit = echo $_.tostring() 
    [int]$exceptionExit = [convert]::ToInt32($exceptionExit) 
    Write-Host "`$exceptionExit = $exceptionExit" 
} 

Điều này trả về tiêu chuẩn và mã thoát cuối cùng. Tuy nhiên, điều này yêu cầu trong khối tập lệnh của bạn, mọi ngoại lệ đều bị bắt và được ném lại như các mã thoát. Đầu ra từ ví dụ ...

This is output that should not be lost 
$exceptionExit = 99 
Các vấn đề liên quan