Ibuyisela inani ukusuka ku-powershell invoke-command kuya kumenzeli weseva ye-SQL

Lapho ngenza eyami indlela yokuphatha izipele kumaseva amaningi e-MS-SQL, ngichithe isikhathi esiningi ngifunda indlela yokudlulisa amanani ku-Powershell phakathi nezingcingo ezikude, ngakho-ke ngizibhalela isikhumbuzi uma kwenzeka siwusizo. komunye umuntu.

Ngakho-ke, ake siqale ngombhalo olula futhi siwuqhube endaweni:

$exitcode = $args[0]
Write-Host 'Out to host.'
Write-Output 'Out to output.'
Write-Host ('ExitCode: ' + $exitcode)
Write-Output $exitcode
$host.SetShouldExit($exitcode)

Ukuze ngisebenzise izikripthi, ngizosebenzisa ifayela le-CMD elilandelayo, ngeke ngilifake njalo:

@Echo OFF
PowerShell .TestOutput1.ps1 1
ECHO ERRORLEVEL=%ERRORLEVEL%

Esikrinini sizobona okulandelayo:

Out to host.
Out to output.
ExitCode: 1
1
ERRORLEVEL=1


Manje ake sisebenzise iskripthi esifanayo nge-WSMAN (ukude):

Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]

Futhi nawu umphumela:

Out to host.
Out to output.
ExitCode: 2
2
ERRORLEVEL=0

Kuhle, i-Errorlevel inyamalele ndawana thize, kodwa sidinga ukuthola inani kuskripthi! Ake sizame ukwakhiwa okulandelayo:

$res=Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]

Lokhu kuyathakazelisa nakakhulu. Umlayezo kokuthi Okukhiphayo unyamalele ndawana thize:

Out to host.
ExitCode: 2
ERRORLEVEL=0

Manje, njengokuhlehla kwezwi, ngizoqaphela ukuthi uma ngaphakathi komsebenzi we-Powershell ubhala i-Writ-Output noma inkulumo nje ngaphandle kokuyabela noma yikuphi okuguquguqukayo (futhi lokhu kusho ngokusobala okuphumayo esiteshini Sokukhipha), khona-ke noma usebenza endaweni, akukho okuzoboniswa esikrinini! Lokhu kuwumphumela wokwakhiwa kwepayipi le-powershell - umsebenzi ngamunye unepayipi lawo Lokukhiphayo, uhlu ludalelwe wona, futhi yonke into engena kuwo kuthathwa njengomphumela wokwenziwa komsebenzi, u-opharetha Wokubuyisela wengeza inani lokubuyisela okufanayo. ipayipi njengento yokugcina futhi idlulisela ukulawula kumsebenzi wokushaya. Ukuze ufanekise, ake siqalise umbhalo olandelayo endaweni:

Function Write-Log {
  Param( [Parameter(Mandatory=$false, ValueFromPipeline=$true)] [String[]] $OutString = "`r`n" )
  Write-Output ("Function: "+$OutString)
  Return "ReturnValue"
}
Write-Output ("Main: "+"ParameterValue")
$res = Write-Log "ParameterValue"
$res.GetType()
$res.Length
$res | Foreach-Object { Write-Host ("Main: "+$_) }

Futhi nawu umphumela:

Main: ParameterValue

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
2
Main: Function: ParameterValue
Main: ReturnValue

Umsebenzi oyinhloko (umzimba weskripthi) nawo unepayipi lawo Lokukhipha, futhi uma sisebenzisa iskripthi sokuqala sisuka ku-CMD, siqondisa kabusha okukhiphayo kufayela,

PowerShell .TestOutput1.ps1 1 > TestOutput1.txt

ke sizobona esikrinini

ERRORLEVEL=1

nakufayela

Out to host.
Out to output.
ExitCode: 1
1

uma senza ikholi efanayo kusuka ku-powershell

PS D:sqlagent> .TestOutput1.ps1 1 > TestOutput1.txt

khona-ke kuzoba esikrinini

Out to host.
ExitCode: 1

nakufayela

Out to output.
1

Lokhu kwenzeka ngoba i-CMD yethula i-powershell, okuthi, uma ingekho eminye imiyalelo, ixube imicu emibili (Host and Output) futhi izinike i-CMD, ethumela yonke into eyitholile efayeleni, futhi esimweni sokwethulwa ku-powershell, le micu emibili ikhona ngokuhlukene, futhi ukuqondisa kabusha uphawu kuthinta kuphela Okukhiphayo.

