A’ tilleadh luach bho òrdughan invoke powershell gu àidseant SQL Server

Nuair a chruthaich mi mo dhòigh-obrach fhìn airson a bhith a’ riaghladh cùl-taic air ioma-sheirbheisean MS-SQL, chuir mi seachad tòrr ùine a’ sgrùdadh an uidheamachd airson luachan a thoirt seachad ann an Powershell aig àm fiosan iomallach, agus mar sin tha mi a’ sgrìobhadh cuimhneachan dhomh fhìn gun fhios nach biodh e feumail do neach eile.

Mar sin, tòisichidh sinn le sgriobt sìmplidh agus ruith e gu h-ionadail:

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

Gus sgriobtaichean a ruith, cleachdaidh mi am faidhle CMD a leanas, cha chuir mi a-steach e a h-uile uair:

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

Air an sgrion chì sinn na leanas:

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


A-nis leig leinn an aon sgriobt a ruith tro WSMAN (air astar):

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

Agus seo an toradh:

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

Sgoinneil, tha Errorlevel air a dhol à bith am badeigin, ach feumaidh sinn an luach fhaighinn bhon sgriobt! Feuch sinn an dealbhadh a leanas:

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

Tha seo eadhon nas inntinniche. Tha an teachdaireachd ann an Toradh air a dhol à bith am badeigin:

Out to host.
ExitCode: 2
ERRORLEVEL=0

A-nis, mar chlaonadh liriceach, bheir mi an aire ma sgrìobhas tu am broinn gnìomh Powershell Write-Output no dìreach abairt gun a bhith ga shònrachadh do chaochladair sam bith (agus tha seo gu h-obann a’ ciallachadh toradh don t-sianal Toraidh), an uairsin eadhon nuair a bhios tu a’ ruith gu h-ionadail, cha tèid dad a thaisbeanadh air an sgrion! Tha seo mar thoradh air ailtireachd loidhne-phìoban cumhachd - tha a loidhne-phìob toraidh fhèin aig gach gnìomh, tha sreath air a chruthachadh air a shon, agus tha a h-uile dad a thèid a-steach air a mheas mar thoradh air coileanadh a’ ghnìomh, bidh an gnìomhaiche Tilleadh a ’cur an luach tilleadh ris an aon rud. loidhne-phìoban mar an eileamaid mu dheireadh agus a’ gluasad smachd chun ghnìomh gairm. Gus sealltainn, ruithidh sinn an sgriobt a leanas gu h-ionadail:

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: "+$_) }

Agus seo an toradh:

Main: ParameterValue

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

Tha loidhne-phìoban toraidh fhèin aig a’ phrìomh ghnìomh (buidheann sgriobt), agus ma ruitheas sinn a’ chiad sgriobt bho CMD, ag ath-stiùireadh an toraidh gu faidhle,

PowerShell .TestOutput1.ps1 1 > TestOutput1.txt

an uairsin chì sinn air an sgrion

ERRORLEVEL=1

agus anns an fhaidhle

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

ma nì sinn an aon ghairm bho powershell

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

an uairsin bidh e air an sgrion

Out to host.
ExitCode: 1

agus anns an fhaidhle

Out to output.
1

Bidh seo a’ tachairt leis gu bheil an CMD a’ cur air bhog slige chumhachdan, a bhios, às aonais stiùireadh eile, a’ measgachadh dà snàithlean (Host and Output) agus gan toirt don CMD, a chuireas a h-uile càil a fhuair e gu faidhle, agus ma thèid a chuir air bhog bho powershell, tha an dà snàithlean seo ann air leth, agus chan eil na h-ath-sheòlaidhean samhla a’ toirt buaidh ach air Toradh.

A’ tilleadh chun phrìomh chuspair, cuimhnichidh sinn gu bheil am modal nì .NET taobh a-staigh powershell ann gu h-iomlan taobh a-staigh aon choimpiutair (aon OS), nuair a bhios sinn a’ ruith còd air astar tro WSMAN, bidh gluasad nithean a’ tachairt tro shreathachadh XML, a bheir mòran ùidh a bharrachd. don rannsachadh againn. Leanaidh sinn oirnn leis na deuchainnean againn le bhith a’ ruith a’ chòd a leanas:

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

Agus seo na tha againn air an sgrion:

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

Toradh sgoinneil! Tha e a’ ciallachadh, nuair a chuireas tu fios gu Invoke-Command, gu bheilear a’ cumail suas na pìoban a roinn ann an dà snàithlean (Host and Output), a tha a’ toirt dòchas dhuinn airson soirbheachas. Feuchaidh sinn ri dìreach aon luach fhàgail anns an t-sruth Toraidh, far an atharraich sinn a’ chiad sgriobt a ruitheas sinn air astar:

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

Feuch an ruith sinn e mar seo:

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

agus... THA, tha e coltach ri buaidh!

Out to host.
ExitCode: 4

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


ERRORLEVEL=4

Feuchaidh sinn ri faighinn a-mach dè a thachair. Dh’ ainmich sinn powershell gu h-ionadail, a dh’ ainmich e fhèin powershell air a’ choimpiutair iomallach agus a chuir an sgriobt againn an gnìomh an sin. Chaidh dà shruth (Host and Output) bhon inneal iomallach a chuir a-steach agus a thoirt air ais, agus chaidh an sruth toraidh, le aon luach didseatach ann, atharrachadh gu seòrsa Int32 agus mar sin chaidh e chun taobh faighinn, agus chleachd an taobh faighinn e. mar chòd fàgail an neach-fios powershell.

Agus mar sgrùdadh deireannach, cruthaichidh sinn obair aon-cheum air an fhrithealaiche SQL leis an t-seòrsa “Siostam-obrachaidh (cmdexec)” leis an teacsa a leanas:

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

HOORAY! Chaidh an obair a chrìochnachadh le mearachd, teacsa san loga:

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

Co-dhùnaidhean:

  • Seachain a bhith a’ cleachdadh Write-Toraidh agus a’ sònrachadh abairtean gun shònrachadh. Thoir an aire gum faodadh gluasad a’ chòd seo ann an àite eile san sgriobt toraidhean ris nach robh dùil.
  • Ann an sgriobtaichean nach eil airson an cur air bhog le làimh, ach airson an cleachdadh anns na h-innealan fèin-ghluasaid agad, gu sònraichte airson fiosan iomallach tro WINRM, dèan làimhseachadh mhearachdan làimhe tro Try / Catch, agus dèan cinnteach, ann an leasachadh thachartasan sam bith, gun cuir an sgriobt seo dìreach aon seòrsa prìomhadail luach . Ma tha thu airson an clasaigeach Errorlevel fhaighinn, feumaidh an luach seo a bhith àireamhach.

Source: www.habr.com

Cuir beachd ann