Ukubuyela esihlokweni esiyinhloko, masikhumbule ukuthi imodeli ye-.NET yento engaphakathi kwe-powershell ikhona ngokugcwele ngaphakathi kwekhompyutha eyodwa (i-OS eyodwa), uma usebenzisa ikhodi ukude nge-WSMAN, ukudluliswa kwezinto kwenzeka ngokwenziwa kwe-XML, okuletha isithakazelo esikhulu esingeziwe. ocwaningweni lwethu. Masiqhubeke nokuhlola kwethu ngokusebenzisa ikhodi elandelayo:

$res=Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]
$res.GetType()
$host.SetShouldExit($res)

Futhi nakhu esinakho esikrinini:

Out to host.

ExitCode: 3

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array
Не удается преобразовать аргумент "exitCode", со значением: "System.Object[]", для "SetShouldExit" в тип "System.Int32": "Не удается преобразовать значение "System.Object[]" типа "System.Object[]" в тип "System
.Int32"."
D:sqlagentTestOutput3.ps1:3 знак:1
+ $host.SetShouldExit($res)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

ERRORLEVEL=0

Umphumela omuhle! Kusho ukuthi uma kushayelwa i-Invoke-Command, ukuhlukaniswa kwamapayipi abe yimicu emibili (I-Host and Output) kugcinwa, okusinika ithemba lempumelelo. Ake sizame ukushiya inani elilodwa kuphela ekusakazweni Kokukhiphayo, lapho sizoshintsha khona iskripthi sokuqala esisisebenzisa ukude:

$exitcode = $args[0]
Write-Host 'Out to host.'
#Write-Output 'Out to output.'
Write-Host ('ExitCode: ' + $exitcode)
Write-Output $exitcode
$host.SetShouldExit($exitcode)

Masiyiqhube kanje:

$res=Invoke-Command -ComputerName . -ScriptBlock { &'D:sqlagentTestOutput1.ps1' $args[0] } -ArgumentList $args[0]
$host.SetShouldExit($res)

futhi... YEBO, kubukeka njengokunqoba!

Out to host.
ExitCode: 4

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType


ERRORLEVEL=4

Ake sizame ukuthola ukuthi kwenzekani. Sishayele i-powershell endaweni, yona eyabiza i-powershell kukhompuyutha eyirimothi futhi sasebenzisa umbhalo wethu lapho. Ukusakaza okubili (Umsingathi kanye Nokukhiphayo) okuvela emshinini oqhelile kwenziwa uchungechunge futhi kwabuyiselwa emuva, kuyilapho ukusakaza Kokukhiphayo, okunenani elilodwa ledijithali kukho, kwaguqulelwa kuhlobo lwe-Int32 futhi kanjalo kwadluliselwa ohlangothini olwamukelayo, futhi uhlangothi olutholayo lwalusebenzisa. njengekhodi yokuphuma yomshayeli we-powershell.

Futhi njengesheke lokugcina, ake sakhe umsebenzi oyisinyathelo esisodwa kuseva ye-SQL ngohlobo lwe-“Operating System (cmdexec)” enombhalo olandelayo:

PowerShell -NonInteractive -NoProfile "$res=Invoke-Command -ComputerName BACKUPSERVER -ConfigurationName SQLAgent -ScriptBlock {&'D:sqlagentTestOutput1.ps1' 6}; $host.SetShouldExit($res)"

HAYI! Umsebenzi uqedelwe ngephutha, umbhalo kulogi:

Выполняется от имени пользователя: DOMAINagentuser. Out to host. ExitCode: 6.  Код завершения процесса 6.  Шаг завершился с ошибкой.

Iziphetho:

  • Gwema ukusebenzisa i-Writ-Output kanye nokucacisa izinkulumo ngaphandle kokunikezwa. Qaphela ukuthi ukuhambisa le khodi kwenye indawo kusikripthi kungase kuveze imiphumela engalindelekile.
  • Emibhalweni ehloselwe ukwethulwa mathupha, kodwa ukusetshenziswa ezindleleni zakho ezizenzakalelayo, ikakhulukazi izingcingo ezikude nge-WINRM, yenza iphutha ngesandla usebenzisa i-Try/Catch, futhi uqinisekise ukuthi, kunoma yikuphi ukuthuthukiswa kwemicimbi, lesi script sithumela inani elilodwa ncamashi lohlobo lwakudala. . Uma ufuna ukuthola i-Errorlevel yakudala, leli nani kufanele libe inombolo.

Source: www.habr.com

Engeza amazwana